1<?php 2/** 3 * This file is part of FPDI 4 * 5 * @package setasign\Fpdi 6 * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com) 7 * @license http://opensource.org/licenses/mit-license The MIT License 8 */ 9 10namespace setasign\Fpdi\PdfParser\Filter; 11 12/** 13 * Class for handling ASCII base-85 encoded data 14 * 15 * @package setasign\Fpdi\PdfParser\Filter 16 */ 17class Ascii85 implements FilterInterface 18{ 19 /** 20 * Decode ASCII85 encoded string. 21 * 22 * @param string $data The input string 23 * @return string 24 * @throws Ascii85Exception 25 */ 26 public function decode($data) 27 { 28 $out = ''; 29 $state = 0; 30 $chn = null; 31 32 $data = \preg_replace('/\s/', '', $data); 33 34 $l = \strlen($data); 35 36 /** @noinspection ForeachInvariantsInspection */ 37 for ($k = 0; $k < $l; ++$k) { 38 $ch = \ord($data[$k]) & 0xff; 39 40 //Start <~ 41 if ($k === 0 && $ch === 60 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 126) { 42 $k++; 43 continue; 44 } 45 //End ~> 46 if ($ch === 126 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 62) { 47 break; 48 } 49 50 if ($ch === 122 /* z */ && $state === 0) { 51 $out .= \chr(0) . \chr(0) . \chr(0) . \chr(0); 52 continue; 53 } 54 55 if ($ch < 33 /* ! */ || $ch > 117 /* u */) { 56 throw new Ascii85Exception( 57 'Illegal character found while ASCII85 decode.', 58 Ascii85Exception::ILLEGAL_CHAR_FOUND 59 ); 60 } 61 62 $chn[$state] = $ch - 33;/* ! */ 63 $state++; 64 65 if ($state === 5) { 66 $state = 0; 67 $r = 0; 68 for ($j = 0; $j < 5; ++$j) { 69 /** @noinspection UnnecessaryCastingInspection */ 70 $r = (int)($r * 85 + $chn[$j]); 71 } 72 73 $out .= \chr($r >> 24) 74 . \chr($r >> 16) 75 . \chr($r >> 8) 76 . \chr($r); 77 } 78 } 79 80 if ($state === 1) { 81 throw new Ascii85Exception( 82 'Illegal length while ASCII85 decode.', 83 Ascii85Exception::ILLEGAL_LENGTH 84 ); 85 } 86 87 if ($state === 2) { 88 $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1] + 1) * 85 * 85 * 85; 89 $out .= \chr($r >> 24); 90 91 } elseif ($state === 3) { 92 $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2] + 1) * 85 * 85; 93 $out .= \chr($r >> 24); 94 $out .= \chr($r >> 16); 95 96 } elseif ($state === 4) { 97 $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3] + 1) * 85; 98 $out .= \chr($r >> 24); 99 $out .= \chr($r >> 16); 100 $out .= \chr($r >> 8); 101 } 102 103 return $out; 104 } 105} 106