]>
git.immae.eu Git - github/wallabag/wallabag.git/blob - inc/3rdparty/libraries/tcpdf/include/tcpdf_filters.php
2 //============================================================+
3 // File name : tcpdf_filters.php
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
12 // This file is part of TCPDF software library.
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.
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.
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>.
28 // See LICENSE.TXT file for more information.
29 // -------------------------------------------------------------------
31 // Description : This is a PHP class for decoding common PDF filters (PDF 32000-2008 - 7.4 Filters).
33 //============================================================+
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
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.
49 * @author Nicola Asuni - info@tecnick.com
54 * Define a list of available filter decoders.
57 private static $available_filters = array ( 'ASCIIHexDecode' , 'ASCII85Decode' , 'LZWDecode' , 'FlateDecode' , 'RunLengthDecode' );
59 // -----------------------------------------------------------------------------
62 * Get a list of available decoding filters.
63 * @return (array) Array of available filter decoders.
64 * @since 1.0.000 (2011-05-23)
67 public static function getAvailableFilters () {
68 return self
:: $available_filters ;
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)
79 public static function decodeFilter ( $filter , $data ) {
81 case 'ASCIIHexDecode' : {
82 return self
:: decodeFilterASCIIHexDecode ( $data );
85 case 'ASCII85Decode' : {
86 return self
:: decodeFilterASCII85Decode ( $data );
90 return self
:: decodeFilterLZWDecode ( $data );
94 return self
:: decodeFilterFlateDecode ( $data );
97 case 'RunLengthDecode' : {
98 return self
:: decodeFilterRunLengthDecode ( $data );
101 case 'CCITTFaxDecode' : {
102 return self
:: decodeFilterCCITTFaxDecode ( $data );
105 case 'JBIG2Decode' : {
106 return self
:: decodeFilterJBIG2Decode ( $data );
110 return self
:: decodeFilterDCTDecode ( $data );
114 return self
:: decodeFilterJPXDecode ( $data );
118 return self
:: decodeFilterCrypt ( $data );
122 return self
:: decodeFilterStandard ( $data );
128 // --- FILTERS (PDF 32000-2008 - 7.4 Filters) ------------------------------
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)
138 public static function decodeFilterStandard ( $data ) {
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)
150 public static function decodeFilterASCIIHexDecode ( $data ) {
151 // intialize string to return
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 );
163 $data_length = strlen ( $data );
164 if (( $data_length %
2 ) != 0 ) {
165 // odd number of hexadecimal digits
167 // EOD shall behave as if a 0 (zero) followed the last digit
168 $data = substr ( $data , 0 , - 1 ). '0' . substr ( $data , - 1 );
170 self
:: Error ( 'decodeFilterASCIIHexDecode: invalid code' );
173 // check for invalid characters
174 if ( preg_match ( '/[^a-fA-F\d]/' , $data ) > 0 ) {
175 self
:: Error ( 'decodeFilterASCIIHexDecode: invalid code' );
177 // get one byte of binary data for each pair of ASCII hexadecimal digits
178 $decoded = pack ( 'H*' , $data );
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)
190 public static function decodeFilterASCII85Decode ( $data ) {
191 // intialize string to return
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 );
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 );
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' );
213 $zseq = chr ( 0 ). chr ( 0 ). chr ( 0 ). chr ( 0 );
214 // position inside a group of 4 bytes (0-3)
217 $pow85 = array (( 85 * 85 * 85 * 85 ), ( 85 * 85 * 85 ), ( 85 * 85 ), 85 , 1 );
218 $last_pos = ( $data_length - 1 );
220 for ( $i = 0 ; $i < $data_length ; ++
$i ) {
222 $char = ord ( $data [ $i ]);
223 if ( $char == 122 ) { // 'z'
224 if ( $group_pos == 0 ) {
227 self
:: Error ( 'decodeFilterASCII85Decode: invalid code' );
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 );
241 if ( $group_pos > 1 ) {
242 $tuple +
= $pow85 [( $group_pos - 1 )];
244 // last tuple (if any)
245 switch ( $group_pos ) {
247 $decoded .= chr ( $tuple >> 24 ). chr ( $tuple >> 16 ). chr ( $tuple >> 8 );
251 $decoded .= chr ( $tuple >> 24 ). chr ( $tuple >> 16 );
255 $decoded .= chr ( $tuple >> 24 );
259 self
:: Error ( 'decodeFilterASCII85Decode: invalid code' );
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)
274 public static function decodeFilterLZWDecode ( $data ) {
275 // intialize string to return
278 $data_length = strlen ( $data );
279 // convert string to binary string
281 for ( $i = 0 ; $i < $data_length ; ++
$i ) {
282 $bitstring .= sprintf ( '%08b' , ord ( $data{ $i
}));
284 // get the number of bits
285 $data_length = strlen ( $bitstring );
286 // initialize code length in bits
288 // initialize dictionary index
290 // initialize the dictionary (with the first 256 entries).
291 $dictionary = array ();
292 for ( $i = 0 ; $i < 256 ; ++
$i ) {
293 $dictionary [ $i ] = chr ( $i );
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
306 // reset dictionary index
309 // reset the dictionary (with the first 256 entries).
310 $dictionary = array ();
311 for ( $i = 0 ; $i < 256 ; ++
$i ) {
312 $dictionary [ $i ] = chr ( $i );
314 } elseif ( $prev_index == 256 ) {
316 $decoded .= $dictionary [ $index ];
317 $prev_index = $index ;
319 // check if index exist in the dictionary
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 ;
327 // index do not exist on dictionary
328 $dic_val = $dictionary [ $prev_index ]. $dictionary [ $prev_index ][ 0 ];
329 $decoded .= $dic_val ;
332 $dictionary [ $dix ] = $dic_val ;
334 // change bit length by case
337 } elseif ( $dix == 1023 ) {
339 } elseif ( $dix == 511 ) {
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)
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' );
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)
371 public static function decodeFilterRunLengthDecode ( $data ) {
372 // intialize string to return
375 $data_length = strlen ( $data );
377 while ( $i < $data_length ) {
378 // get current byte value
379 $byte = ord ( $data{ $i
});
381 // a length value of 128 denote EOD
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
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
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)
408 public static function decodeFilterCCITTFaxDecode ( $data ) {
409 self
:: Error ( '~decodeFilterCCITTFaxDecode: this method has not been yet implemented' );
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)
421 public static function decodeFilterJBIG2Decode ( $data ) {
422 self
:: Error ( '~decodeFilterJBIG2Decode: this method has not been yet implemented' );
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)
434 public static function decodeFilterDCTDecode ( $data ) {
435 self
:: Error ( '~decodeFilterDCTDecode: this method has not been yet implemented' );
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)
447 public static function decodeFilterJPXDecode ( $data ) {
448 self
:: Error ( '~decodeFilterJPXDecode: this method has not been yet implemented' );
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)
460 public static function decodeFilterCrypt ( $data ) {
461 self
:: Error ( '~decodeFilterCrypt: this method has not been yet implemented' );
465 // --- END FILTERS SECTION -------------------------------------------------
468 * Throw an exception.
469 * @param $msg (string) The error message
470 * @since 1.0.000 (2011-05-23)
473 public static function Error ( $msg ) {
474 throw new Exception ( 'TCPDF_PARSER ERROR: ' . $msg );
477 } // END OF TCPDF_FILTERS CLASS
479 //============================================================+
481 //============================================================+