Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/tcpdf/tcpdf_filters.php
Go to the documentation of this file.
00001 <?php
00002 //============================================================+
00003 // File name   : tcpdf_filters.php
00004 // Version     : 1.0.000
00005 // Begin       : 2011-05-23
00006 // Last Update : 2011-06-26
00007 // Author      : Nicola Asuni - Tecnick.com S.r.l - Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com
00008 // License     : http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT GNU-LGPLv3 + YOU CAN'T REMOVE ANY TCPDF COPYRIGHT NOTICE OR LINK FROM THE GENERATED PDF DOCUMENTS.
00009 // -------------------------------------------------------------------
00010 // Copyright (C) 2011-2011  Nicola Asuni - Tecnick.com S.r.l.
00011 //
00012 // This file is part of TCPDF software library.
00013 //
00014 // TCPDF is free software: you can redistribute it and/or modify it
00015 // under the terms of the GNU Lesser General Public License as
00016 // published by the Free Software Foundation, either version 3 of the
00017 // License, or (at your option) any later version. Additionally,
00018 // YOU CAN'T REMOVE ANY TCPDF COPYRIGHT NOTICE OR LINK FROM THE
00019 // GENERATED PDF DOCUMENTS.
00020 //
00021 // TCPDF is distributed in the hope that it will be useful, but
00022 // WITHOUT ANY WARRANTY; without even the implied warranty of
00023 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00024 // See the GNU Lesser General Public License for more details.
00025 //
00026 // You should have received a copy of the License
00027 // along with TCPDF. If not, see
00028 // <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>.
00029 //
00030 // See LICENSE.TXT file for more information.
00031 // -------------------------------------------------------------------
00032 //
00033 // Description : This is a PHP class for decoding common PDF filters (PDF 32000-2008 - 7.4 Filters).
00034 //
00035 //============================================================+
00036 
00053 class TCPDF_FILTERS {
00054 
00059         private $available_filters = array('ASCIIHexDecode', 'ASCII85Decode', 'LZWDecode', 'FlateDecode', 'RunLengthDecode');
00060 
00061 // -----------------------------------------------------------------------------
00062 
00069         public function getAvailableFilters() {
00070                 return $this->available_filters;
00071         }
00072 
00081         public function decodeFilter($filter, $data) {
00082                 switch ($filter) {
00083                         case 'ASCIIHexDecode': {
00084                                 return $this->decodeFilterASCIIHexDecode($data);
00085                                 break;
00086                         }
00087                         case 'ASCII85Decode': {
00088                                 return $this->decodeFilterASCII85Decode($data);
00089                                 break;
00090                         }
00091                         case 'LZWDecode': {
00092                                 return $this->decodeFilterLZWDecode($data);
00093                                 break;
00094                         }
00095                         case 'FlateDecode': {
00096                                 return $this->decodeFilterFlateDecode($data);
00097                                 break;
00098                         }
00099                         case 'RunLengthDecode': {
00100                                 return $this->decodeFilterRunLengthDecode($data);
00101                                 break;
00102                         }
00103                         case 'CCITTFaxDecode': {
00104                                 return $this->decodeFilterCCITTFaxDecode($data);
00105                                 break;
00106                         }
00107                         case 'JBIG2Decode': {
00108                                 return $this->decodeFilterJBIG2Decode($data);
00109                                 break;
00110                         }
00111                         case 'DCTDecode': {
00112                                 return $this->decodeFilterDCTDecode($data);
00113                                 break;
00114                         }
00115                         case 'JPXDecode': {
00116                                 return $this->decodeFilterJPXDecode($data);
00117                                 break;
00118                         }
00119                         case 'Crypt': {
00120                                 return $this->decodeFilterCrypt($data);
00121                                 break;
00122                         }
00123                         default: {
00124                                 return decodeFilterStandard($data);
00125                                 break;
00126                         }
00127                 }
00128         }
00129 
00130         // --- FILTERS (PDF 32000-2008 - 7.4 Filters) ------------------------------
00131 
00140         public function decodeFilterStandard($data) {
00141                 return $data;
00142         }
00143 
00152         public function decodeFilterASCIIHexDecode($data) {
00153                 // intialize string to return
00154                 $decoded = '';
00155                 // all white-space characters shall be ignored
00156                 $data = preg_replace('/[\s]/', '', $data);
00157                 // check for EOD character: GREATER-THAN SIGN (3Eh)
00158                 $eod = strpos($data, '>');
00159                 if ($eod !== false) {
00160                         // remove EOD and extra data (if any)
00161                         $data = substr($data, 0, $eod);
00162                         $eod = true;
00163                 }
00164                 // get data length
00165                 $data_length = strlen($data);
00166                 if (($data_length % 2) != 0) {
00167                         // odd number of hexadecimal digits
00168                         if ($eod) {
00169                                 // EOD shall behave as if a 0 (zero) followed the last digit
00170                                 $data = substr($data, 0, -1).'0'.substr($data, -1);
00171                         } else {
00172                                 $this->Error('decodeASCIIHex: invalid code');
00173                         }
00174                 }
00175                 // check for invalid characters
00176                 if (preg_match('/[^a-fA-F\d]/', $data) > 0) {
00177                         $this->Error('decodeASCIIHex: invalid code');
00178                 }
00179                 // get one byte of binary data for each pair of ASCII hexadecimal digits
00180                 $decoded = pack('H*', $data);
00181                 return $decoded;
00182         }
00183 
00192         public function decodeFilterASCII85Decode($data) {
00193                 // intialize string to return
00194                 $decoded = '';
00195                 // all white-space characters shall be ignored
00196                 $data = preg_replace('/[\s]/', '', $data);
00197                 // remove start sequence 2-character sequence <~ (3Ch)(7Eh)
00198                 if (strpos($data, '<~') !== false) {
00199                         // remove EOD and extra data (if any)
00200                         $data = substr($data, 2);
00201                 }
00202                 // check for EOD: 2-character sequence ~> (7Eh)(3Eh)
00203                 $eod = strpos($data, '~>');
00204                 if ($eod !== false) {
00205                         // remove EOD and extra data (if any)
00206                         $data = substr($data, 0, $eod);
00207                 }
00208                 // data length
00209                 $data_length = strlen($data);
00210                 // check for invalid characters
00211                 if (preg_match('/[^\x21-\x75,\x74]/', $data) > 0) {
00212                         $this->Error('decodeASCII85: invalid code');
00213                 }
00214                 // z sequence
00215                 $zseq = chr(0).chr(0).chr(0).chr(0);
00216                 // position inside a group of 4 bytes (0-3)
00217                 $group_pos = 0;
00218                 $tuple = 0;
00219                 $pow85 = array((85*85*85*85), (85*85*85), (85*85), 85, 1);
00220                 $last_pos = ($data_length - 1);
00221                 // for each byte
00222                 for ($i = 0; $i < $data_length; ++$i) {
00223                         // get char value
00224                         $char = ord($data[$i]);
00225                         if ($char == 122) { // 'z'
00226                                 if ($group_pos == 0) {
00227                                         $decoded .= $zseq;
00228                                 } else {
00229                                         $this->Error('decodeASCII85: invalid code');
00230                                 }
00231                         } else {
00232                                 // the value represented by a group of 5 characters should never be greater than 2^32 - 1
00233                                 $tuple += (($char - 33) * $pow85[$group_pos]);
00234                                 if ($group_pos == 4) {
00235                                         $decoded .= chr($tuple >> 24).chr($tuple >> 16).chr($tuple >> 8).chr($tuple);
00236                                         $tuple = 0;
00237                                         $group_pos = 0;
00238                                 } else {
00239                                         ++$group_pos;
00240                                 }
00241                         }
00242                 }
00243                 if ($group_pos > 1) {
00244                         $tuple += $pow85[($group_pos - 1)];
00245                 }
00246                 // last tuple (if any)
00247                 switch ($group_pos) {
00248                         case 4: {
00249                                 $decoded .= chr($tuple >> 24).chr($tuple >> 16).chr($tuple >> 8);
00250                                 break;
00251                         }
00252                         case 3: {
00253                                 $decoded .= chr($tuple >> 24).chr($tuple >> 16);
00254                                 break;
00255                         }
00256                         case 2: {
00257                                 $decoded .= chr($tuple >> 24);
00258                                 break;
00259                         }
00260                         case 1: {
00261                                 $this->Error('decodeASCII85: invalid code');
00262                                 break;
00263                         }
00264                 }
00265                 return $decoded;
00266         }
00267 
00276         public function decodeFilterLZWDecode($data) {
00277                 // intialize string to return
00278                 $decoded = '';
00279                 // data length
00280                 $data_length = strlen($data);
00281                 // convert string to binary string
00282                 $bitstring = '';
00283                 for ($i = 0; $i < $data_length; ++$i) {
00284                         $bitstring .= sprintf('%08b', ord($data{$i}));
00285                 }
00286                 // get the number of bits
00287                 $data_length = strlen($bitstring);
00288                 // initialize code length in bits
00289                 $bitlen = 9;
00290                 // initialize dictionary index
00291                 $dix = 258;
00292                 // initialize the dictionary (with the first 256 entries).
00293                 $dictionary = array();
00294                 for ($i = 0; $i < 256; ++$i) {
00295                         $dictionary[$i] = chr($i);
00296                 }
00297                 // previous val
00298                 $prev_index = 0;
00299                 // while we encounter EOD marker (257), read code_length bits
00300                 while (($data_length > 0) AND (($index = bindec(substr($bitstring, 0, $bitlen))) != 257)) {
00301                         // remove read bits from string
00302                         $bitstring = substr($bitstring, $bitlen);
00303                         // update number of bits
00304                         $data_length -= $bitlen;
00305                         if ($index == 256) { // clear-table marker
00306                                 // reset code length in bits
00307                                 $bitlen = 9;
00308                                 // reset dictionary index
00309                                 $dix = 258;
00310                                 $prev_index = 256;
00311                                 // reset the dictionary (with the first 256 entries).
00312                                 $dictionary = array();
00313                                 for ($i = 0; $i < 256; ++$i) {
00314                                         $dictionary[$i] = chr($i);
00315                                 }
00316                         } elseif ($prev_index == 256) {
00317                                 // first entry
00318                                 $decoded .= $dictionary[$index];
00319                                 $prev_index = $index;
00320                         } else {
00321                                 // check if index exist in the dictionary
00322                                 if ($index < $dix) {
00323                                         // index exist on dictionary
00324                                         $decoded .= $dictionary[$index];
00325                                         $dic_val = $dictionary[$prev_index].$dictionary[$index]{0};
00326                                         // store current index
00327                                         $prev_index = $index;
00328                                 } else {
00329                                         // index do not exist on dictionary
00330                                         $dic_val = $dictionary[$prev_index].$dictionary[$prev_index]{0};
00331                                         $decoded .= $dic_val;
00332                                 }
00333                                 // update dictionary
00334                                 $dictionary[$dix] = $dic_val;
00335                                 ++$dix;
00336                                 // change bit length by case
00337                                 if ($dix == 2047) {
00338                                         $bitlen = 12;
00339                                 } elseif ($dix == 1023) {
00340                                         $bitlen = 11;
00341                                 } elseif ($dix == 511) {
00342                                         $bitlen = 10;
00343                                 }
00344                         }
00345                 }
00346                 return $decoded;
00347         }
00348 
00357         public function decodeFilterFlateDecode($data) {
00358                 // intialize string to return
00359                 $decoded = gzuncompress($data);
00360                 if ($decoded === false) {
00361                         $this->Error('decodeFlate: invalid code');
00362                 }
00363                 return $decoded;
00364         }
00365 
00373         public function decodeFilterRunLengthDecode($data) {
00374                 // intialize string to return
00375                 $decoded = '';
00376                 // data length
00377                 $data_length = strlen($data);
00378                 $i = 0;
00379                 while($i < $data_length) {
00380                         // get current byte value
00381                         $byte = ord($data{$i});
00382                         if ($byte == 128) {
00383                                 // a length value of 128 denote EOD
00384                                 break;
00385                         } elseif ($byte < 128) {
00386                                 // if the length byte is in the range 0 to 127
00387                                 // the following length + 1 (1 to 128) bytes shall be copied literally during decompression
00388                                 $decoded .= substr($data, ($i + 1), ($byte + 1));
00389                                 // move to next block
00390                                 $i += ($byte + 2);
00391                         } else {
00392                                 // if length is in the range 129 to 255,
00393                                 // the following single byte shall be copied 257 - length (2 to 128) times during decompression
00394                                 $decoded .= str_repeat($data{($i + 1)}, (257 - $byte));
00395                                 // move to next block
00396                                 $i += 2;
00397                         }
00398                 }
00399                 return $decoded;
00400         }
00401 
00410         public function decodeFilterCCITTFaxDecode($data) {
00411                 return $data;
00412         }
00413 
00422         public function decodeFilterJBIG2Decode($data) {
00423                 return $data;
00424         }
00425 
00434         public function decodeFilterDCTDecode($data) {
00435                 return $data;
00436         }
00437 
00446         public function decodeFilterJPXDecode($data) {
00447                 return $data;
00448         }
00449 
00458         public function decodeFilterCrypt($data) {
00459                 return $data;
00460         }
00461 
00462         // --- END FILTERS SECTION -------------------------------------------------
00463 
00470         public function Error($msg) {
00471                 // exit program and print error
00472                 die('<strong>TCPDF_FILTERS ERROR: </strong>'.$msg);
00473         }
00474 
00475 } // END OF TCPDF_FILTERS CLASS
00476 
00477 //============================================================+
00478 // END OF FILE
00479 //============================================================+
 All Data Structures Namespaces Files Functions Variables Enumerations