Index: tests/Zend/Pdf/Filter/AllTests.php =================================================================== --- tests/Zend/Pdf/Filter/AllTests.php (revision 19744) +++ tests/Zend/Pdf/Filter/AllTests.php (working copy) @@ -27,6 +27,7 @@ require_once 'PHPUnit/TextUI/TestRunner.php'; require_once 'Zend/Pdf/Filter/RunLengthTest.php'; +require_once 'Zend/Pdf/Filter/Ascii85Test.php'; /** * @category Zend @@ -48,6 +49,7 @@ $suite = new PHPUnit_Framework_TestSuite('Zend Framework - Zend_Pdf_Filter'); $suite->addTestSuite('Zend_Pdf_Filter_RunLengthTest'); + $suite->addTestSuite('Zend_Pdf_Filter_Ascii85Test'); return $suite; } Index: tests/Zend/Pdf/Filter/Ascii85Test.php =================================================================== --- tests/Zend/Pdf/Filter/Ascii85Test.php (revision 0) +++ tests/Zend/Pdf/Filter/Ascii85Test.php (revision 0) @@ -0,0 +1,75 @@ +~>"; + $this->assertEquals($encodedContents, $testString); + } + + public function testStringDivisibleBy4Decode() + { + $encodedContents = "9Q+r_D'3P3F*2=BA8c:&EZfF;F~>"; + $decodedContents = Zend_Pdf_Filter_Ascii85::decode($encodedContents); + $testString = 'Lorem ipsum dolor sit amet orci aliquam.'; + $this->assertEquals($decodedContents, $testString); + } + + public function testStringNotDivisibleBy4Encode() + { + $decodedContents = 'Lorem ipsum dolor sit amet, consectetur cras amet.'; + $encodedContents = Zend_Pdf_Filter_Ascii85::encode($decodedContents); + $testString = "9Q+r_D'3P3F*2=BA8c:&EZfF;F"; + $this->assertEquals($encodedContents, $testString); + } + + public function testStringNotDivisibleBy4Decode() + { + $encodedContents .= "9Q+r_D'3P3F*2=BA8c:&EZfF;F"; + $decodedContents = Zend_Pdf_Filter_Ascii85::decode($encodedContents); + $testString = 'Lorem ipsum dolor sit amet, consectetur cras amet.'; + $this->assertEquals($decodedContents, $testString); + } +} Index: library/Zend/Pdf/Filter/Ascii85.php =================================================================== --- library/Zend/Pdf/Filter/Ascii85.php (revision 19744) +++ library/Zend/Pdf/Filter/Ascii85.php (working copy) @@ -42,8 +42,65 @@ */ public static function encode($data, $params = null) { - require_once 'Zend/Pdf/Exception.php'; - throw new Zend_Pdf_Exception('Not implemented yet'); + $output = ''; + $dataLength = strlen($data); + + for ($i = 0; $i < $dataLength; $i += 4) { + //convert the 4 characters into a 32-bit number + $chunk = substr($data, $i, 4); + + if (strlen($chunk) < 4) { + //partial chunk + break; + } + + $b = unpack("N", $chunk); + $b = $b[1]; + + //special char for all 4 bytes = 0 + if ($b == 0) { + $output .= 'z'; + continue; + } + + //encode into 5 bytes + for ($j = 4; $j >= 0; $j--) { + $foo = (int) (($b / pow(85,$j)) + 33); + $b %= pow(85,$j); + $output .= chr($foo); + } + } + + //encode partial chunk + if ($i < $dataLength) { + $n = $dataLength - $i; + $chunk = substr($data, -$n); + + //0 pad the rest + for ($j = $n;$j < 4;$j++) { + $chunk .= chr(0); + } + + $b = unpack("N", $chunk); + $b = $b[1]; + + //encode just $n + 1 + for ($j = 4; $j >= (4 - $n); $j--) { + $foo = (int) (($b / pow(85,$j)) + 33); + $b %= pow(85,$j); + $output .= chr($foo); + } + } + + //EOD + $output .= '~>'; + + //make sure lines are split + $output = chunk_split($output, 76, "\n"); + + //get rid of new line at the end + $output = substr($output, 0, -1); + return $output; } /** @@ -56,7 +113,69 @@ */ public static function decode($data, $params = null) { - require_once 'Zend/Pdf/Exception.php'; - throw new Zend_Pdf_Exception('Not implemented yet'); + $output = ''; + + //get rid of the whitespaces + $whiteSpace = array("\x00", "\x09", "\x0A", "\x0C", "\x0D", "\x20"); + $data = str_replace($whiteSpace, '', $data); + + if (substr($data, -2) != '~>') { + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Invalid EOF marker'); + return ''; + } + + $data = substr($data, 0, (strlen($data) - 2)); + $dataLength = strlen($data); + + for ($i = 0; $i < $dataLength; $i += 5) { + $b = 0; + + if (substr($data, $i, 1) == "z") { + $i -= 4; + $output .= pack("N", 0); + next; + } + + $c = substr($data, $i, 5); + + if(strlen($c) < 5) { + //partial chunk + break; + } + + $c = unpack('C5', $c); + $value = 0; + + for ($j = 1; $j <= 5; $j++) { + $value += (($c[$j] - 33) * pow(85, (5 - $j))); + } + + $output .= pack("N", $value); + } + + //decode partial + if ($i < $dataLength) { + $value = 0; + $chunk = substr($data, $i); + $partialLength = strlen($chunk); + + //pad the rest of the chunk with u's + //until the lenght of the chunk is 5 + for ($j = 0; $j < (5 - $partialLength); $j++) { + $chunk .= 'u'; + } + + $c = unpack('C5', $chunk); + + for ($j = 1; $j <= 5; $j++) { + $value += (($c[$j] - 33) * pow(85, (5 - $j))); + } + + $foo = pack("N", $value); + $output .= substr($foo, 0, ($partialLength - 1)); + } + + return $output; } }