PageRenderTime 26ms CodeModel.GetById 37ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Pdf/Element/Object/Stream.php

https://bitbucket.org/brunoMaurice/youfood
PHP | 410 lines | 222 code | 59 blank | 129 comment | 42 complexity | 69af550b8d0b6ea4033c8558caeb70b3 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Pdf
  17. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: Stream.php 16541 2009-07-07 06:59:03Z bkarwin $
  20. */
  21. /** Zend_Pdf_Element_Object */
  22. require_once 'Zend/Pdf/Element/Object.php';
  23. /** Zend_Pdf_Element_Stream */
  24. require_once 'Zend/Pdf/Element/Stream.php';
  25. /** Zend_Pdf_Filter_Ascii85 */
  26. require_once 'Zend/Pdf/Filter/Ascii85.php';
  27. /** Zend_Pdf_Filter_AsciiHex */
  28. require_once 'Zend/Pdf/Filter/AsciiHex.php';
  29. /** Zend_Pdf_Filter_Compression_Flate */
  30. require_once 'Zend/Pdf/Filter/Compression/Flate.php';
  31. /** Zend_Pdf_Filter_Compression_Lzw */
  32. require_once 'Zend/Pdf/Filter/Compression/Lzw.php';
  33. /** Zend_Pdf_ElementFactory */
  34. require_once 'Zend/Pdf/ElementFactory.php';
  35. /**
  36. * PDF file 'stream object' element implementation
  37. *
  38. * @category Zend
  39. * @package Zend_Pdf
  40. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  41. * @license http://framework.zend.com/license/new-bsd New BSD License
  42. */
  43. class Zend_Pdf_Element_Object_Stream extends Zend_Pdf_Element_Object
  44. {
  45. /**
  46. * StreamObject dictionary
  47. * Required enries:
  48. * Length
  49. *
  50. * @var Zend_Pdf_Element_Dictionary
  51. */
  52. private $_dictionary;
  53. /**
  54. * Flag which signals, that stream is decoded
  55. *
  56. * @var boolean
  57. */
  58. private $_streamDecoded;
  59. /**
  60. * Stored original stream object dictionary.
  61. * Used to decode stream during an access time.
  62. *
  63. * The only properties, which affect decoding, are sored here.
  64. *
  65. * @var array|null
  66. */
  67. private $_originalDictionary = null;
  68. /**
  69. * Object constructor
  70. *
  71. * @param mixed $val
  72. * @param integer $objNum
  73. * @param integer $genNum
  74. * @param Zend_Pdf_ElementFactory $factory
  75. * @param Zend_Pdf_Element_Dictionary|null $dictionary
  76. * @throws Zend_Pdf_Exception
  77. */
  78. public function __construct($val, $objNum, $genNum, Zend_Pdf_ElementFactory $factory, $dictionary = null)
  79. {
  80. parent::__construct(new Zend_Pdf_Element_Stream($val), $objNum, $genNum, $factory);
  81. if ($dictionary === null) {
  82. $this->_dictionary = new Zend_Pdf_Element_Dictionary();
  83. $this->_dictionary->Length = new Zend_Pdf_Element_Numeric(strlen( $val ));
  84. $this->_streamDecoded = true;
  85. } else {
  86. $this->_dictionary = $dictionary;
  87. $this->_streamDecoded = false;
  88. }
  89. }
  90. /**
  91. * Store original dictionary information in $_originalDictionary class member.
  92. * Used to store information and to normalize filters information before defiltering.
  93. *
  94. */
  95. private function _storeOriginalDictionary()
  96. {
  97. $this->_originalDictionary = array();
  98. $this->_originalDictionary['Filter'] = array();
  99. $this->_originalDictionary['DecodeParms'] = array();
  100. if ($this->_dictionary->Filter === null) {
  101. // Do nothing.
  102. } else if ($this->_dictionary->Filter->getType() == Zend_Pdf_Element::TYPE_ARRAY) {
  103. foreach ($this->_dictionary->Filter->items as $id => $filter) {
  104. $this->_originalDictionary['Filter'][$id] = $filter->value;
  105. $this->_originalDictionary['DecodeParms'][$id] = array();
  106. if ($this->_dictionary->DecodeParms !== null ) {
  107. if ($this->_dictionary->DecodeParms->items[$id] !== null &&
  108. $this->_dictionary->DecodeParms->items[$id]->value !== null ) {
  109. foreach ($this->_dictionary->DecodeParms->items[$id]->getKeys() as $paramKey) {
  110. $this->_originalDictionary['DecodeParms'][$id][$paramKey] =
  111. $this->_dictionary->DecodeParms->items[$id]->$paramKey->value;
  112. }
  113. }
  114. }
  115. }
  116. } else if ($this->_dictionary->Filter->getType() != Zend_Pdf_Element::TYPE_NULL) {
  117. $this->_originalDictionary['Filter'][0] = $this->_dictionary->Filter->value;
  118. $this->_originalDictionary['DecodeParms'][0] = array();
  119. if ($this->_dictionary->DecodeParms !== null ) {
  120. foreach ($this->_dictionary->DecodeParms->getKeys() as $paramKey) {
  121. $this->_originalDictionary['DecodeParms'][0][$paramKey] =
  122. $this->_dictionary->DecodeParms->$paramKey->value;
  123. }
  124. }
  125. }
  126. if ($this->_dictionary->F !== null) {
  127. $this->_originalDictionary['F'] = $this->_dictionary->F->value;
  128. }
  129. $this->_originalDictionary['FFilter'] = array();
  130. $this->_originalDictionary['FDecodeParms'] = array();
  131. if ($this->_dictionary->FFilter === null) {
  132. // Do nothing.
  133. } else if ($this->_dictionary->FFilter->getType() == Zend_Pdf_Element::TYPE_ARRAY) {
  134. foreach ($this->_dictionary->FFilter->items as $id => $filter) {
  135. $this->_originalDictionary['FFilter'][$id] = $filter->value;
  136. $this->_originalDictionary['FDecodeParms'][$id] = array();
  137. if ($this->_dictionary->FDecodeParms !== null ) {
  138. if ($this->_dictionary->FDecodeParms->items[$id] !== null &&
  139. $this->_dictionary->FDecodeParms->items[$id]->value !== null) {
  140. foreach ($this->_dictionary->FDecodeParms->items[$id]->getKeys() as $paramKey) {
  141. $this->_originalDictionary['FDecodeParms'][$id][$paramKey] =
  142. $this->_dictionary->FDecodeParms->items[$id]->items[$paramKey]->value;
  143. }
  144. }
  145. }
  146. }
  147. } else {
  148. $this->_originalDictionary['FFilter'][0] = $this->_dictionary->FFilter->value;
  149. $this->_originalDictionary['FDecodeParms'][0] = array();
  150. if ($this->_dictionary->FDecodeParms !== null ) {
  151. foreach ($this->_dictionary->FDecodeParms->getKeys() as $paramKey) {
  152. $this->_originalDictionary['FDecodeParms'][0][$paramKey] =
  153. $this->_dictionary->FDecodeParms->items[$paramKey]->value;
  154. }
  155. }
  156. }
  157. }
  158. /**
  159. * Decode stream
  160. *
  161. * @throws Zend_Pdf_Exception
  162. */
  163. private function _decodeStream()
  164. {
  165. if ($this->_originalDictionary === null) {
  166. $this->_storeOriginalDictionary();
  167. }
  168. /**
  169. * All applied stream filters must be processed to decode stream.
  170. * If we don't recognize any of applied filetrs an exception should be thrown here
  171. */
  172. if (isset($this->_originalDictionary['F'])) {
  173. /** @todo Check, how external files can be processed. */
  174. throw new Zend_Pdf_Exception('External filters are not supported now.');
  175. }
  176. foreach ($this->_originalDictionary['Filter'] as $id => $filterName ) {
  177. $valueRef = &$this->_value->value->getRef();
  178. $this->_value->value->touch();
  179. switch ($filterName) {
  180. case 'ASCIIHexDecode':
  181. $valueRef = Zend_Pdf_Filter_AsciiHex::decode($valueRef);
  182. break;
  183. case 'ASCII85Decode':
  184. $valueRef = Zend_Pdf_Filter_Ascii85::decode($valueRef);
  185. break;
  186. case 'FlateDecode':
  187. $valueRef = Zend_Pdf_Filter_Compression_Flate::decode($valueRef,
  188. $this->_originalDictionary['DecodeParms'][$id]);
  189. break;
  190. case 'LZWDecode':
  191. $valueRef = Zend_Pdf_Filter_Compression_Lzw::decode($valueRef,
  192. $this->_originalDictionary['DecodeParms'][$id]);
  193. break;
  194. default:
  195. throw new Zend_Pdf_Exception('Unknown stream filter: \'' . $filterName . '\'.');
  196. }
  197. }
  198. $this->_streamDecoded = true;
  199. }
  200. /**
  201. * Encode stream
  202. *
  203. * @throws Zend_Pdf_Exception
  204. */
  205. private function _encodeStream()
  206. {
  207. /**
  208. * All applied stream filters must be processed to encode stream.
  209. * If we don't recognize any of applied filetrs an exception should be thrown here
  210. */
  211. if (isset($this->_originalDictionary['F'])) {
  212. /** @todo Check, how external files can be processed. */
  213. throw new Zend_Pdf_Exception('External filters are not supported now.');
  214. }
  215. $filters = array_reverse($this->_originalDictionary['Filter'], true);
  216. foreach ($filters as $id => $filterName ) {
  217. $valueRef = &$this->_value->value->getRef();
  218. $this->_value->value->touch();
  219. switch ($filterName) {
  220. case 'ASCIIHexDecode':
  221. $valueRef = Zend_Pdf_Filter_AsciiHex::encode($valueRef);
  222. break;
  223. case 'ASCII85Decode':
  224. $valueRef = Zend_Pdf_Filter_Ascii85::encode($valueRef);
  225. break;
  226. case 'FlateDecode':
  227. $valueRef = Zend_Pdf_Filter_Compression_Flate::encode($valueRef,
  228. $this->_originalDictionary['DecodeParms'][$id]);
  229. break;
  230. case 'LZWDecode':
  231. $valueRef = Zend_Pdf_Filter_Compression_Lzw::encode($valueRef,
  232. $this->_originalDictionary['DecodeParms'][$id]);
  233. break;
  234. default:
  235. throw new Zend_Pdf_Exception('Unknown stream filter: \'' . $filterName . '\'.');
  236. }
  237. }
  238. $this->_streamDecoded = false;
  239. }
  240. /**
  241. * Get handler
  242. *
  243. * @param string $property
  244. * @return mixed
  245. * @throws Zend_Pdf_Exception
  246. */
  247. public function __get($property)
  248. {
  249. if ($property == 'dictionary') {
  250. /**
  251. * If stream is note decoded yet, then store original decoding options (do it only once).
  252. */
  253. if (( !$this->_streamDecoded ) && ($this->_originalDictionary === null)) {
  254. $this->_storeOriginalDictionary();
  255. }
  256. return $this->_dictionary;
  257. }
  258. if ($property == 'value') {
  259. if (!$this->_streamDecoded) {
  260. $this->_decodeStream();
  261. }
  262. return $this->_value->value->getRef();
  263. }
  264. throw new Zend_Pdf_Exception('Unknown stream object property requested.');
  265. }
  266. /**
  267. * Set handler
  268. *
  269. * @param string $property
  270. * @param mixed $value
  271. */
  272. public function __set($property, $value)
  273. {
  274. if ($property == 'value') {
  275. $valueRef = &$this->_value->value->getRef();
  276. $valueRef = $value;
  277. $this->_value->value->touch();
  278. $this->_streamDecoded = true;
  279. return;
  280. }
  281. throw new Zend_Pdf_Exception('Unknown stream object property: \'' . $property . '\'.');
  282. }
  283. /**
  284. * Treat stream data as already encoded
  285. */
  286. public function skipFilters()
  287. {
  288. $this->_streamDecoded = false;
  289. }
  290. /**
  291. * Call handler
  292. *
  293. * @param string $method
  294. * @param array $args
  295. * @return mixed
  296. */
  297. public function __call($method, $args)
  298. {
  299. if (!$this->_streamDecoded) {
  300. $this->_decodeStream();
  301. }
  302. switch (count($args)) {
  303. case 0:
  304. return $this->_value->$method();
  305. case 1:
  306. return $this->_value->$method($args[0]);
  307. default:
  308. throw new Zend_Pdf_Exception('Unsupported number of arguments');
  309. }
  310. }
  311. /**
  312. * Dump object to a string to save within PDF file
  313. *
  314. * $factory parameter defines operation context.
  315. *
  316. * @param Zend_Pdf_ElementFactory $factory
  317. * @return string
  318. */
  319. public function dump(Zend_Pdf_ElementFactory $factory)
  320. {
  321. $shift = $factory->getEnumerationShift($this->_factory);
  322. if ($this->_streamDecoded) {
  323. $this->_storeOriginalDictionary();
  324. $this->_encodeStream();
  325. } else if ($this->_originalDictionary != null) {
  326. $startDictionary = $this->_originalDictionary;
  327. $this->_storeOriginalDictionary();
  328. $newDictionary = $this->_originalDictionary;
  329. if ($startDictionary !== $newDictionary) {
  330. $this->_originalDictionary = $startDictionary;
  331. $this->_decodeStream();
  332. $this->_originalDictionary = $newDictionary;
  333. $this->_encodeStream();
  334. }
  335. }
  336. // Update stream length
  337. $this->dictionary->Length->value = $this->_value->length();
  338. return $this->_objNum + $shift . " " . $this->_genNum . " obj \n"
  339. . $this->dictionary->toString($factory) . "\n"
  340. . $this->_value->toString($factory) . "\n"
  341. . "endobj\n";
  342. }
  343. /**
  344. * Clean up resources, used by object
  345. */
  346. public function cleanUp()
  347. {
  348. $this->_dictionary = null;
  349. $this->_value = null;
  350. }
  351. }