diff options
author | Thomas Citharel <tcit@tcit.fr> | 2014-12-22 14:33:01 +0100 |
---|---|---|
committer | Thomas Citharel <tcit@tcit.fr> | 2014-12-22 14:33:01 +0100 |
commit | f3917b1ee4bba812e82da57dd181f50d62926db4 (patch) | |
tree | cb4b04931e97e4a69500bf9d7aa5c21985cab59e /inc/3rdparty/libraries/tcpdf/include/tcpdf_filters.php | |
parent | 311baf86befde0557faea614ca4d13bb2bd2cc66 (diff) | |
parent | 9254b6cf460edec3a59e9ccc19873481a1d19c90 (diff) | |
download | wallabag-f3917b1ee4bba812e82da57dd181f50d62926db4.tar.gz wallabag-f3917b1ee4bba812e82da57dd181f50d62926db4.tar.zst wallabag-f3917b1ee4bba812e82da57dd181f50d62926db4.zip |
Merge branch 'dev' into randomarticle
Diffstat (limited to 'inc/3rdparty/libraries/tcpdf/include/tcpdf_filters.php')
-rw-r--r-- | inc/3rdparty/libraries/tcpdf/include/tcpdf_filters.php | 481 |
1 files changed, 481 insertions, 0 deletions
diff --git a/inc/3rdparty/libraries/tcpdf/include/tcpdf_filters.php b/inc/3rdparty/libraries/tcpdf/include/tcpdf_filters.php new file mode 100644 index 00000000..96584db5 --- /dev/null +++ b/inc/3rdparty/libraries/tcpdf/include/tcpdf_filters.php | |||
@@ -0,0 +1,481 @@ | |||
1 | <?php | ||
2 | //============================================================+ | ||
3 | // File name : tcpdf_filters.php | ||
4 | // Version : 1.0.001 | ||
5 | // Begin : 2011-05-23 | ||
6 | // Last Update : 2014-04-25 | ||
7 | // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com | ||
8 | // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html) | ||
9 | // ------------------------------------------------------------------- | ||
10 | // Copyright (C) 2011-2013 Nicola Asuni - Tecnick.com LTD | ||
11 | // | ||
12 | // This file is part of TCPDF software library. | ||
13 | // | ||
14 | // TCPDF is free software: you can redistribute it and/or modify it | ||
15 | // under the terms of the GNU Lesser General Public License as | ||
16 | // published by the Free Software Foundation, either version 3 of the | ||
17 | // License, or (at your option) any later version. | ||
18 | // | ||
19 | // TCPDF is distributed in the hope that it will be useful, but | ||
20 | // WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
22 | // See the GNU Lesser General Public License for more details. | ||
23 | // | ||
24 | // You should have received a copy of the License | ||
25 | // along with TCPDF. If not, see | ||
26 | // <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>. | ||
27 | // | ||
28 | // See LICENSE.TXT file for more information. | ||
29 | // ------------------------------------------------------------------- | ||
30 | // | ||
31 | // Description : This is a PHP class for decoding common PDF filters (PDF 32000-2008 - 7.4 Filters). | ||
32 | // | ||
33 | //============================================================+ | ||
34 | |||
35 | /** | ||
36 | * @file | ||
37 | * This is a PHP class for decoding common PDF filters (PDF 32000-2008 - 7.4 Filters).<br> | ||
38 | * @package com.tecnick.tcpdf | ||
39 | * @author Nicola Asuni | ||
40 | * @version 1.0.001 | ||
41 | */ | ||
42 | |||
43 | /** | ||
44 | * @class TCPDF_FILTERS | ||
45 | * This is a PHP class for decoding common PDF filters (PDF 32000-2008 - 7.4 Filters).<br> | ||
46 | * @package com.tecnick.tcpdf | ||
47 | * @brief This is a PHP class for decoding common PDF filters. | ||
48 | * @version 1.0.001 | ||
49 | * @author Nicola Asuni - info@tecnick.com | ||
50 | */ | ||
51 | class TCPDF_FILTERS { | ||
52 | |||
53 | /** | ||
54 | * Define a list of available filter decoders. | ||
55 | * @private static | ||
56 | */ | ||
57 | private static $available_filters = array('ASCIIHexDecode', 'ASCII85Decode', 'LZWDecode', 'FlateDecode', 'RunLengthDecode'); | ||
58 | |||
59 | // ----------------------------------------------------------------------------- | ||
60 | |||
61 | /** | ||
62 | * Get a list of available decoding filters. | ||
63 | * @return (array) Array of available filter decoders. | ||
64 | * @since 1.0.000 (2011-05-23) | ||
65 | * @public static | ||
66 | */ | ||
67 | public static function getAvailableFilters() { | ||
68 | return self::$available_filters; | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * Decode data using the specified filter type. | ||
73 | * @param $filter (string) Filter name. | ||
74 | * @param $data (string) Data to decode. | ||
75 | * @return Decoded data string. | ||
76 | * @since 1.0.000 (2011-05-23) | ||
77 | * @public static | ||
78 | */ | ||
79 | public static function decodeFilter($filter, $data) { | ||
80 | switch ($filter) { | ||
81 | case 'ASCIIHexDecode': { | ||
82 | return self::decodeFilterASCIIHexDecode($data); | ||
83 | break; | ||
84 | } | ||
85 | case 'ASCII85Decode': { | ||
86 | return self::decodeFilterASCII85Decode($data); | ||
87 | break; | ||
88 | } | ||
89 | case 'LZWDecode': { | ||
90 | return self::decodeFilterLZWDecode($data); | ||
91 | break; | ||
92 | } | ||
93 | case 'FlateDecode': { | ||
94 | return self::decodeFilterFlateDecode($data); | ||
95 | break; | ||
96 | } | ||
97 | case 'RunLengthDecode': { | ||
98 | return self::decodeFilterRunLengthDecode($data); | ||
99 | break; | ||
100 | } | ||
101 | case 'CCITTFaxDecode': { | ||
102 | return self::decodeFilterCCITTFaxDecode($data); | ||
103 | break; | ||
104 | } | ||
105 | case 'JBIG2Decode': { | ||
106 | return self::decodeFilterJBIG2Decode($data); | ||
107 | break; | ||
108 | } | ||
109 | case 'DCTDecode': { | ||
110 | return self::decodeFilterDCTDecode($data); | ||
111 | break; | ||
112 | } | ||
113 | case 'JPXDecode': { | ||
114 | return self::decodeFilterJPXDecode($data); | ||
115 | break; | ||
116 | } | ||
117 | case 'Crypt': { | ||
118 | return self::decodeFilterCrypt($data); | ||
119 | break; | ||
120 | } | ||
121 | default: { | ||
122 | return self::decodeFilterStandard($data); | ||
123 | break; | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | |||
128 | // --- FILTERS (PDF 32000-2008 - 7.4 Filters) ------------------------------ | ||
129 | |||
130 | /** | ||
131 | * Standard | ||
132 | * Default decoding filter (leaves data unchanged). | ||
133 | * @param $data (string) Data to decode. | ||
134 | * @return Decoded data string. | ||
135 | * @since 1.0.000 (2011-05-23) | ||
136 | * @public static | ||
137 | */ | ||
138 | public static function decodeFilterStandard($data) { | ||
139 | return $data; | ||
140 | } | ||
141 | |||
142 | /** | ||
143 | * ASCIIHexDecode | ||
144 | * Decodes data encoded in an ASCII hexadecimal representation, reproducing the original binary data. | ||
145 | * @param $data (string) Data to decode. | ||
146 | * @return Decoded data string. | ||
147 | * @since 1.0.000 (2011-05-23) | ||
148 | * @public static | ||
149 | */ | ||
150 | public static function decodeFilterASCIIHexDecode($data) { | ||
151 | // intialize string to return | ||
152 | $decoded = ''; | ||
153 | // all white-space characters shall be ignored | ||
154 | $data = preg_replace('/[\s]/', '', $data); | ||
155 | // check for EOD character: GREATER-THAN SIGN (3Eh) | ||
156 | $eod = strpos($data, '>'); | ||
157 | if ($eod !== false) { | ||
158 | // remove EOD and extra data (if any) | ||
159 | $data = substr($data, 0, $eod); | ||
160 | $eod = true; | ||
161 | } | ||
162 | // get data length | ||
163 | $data_length = strlen($data); | ||
164 | if (($data_length % 2) != 0) { | ||
165 | // odd number of hexadecimal digits | ||
166 | if ($eod) { | ||
167 | // EOD shall behave as if a 0 (zero) followed the last digit | ||
168 | $data = substr($data, 0, -1).'0'.substr($data, -1); | ||
169 | } else { | ||
170 | self::Error('decodeFilterASCIIHexDecode: invalid code'); | ||
171 | } | ||
172 | } | ||
173 | // check for invalid characters | ||
174 | if (preg_match('/[^a-fA-F\d]/', $data) > 0) { | ||
175 | self::Error('decodeFilterASCIIHexDecode: invalid code'); | ||
176 | } | ||
177 | // get one byte of binary data for each pair of ASCII hexadecimal digits | ||
178 | $decoded = pack('H*', $data); | ||
179 | return $decoded; | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * ASCII85Decode | ||
184 | * Decodes data encoded in an ASCII base-85 representation, reproducing the original binary data. | ||
185 | * @param $data (string) Data to decode. | ||
186 | * @return Decoded data string. | ||
187 | * @since 1.0.000 (2011-05-23) | ||
188 | * @public static | ||
189 | */ | ||
190 | public static function decodeFilterASCII85Decode($data) { | ||
191 | // intialize string to return | ||
192 | $decoded = ''; | ||
193 | // all white-space characters shall be ignored | ||
194 | $data = preg_replace('/[\s]/', '', $data); | ||
195 | // remove start sequence 2-character sequence <~ (3Ch)(7Eh) | ||
196 | if (strpos($data, '<~') !== false) { | ||
197 | // remove EOD and extra data (if any) | ||
198 | $data = substr($data, 2); | ||
199 | } | ||
200 | // check for EOD: 2-character sequence ~> (7Eh)(3Eh) | ||
201 | $eod = strpos($data, '~>'); | ||
202 | if ($eod !== false) { | ||
203 | // remove EOD and extra data (if any) | ||
204 | $data = substr($data, 0, $eod); | ||
205 | } | ||
206 | // data length | ||
207 | $data_length = strlen($data); | ||
208 | // check for invalid characters | ||
209 | if (preg_match('/[^\x21-\x75,\x74]/', $data) > 0) { | ||
210 | self::Error('decodeFilterASCII85Decode: invalid code'); | ||
211 | } | ||
212 | // z sequence | ||
213 | $zseq = chr(0).chr(0).chr(0).chr(0); | ||
214 | // position inside a group of 4 bytes (0-3) | ||
215 | $group_pos = 0; | ||
216 | $tuple = 0; | ||
217 | $pow85 = array((85*85*85*85), (85*85*85), (85*85), 85, 1); | ||
218 | $last_pos = ($data_length - 1); | ||
219 | // for each byte | ||
220 | for ($i = 0; $i < $data_length; ++$i) { | ||
221 | // get char value | ||
222 | $char = ord($data[$i]); | ||
223 | if ($char == 122) { // 'z' | ||
224 | if ($group_pos == 0) { | ||
225 | $decoded .= $zseq; | ||
226 | } else { | ||
227 | self::Error('decodeFilterASCII85Decode: invalid code'); | ||
228 | } | ||
229 | } else { | ||
230 | // the value represented by a group of 5 characters should never be greater than 2^32 - 1 | ||
231 | $tuple += (($char - 33) * $pow85[$group_pos]); | ||
232 | if ($group_pos == 4) { | ||
233 | $decoded .= chr($tuple >> 24).chr($tuple >> 16).chr($tuple >> 8).chr($tuple); | ||
234 | $tuple = 0; | ||
235 | $group_pos = 0; | ||
236 | } else { | ||
237 | ++$group_pos; | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | if ($group_pos > 1) { | ||
242 | $tuple += $pow85[($group_pos - 1)]; | ||
243 | } | ||
244 | // last tuple (if any) | ||
245 | switch ($group_pos) { | ||
246 | case 4: { | ||
247 | $decoded .= chr($tuple >> 24).chr($tuple >> 16).chr($tuple >> 8); | ||
248 | break; | ||
249 | } | ||
250 | case 3: { | ||
251 | $decoded .= chr($tuple >> 24).chr($tuple >> 16); | ||
252 | break; | ||
253 | } | ||
254 | case 2: { | ||
255 | $decoded .= chr($tuple >> 24); | ||
256 | break; | ||
257 | } | ||
258 | case 1: { | ||
259 | self::Error('decodeFilterASCII85Decode: invalid code'); | ||
260 | break; | ||
261 | } | ||
262 | } | ||
263 | return $decoded; | ||
264 | } | ||
265 | |||
266 | /** | ||
267 | * LZWDecode | ||
268 | * Decompresses data encoded using the LZW (Lempel-Ziv-Welch) adaptive compression method, reproducing the original text or binary data. | ||
269 | * @param $data (string) Data to decode. | ||
270 | * @return Decoded data string. | ||
271 | * @since 1.0.000 (2011-05-23) | ||
272 | * @public static | ||
273 | */ | ||
274 | public static function decodeFilterLZWDecode($data) { | ||
275 | // intialize string to return | ||
276 | $decoded = ''; | ||
277 | // data length | ||
278 | $data_length = strlen($data); | ||
279 | // convert string to binary string | ||
280 | $bitstring = ''; | ||
281 | for ($i = 0; $i < $data_length; ++$i) { | ||
282 | $bitstring .= sprintf('%08b', ord($data{$i})); | ||
283 | } | ||
284 | // get the number of bits | ||
285 | $data_length = strlen($bitstring); | ||
286 | // initialize code length in bits | ||
287 | $bitlen = 9; | ||
288 | // initialize dictionary index | ||
289 | $dix = 258; | ||
290 | // initialize the dictionary (with the first 256 entries). | ||
291 | $dictionary = array(); | ||
292 | for ($i = 0; $i < 256; ++$i) { | ||
293 | $dictionary[$i] = chr($i); | ||
294 | } | ||
295 | // previous val | ||
296 | $prev_index = 0; | ||
297 | // while we encounter EOD marker (257), read code_length bits | ||
298 | while (($data_length > 0) AND (($index = bindec(substr($bitstring, 0, $bitlen))) != 257)) { | ||
299 | // remove read bits from string | ||
300 | $bitstring = substr($bitstring, $bitlen); | ||
301 | // update number of bits | ||
302 | $data_length -= $bitlen; | ||
303 | if ($index == 256) { // clear-table marker | ||
304 | // reset code length in bits | ||
305 | $bitlen = 9; | ||
306 | // reset dictionary index | ||
307 | $dix = 258; | ||
308 | $prev_index = 256; | ||
309 | // reset the dictionary (with the first 256 entries). | ||
310 | $dictionary = array(); | ||
311 | for ($i = 0; $i < 256; ++$i) { | ||
312 | $dictionary[$i] = chr($i); | ||
313 | } | ||
314 | } elseif ($prev_index == 256) { | ||
315 | // first entry | ||
316 | $decoded .= $dictionary[$index]; | ||
317 | $prev_index = $index; | ||
318 | } else { | ||
319 | // check if index exist in the dictionary | ||
320 | if ($index < $dix) { | ||
321 | // index exist on dictionary | ||
322 | $decoded .= $dictionary[$index]; | ||
323 | $dic_val = $dictionary[$prev_index].$dictionary[$index][0]; | ||
324 | // store current index | ||
325 | $prev_index = $index; | ||
326 | } else { | ||
327 | // index do not exist on dictionary | ||
328 | $dic_val = $dictionary[$prev_index].$dictionary[$prev_index][0]; | ||
329 | $decoded .= $dic_val; | ||
330 | } | ||
331 | // update dictionary | ||
332 | $dictionary[$dix] = $dic_val; | ||
333 | ++$dix; | ||
334 | // change bit length by case | ||
335 | if ($dix == 2047) { | ||
336 | $bitlen = 12; | ||
337 | } elseif ($dix == 1023) { | ||
338 | $bitlen = 11; | ||
339 | } elseif ($dix == 511) { | ||
340 | $bitlen = 10; | ||
341 | } | ||
342 | } | ||
343 | } | ||
344 | return $decoded; | ||
345 | } | ||
346 | |||
347 | /** | ||
348 | * FlateDecode | ||
349 | * Decompresses data encoded using the zlib/deflate compression method, reproducing the original text or binary data. | ||
350 | * @param $data (string) Data to decode. | ||
351 | * @return Decoded data string. | ||
352 | * @since 1.0.000 (2011-05-23) | ||
353 | * @public static | ||
354 | */ | ||
355 | public static function decodeFilterFlateDecode($data) { | ||
356 | // intialize string to return | ||
357 | $decoded = @gzuncompress($data); | ||
358 | if ($decoded === false) { | ||
359 | self::Error('decodeFilterFlateDecode: invalid code'); | ||
360 | } | ||
361 | return $decoded; | ||
362 | } | ||
363 | |||
364 | /** | ||
365 | * RunLengthDecode | ||
366 | * Decompresses data encoded using a byte-oriented run-length encoding algorithm. | ||
367 | * @param $data (string) Data to decode. | ||
368 | * @since 1.0.000 (2011-05-23) | ||
369 | * @public static | ||
370 | */ | ||
371 | public static function decodeFilterRunLengthDecode($data) { | ||
372 | // intialize string to return | ||
373 | $decoded = ''; | ||
374 | // data length | ||
375 | $data_length = strlen($data); | ||
376 | $i = 0; | ||
377 | while($i < $data_length) { | ||
378 | // get current byte value | ||
379 | $byte = ord($data{$i}); | ||
380 | if ($byte == 128) { | ||
381 | // a length value of 128 denote EOD | ||
382 | break; | ||
383 | } elseif ($byte < 128) { | ||
384 | // if the length byte is in the range 0 to 127 | ||
385 | // the following length + 1 (1 to 128) bytes shall be copied literally during decompression | ||
386 | $decoded .= substr($data, ($i + 1), ($byte + 1)); | ||
387 | // move to next block | ||
388 | $i += ($byte + 2); | ||
389 | } else { | ||
390 | // if length is in the range 129 to 255, | ||
391 | // the following single byte shall be copied 257 - length (2 to 128) times during decompression | ||
392 | $decoded .= str_repeat($data{($i + 1)}, (257 - $byte)); | ||
393 | // move to next block | ||
394 | $i += 2; | ||
395 | } | ||
396 | } | ||
397 | return $decoded; | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * CCITTFaxDecode (NOT IMPLEMETED - RETURN AN EXCEPTION) | ||
402 | * Decompresses data encoded using the CCITT facsimile standard, reproducing the original data (typically monochrome image data at 1 bit per pixel). | ||
403 | * @param $data (string) Data to decode. | ||
404 | * @return Decoded data string. | ||
405 | * @since 1.0.000 (2011-05-23) | ||
406 | * @public static | ||
407 | */ | ||
408 | public static function decodeFilterCCITTFaxDecode($data) { | ||
409 | self::Error('~decodeFilterCCITTFaxDecode: this method has not been yet implemented'); | ||
410 | //return $data; | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * JBIG2Decode (NOT IMPLEMETED - RETURN AN EXCEPTION) | ||
415 | * Decompresses data encoded using the JBIG2 standard, reproducing the original monochrome (1 bit per pixel) image data (or an approximation of that data). | ||
416 | * @param $data (string) Data to decode. | ||
417 | * @return Decoded data string. | ||
418 | * @since 1.0.000 (2011-05-23) | ||
419 | * @public static | ||
420 | */ | ||
421 | public static function decodeFilterJBIG2Decode($data) { | ||
422 | self::Error('~decodeFilterJBIG2Decode: this method has not been yet implemented'); | ||
423 | //return $data; | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * DCTDecode (NOT IMPLEMETED - RETURN AN EXCEPTION) | ||
428 | * Decompresses data encoded using a DCT (discrete cosine transform) technique based on the JPEG standard, reproducing image sample data that approximates the original data. | ||
429 | * @param $data (string) Data to decode. | ||
430 | * @return Decoded data string. | ||
431 | * @since 1.0.000 (2011-05-23) | ||
432 | * @public static | ||
433 | */ | ||
434 | public static function decodeFilterDCTDecode($data) { | ||
435 | self::Error('~decodeFilterDCTDecode: this method has not been yet implemented'); | ||
436 | //return $data; | ||
437 | } | ||
438 | |||
439 | /** | ||
440 | * JPXDecode (NOT IMPLEMETED - RETURN AN EXCEPTION) | ||
441 | * Decompresses data encoded using the wavelet-based JPEG2000 standard, reproducing the original image data. | ||
442 | * @param $data (string) Data to decode. | ||
443 | * @return Decoded data string. | ||
444 | * @since 1.0.000 (2011-05-23) | ||
445 | * @public static | ||
446 | */ | ||
447 | public static function decodeFilterJPXDecode($data) { | ||
448 | self::Error('~decodeFilterJPXDecode: this method has not been yet implemented'); | ||
449 | //return $data; | ||
450 | } | ||
451 | |||
452 | /** | ||
453 | * Crypt (NOT IMPLEMETED - RETURN AN EXCEPTION) | ||
454 | * Decrypts data encrypted by a security handler, reproducing the data as it was before encryption. | ||
455 | * @param $data (string) Data to decode. | ||
456 | * @return Decoded data string. | ||
457 | * @since 1.0.000 (2011-05-23) | ||
458 | * @public static | ||
459 | */ | ||
460 | public static function decodeFilterCrypt($data) { | ||
461 | self::Error('~decodeFilterCrypt: this method has not been yet implemented'); | ||
462 | //return $data; | ||
463 | } | ||
464 | |||
465 | // --- END FILTERS SECTION ------------------------------------------------- | ||
466 | |||
467 | /** | ||
468 | * Throw an exception. | ||
469 | * @param $msg (string) The error message | ||
470 | * @since 1.0.000 (2011-05-23) | ||
471 | * @public static | ||
472 | */ | ||
473 | public static function Error($msg) { | ||
474 | throw new Exception('TCPDF_PARSER ERROR: '.$msg); | ||
475 | } | ||
476 | |||
477 | } // END OF TCPDF_FILTERS CLASS | ||
478 | |||
479 | //============================================================+ | ||
480 | // END OF FILE | ||
481 | //============================================================+ | ||