|
|
@@ -0,0 +1,124 @@
|
|
|
+<?php
|
|
|
+/**
|
|
|
+ * Zend Framework
|
|
|
+ *
|
|
|
+ * LICENSE
|
|
|
+ *
|
|
|
+ * This source file is subject to the new BSD license that is bundled
|
|
|
+ * with this package in the file LICENSE.txt.
|
|
|
+ * It is also available through the world-wide-web at this URL:
|
|
|
+ * http://framework.zend.com/license/new-bsd
|
|
|
+ * If you did not receive a copy of the license and are unable to
|
|
|
+ * obtain it through the world-wide-web, please send an email
|
|
|
+ * to license@zend.com so we can send you a copy immediately.
|
|
|
+ *
|
|
|
+ * @category Zend
|
|
|
+ * @package Zend_Pdf
|
|
|
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
|
|
+ * @license http://framework.zend.com/license/new-bsd New BSD License
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+/** Zend_Pdf_Filter_Interface */
|
|
|
+require_once 'Zend/Pdf/Filter/Interface.php';
|
|
|
+
|
|
|
+/**
|
|
|
+ * RunLength stream filter
|
|
|
+ *
|
|
|
+ * @package Zend_Pdf
|
|
|
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
|
|
+ * @license http://framework.zend.com/license/new-bsd New BSD License
|
|
|
+ */
|
|
|
+class Zend_Pdf_Filter_RunLength implements Zend_Pdf_Filter_Interface
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * Encode data
|
|
|
+ *
|
|
|
+ * @param string $data
|
|
|
+ * @param array $params
|
|
|
+ * @return string
|
|
|
+ * @throws Zend_Pdf_Exception
|
|
|
+ */
|
|
|
+ public static function encode($data, $params = null)
|
|
|
+ {
|
|
|
+ $output = '';
|
|
|
+
|
|
|
+ $chainStartOffset = 0;
|
|
|
+ $offset = 0;
|
|
|
+
|
|
|
+ while ($offset < strlen($data)) {
|
|
|
+ // Do not encode 2 char chains since they produce 2 char run sequence,
|
|
|
+ // but it takes more time to decode such output (because of processing additional run)
|
|
|
+ if (($repeatedCharChainLength = strspn($data, $data[$offset], $offset + 1, 127) + 1) > 2) {
|
|
|
+ if ($chainStartOffset != $offset) {
|
|
|
+ // Drop down previouse (non-repeatable chars) run
|
|
|
+ $output .= chr($offset - $chainStartOffset - 1)
|
|
|
+ . substr($data, $chainStartOffset, $offset - $chainStartOffset);
|
|
|
+ }
|
|
|
+
|
|
|
+ $output .= chr(257 - $repeatedCharChainLength) . $data[$offset];
|
|
|
+
|
|
|
+ $offset += $repeatedCharChainLength;
|
|
|
+ $chainStartOffset = $offset;
|
|
|
+ } else {
|
|
|
+ $offset++;
|
|
|
+
|
|
|
+ if ($offset - $chainStartOffset == 128) {
|
|
|
+ // Maximum run length is reached
|
|
|
+ // Drop down non-repeatable chars run
|
|
|
+ $output .= "\x7F" . substr($data, $chainStartOffset, 128);
|
|
|
+
|
|
|
+ $chainStartOffset = $offset;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($chainStartOffset != $offset) {
|
|
|
+ // Drop down non-repeatable chars run
|
|
|
+ $output .= chr($offset - $chainStartOffset - 1) . substr($data, $chainStartOffset, $offset - $chainStartOffset);
|
|
|
+ }
|
|
|
+
|
|
|
+ $output .= "\x80";
|
|
|
+
|
|
|
+ return $output;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Decode data
|
|
|
+ *
|
|
|
+ * @param string $data
|
|
|
+ * @param array $params
|
|
|
+ * @return string
|
|
|
+ * @throws Zend_Pdf_Exception
|
|
|
+ */
|
|
|
+ public static function decode($data, $params = null)
|
|
|
+ {
|
|
|
+ $dataLength = strlen($data);
|
|
|
+ $output = '';
|
|
|
+ $offset = 0;
|
|
|
+
|
|
|
+ while($offset < $dataLength) {
|
|
|
+ $length = ord($data[$offset]);
|
|
|
+
|
|
|
+ $offset++;
|
|
|
+
|
|
|
+ if ($length == 128) {
|
|
|
+ // EOD byte
|
|
|
+ break;
|
|
|
+ } else if ($length < 128) {
|
|
|
+ $length++;
|
|
|
+
|
|
|
+ $output .= substr($data, $offset, $length);
|
|
|
+
|
|
|
+ $offset += $length;
|
|
|
+ } else if ($length > 128) {
|
|
|
+ $output .= str_repeat($data[$offset], 257 - $length);
|
|
|
+
|
|
|
+ $offset++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $output;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|