diff -r 5b37998e522e -r 162c1de6545a web/lib/Zend/Pdf/Element/Object/Stream.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/Zend/Pdf/Element/Object/Stream.php Fri Mar 11 15:05:35 2011 +0100 @@ -0,0 +1,453 @@ +_dictionary = new Zend_Pdf_Element_Dictionary(); + $this->_dictionary->Length = new Zend_Pdf_Element_Numeric(strlen( $val )); + $this->_streamDecoded = true; + } else { + $this->_dictionary = $dictionary; + $this->_streamDecoded = false; + } + } + + + /** + * Extract dictionary data which are used to store information and to normalize filters + * information before defiltering. + * + * @return array + */ + private function _extractDictionaryData() + { + $dictionaryArray = array(); + + $dictionaryArray['Filter'] = array(); + $dictionaryArray['DecodeParms'] = array(); + if ($this->_dictionary->Filter === null) { + // Do nothing. + } else if ($this->_dictionary->Filter->getType() == Zend_Pdf_Element::TYPE_ARRAY) { + foreach ($this->_dictionary->Filter->items as $id => $filter) { + $dictionaryArray['Filter'][$id] = $filter->value; + $dictionaryArray['DecodeParms'][$id] = array(); + + if ($this->_dictionary->DecodeParms !== null ) { + if ($this->_dictionary->DecodeParms->items[$id] !== null && + $this->_dictionary->DecodeParms->items[$id]->value !== null ) { + foreach ($this->_dictionary->DecodeParms->items[$id]->getKeys() as $paramKey) { + $dictionaryArray['DecodeParms'][$id][$paramKey] = + $this->_dictionary->DecodeParms->items[$id]->$paramKey->value; + } + } + } + } + } else if ($this->_dictionary->Filter->getType() != Zend_Pdf_Element::TYPE_NULL) { + $dictionaryArray['Filter'][0] = $this->_dictionary->Filter->value; + $dictionaryArray['DecodeParms'][0] = array(); + if ($this->_dictionary->DecodeParms !== null ) { + foreach ($this->_dictionary->DecodeParms->getKeys() as $paramKey) { + $dictionaryArray['DecodeParms'][0][$paramKey] = + $this->_dictionary->DecodeParms->$paramKey->value; + } + } + } + + if ($this->_dictionary->F !== null) { + $dictionaryArray['F'] = $this->_dictionary->F->value; + } + + $dictionaryArray['FFilter'] = array(); + $dictionaryArray['FDecodeParms'] = array(); + if ($this->_dictionary->FFilter === null) { + // Do nothing. + } else if ($this->_dictionary->FFilter->getType() == Zend_Pdf_Element::TYPE_ARRAY) { + foreach ($this->_dictionary->FFilter->items as $id => $filter) { + $dictionaryArray['FFilter'][$id] = $filter->value; + $dictionaryArray['FDecodeParms'][$id] = array(); + + if ($this->_dictionary->FDecodeParms !== null ) { + if ($this->_dictionary->FDecodeParms->items[$id] !== null && + $this->_dictionary->FDecodeParms->items[$id]->value !== null) { + foreach ($this->_dictionary->FDecodeParms->items[$id]->getKeys() as $paramKey) { + $dictionaryArray['FDecodeParms'][$id][$paramKey] = + $this->_dictionary->FDecodeParms->items[$id]->items[$paramKey]->value; + } + } + } + } + } else { + $dictionaryArray['FFilter'][0] = $this->_dictionary->FFilter->value; + $dictionaryArray['FDecodeParms'][0] = array(); + if ($this->_dictionary->FDecodeParms !== null ) { + foreach ($this->_dictionary->FDecodeParms->getKeys() as $paramKey) { + $dictionaryArray['FDecodeParms'][0][$paramKey] = + $this->_dictionary->FDecodeParms->items[$paramKey]->value; + } + } + } + + return $dictionaryArray; + } + + /** + * Decode stream + * + * @throws Zend_Pdf_Exception + */ + private function _decodeStream() + { + if ($this->_initialDictionaryData === null) { + $this->_initialDictionaryData = $this->_extractDictionaryData(); + } + + /** + * All applied stream filters must be processed to decode stream. + * If we don't recognize any of applied filetrs an exception should be thrown here + */ + if (isset($this->_initialDictionaryData['F'])) { + /** @todo Check, how external files can be processed. */ + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('External filters are not supported now.'); + } + + foreach ($this->_initialDictionaryData['Filter'] as $id => $filterName ) { + $valueRef = &$this->_value->value->getRef(); + $this->_value->value->touch(); + switch ($filterName) { + case 'ASCIIHexDecode': + require_once 'Zend/Pdf/Filter/AsciiHex.php'; + $valueRef = Zend_Pdf_Filter_AsciiHex::decode($valueRef); + break; + + case 'ASCII85Decode': + require_once 'Zend/Pdf/Filter/Ascii85.php'; + $valueRef = Zend_Pdf_Filter_Ascii85::decode($valueRef); + break; + + case 'FlateDecode': + require_once 'Zend/Pdf/Filter/Compression/Flate.php'; + $valueRef = Zend_Pdf_Filter_Compression_Flate::decode($valueRef, + $this->_initialDictionaryData['DecodeParms'][$id]); + break; + + case 'LZWDecode': + require_once 'Zend/Pdf/Filter/Compression/Lzw.php'; + $valueRef = Zend_Pdf_Filter_Compression_Lzw::decode($valueRef, + $this->_initialDictionaryData['DecodeParms'][$id]); + break; + + case 'RunLengthDecode': + require_once 'Zend/Pdf/Filter/RunLength.php'; + $valueRef = Zend_Pdf_Filter_RunLength::decode($valueRef); + break; + + default: + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Unknown stream filter: \'' . $filterName . '\'.'); + } + } + + $this->_streamDecoded = true; + } + + /** + * Encode stream + * + * @throws Zend_Pdf_Exception + */ + private function _encodeStream() + { + /** + * All applied stream filters must be processed to encode stream. + * If we don't recognize any of applied filetrs an exception should be thrown here + */ + if (isset($this->_initialDictionaryData['F'])) { + /** @todo Check, how external files can be processed. */ + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('External filters are not supported now.'); + } + + $filters = array_reverse($this->_initialDictionaryData['Filter'], true); + + foreach ($filters as $id => $filterName ) { + $valueRef = &$this->_value->value->getRef(); + $this->_value->value->touch(); + switch ($filterName) { + case 'ASCIIHexDecode': + require_once 'Zend/Pdf/Filter/AsciiHex.php'; + $valueRef = Zend_Pdf_Filter_AsciiHex::encode($valueRef); + break; + + case 'ASCII85Decode': + require_once 'Zend/Pdf/Filter/Ascii85.php'; + $valueRef = Zend_Pdf_Filter_Ascii85::encode($valueRef); + break; + + case 'FlateDecode': + require_once 'Zend/Pdf/Filter/Compression/Flate.php'; + $valueRef = Zend_Pdf_Filter_Compression_Flate::encode($valueRef, + $this->_initialDictionaryData['DecodeParms'][$id]); + break; + + case 'LZWDecode': + require_once 'Zend/Pdf/Filter/Compression/Lzw.php'; + $valueRef = Zend_Pdf_Filter_Compression_Lzw::encode($valueRef, + $this->_initialDictionaryData['DecodeParms'][$id]); + break; + + case 'RunLengthDecode': + require_once 'Zend/Pdf/Filter/RunLength.php'; + $valueRef = Zend_Pdf_Filter_RunLength::encode($valueRef); + break; + + default: + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Unknown stream filter: \'' . $filterName . '\'.'); + } + } + + $this->_streamDecoded = false; + } + + /** + * Get handler + * + * @param string $property + * @return mixed + * @throws Zend_Pdf_Exception + */ + public function __get($property) + { + if ($property == 'dictionary') { + /** + * If stream is not decoded yet, then store original decoding options (do it only once). + */ + if (( !$this->_streamDecoded ) && ($this->_initialDictionaryData === null)) { + $this->_initialDictionaryData = $this->_extractDictionaryData(); + } + + return $this->_dictionary; + } + + if ($property == 'value') { + if (!$this->_streamDecoded) { + $this->_decodeStream(); + } + + return $this->_value->value->getRef(); + } + + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Unknown stream object property requested.'); + } + + + /** + * Set handler + * + * @param string $property + * @param mixed $value + */ + public function __set($property, $value) + { + if ($property == 'value') { + $valueRef = &$this->_value->value->getRef(); + $valueRef = $value; + $this->_value->value->touch(); + + $this->_streamDecoded = true; + + return; + } + + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Unknown stream object property: \'' . $property . '\'.'); + } + + + /** + * Treat stream data as already encoded + */ + public function skipFilters() + { + $this->_streamDecoded = false; + } + + + /** + * Call handler + * + * @param string $method + * @param array $args + * @return mixed + */ + public function __call($method, $args) + { + if (!$this->_streamDecoded) { + $this->_decodeStream(); + } + + switch (count($args)) { + case 0: + return $this->_value->$method(); + case 1: + return $this->_value->$method($args[0]); + default: + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Unsupported number of arguments'); + } + } + + /** + * Detach PDF object from the factory (if applicable), clone it and attach to new factory. + * + * @param Zend_Pdf_ElementFactory $factory The factory to attach + * @param array &$processed List of already processed indirect objects, used to avoid objects duplication + * @param integer $mode Cloning mode (defines filter for objects cloning) + * @returns Zend_Pdf_Element + */ + public function makeClone(Zend_Pdf_ElementFactory $factory, array &$processed, $mode) + { + $id = spl_object_hash($this); + if (isset($processed[$id])) { + // Do nothing if object is already processed + // return it + return $processed[$id]; + } + + $streamValue = $this->_value; + $streamDictionary = $this->_dictionary->makeClone($factory, $processed, $mode); + + // Make new empty instance of stream object and register it in $processed container + $processed[$id] = $clonedObject = $factory->newStreamObject(''); + + // Copy current object data and state + $clonedObject->_dictionary = $this->_dictionary->makeClone($factory, $processed, $mode); + $clonedObject->_value = $this->_value->makeClone($factory, $processed, $mode); + $clonedObject->_initialDictionaryData = $this->_initialDictionaryData; + $clonedObject->_streamDecoded = $this->_streamDecoded; + + return $clonedObject; + } + + /** + * Dump object to a string to save within PDF file + * + * $factory parameter defines operation context. + * + * @param Zend_Pdf_ElementFactory $factory + * @return string + */ + public function dump(Zend_Pdf_ElementFactory $factory) + { + $shift = $factory->getEnumerationShift($this->_factory); + + if ($this->_streamDecoded) { + $this->_initialDictionaryData = $this->_extractDictionaryData(); + $this->_encodeStream(); + } else if ($this->_initialDictionaryData != null) { + $newDictionary = $this->_extractDictionaryData(); + + if ($this->_initialDictionaryData !== $newDictionary) { + $this->_decodeStream(); + $this->_initialDictionaryData = $newDictionary; + $this->_encodeStream(); + } + } + + // Update stream length + $this->dictionary->Length->value = $this->_value->length(); + + return $this->_objNum + $shift . " " . $this->_genNum . " obj \n" + . $this->dictionary->toString($factory) . "\n" + . $this->_value->toString($factory) . "\n" + . "endobj\n"; + } + + /** + * Clean up resources, used by object + */ + public function cleanUp() + { + $this->_dictionary = null; + $this->_value = null; + } +}