dumper.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. /**
  3. * tools/dumper.php file
  4. *
  5. * @package Nanodicom
  6. * @category Tools
  7. * @author Nano Documet <nanodocumet@gmail.com>
  8. * @version 1.3.1
  9. * @copyright (c) 2010-2011
  10. * @license http://www.opensource.org/licenses/mit-license.php MIT-license
  11. */
  12. /**
  13. * Dicom_Dumper class.
  14. *
  15. * Extends Nanodicom. Dumps the dataset. Currently supports normal echo output and formatted
  16. * html output. Fully extensible, ie. an xml output can be created as well.
  17. * @package Nanodicom
  18. * @category Tools
  19. * @author Nano Documet <nanodocumet@gmail.com>
  20. * @version 1.3.1
  21. * @copyright (c) 2010-2011
  22. * @license http://www.opensource.org/licenses/mit-license.php MIT-license
  23. */
  24. class Dicom_Dumper extends Nanodicom {
  25. // Default html output
  26. protected $_output_html = array(
  27. 'dataset_begin' => '<ul>',
  28. 'dataset_end' => '</ul>',
  29. 'item_begin' => '<li>',
  30. 'item_end' => '</li>',
  31. 'spacer' => '',
  32. 'text_begin' => '<pre>',
  33. 'text_end' => '</pre>',
  34. 'columns' => array(
  35. 'off' => array('%05X', ' '),
  36. 'g' => array('0x%04X', ':'),
  37. 'e' => array('0x%04X', ' '),
  38. 'name' => array('%-30.30s', ' '),
  39. 'vr' => array('%2s', ' '),
  40. 'len' => array('%-3d', ' '),
  41. 'val' => array('[%s]', ''),
  42. ),
  43. );
  44. // Default echo output
  45. protected $_output_echo = array(
  46. 'dataset_begin' => '',
  47. 'dataset_end' => '',
  48. 'item_begin' => '',
  49. 'item_end' => "\n",
  50. 'spacer' => ' ',
  51. 'text_begin' => '',
  52. 'text_end' => '',
  53. 'columns' => array(
  54. 'off' => array('%05X', ' '),
  55. 'g' => array('%04X', ':'),
  56. 'e' => array('%04X', ' '),
  57. 'name' => array('%-30.30s', ' '),
  58. 'vr' => array('%2s', ' '),
  59. 'len' => array('%-3d', ' '),
  60. 'val' => array('[%s]', ''),
  61. ),
  62. );
  63. // For formatting
  64. protected $output = array();
  65. // The output
  66. protected $_out = '';
  67. /**
  68. * Public method for dump
  69. *
  70. * @param mixed for formatting
  71. * @return string the dumped full dataset
  72. */
  73. public function dump($output = 'echo')
  74. {
  75. $this->parse();
  76. // TODO:
  77. // - Check if $output exists.
  78. // - Max number of nested datasets
  79. // - Show binary in hexdump format
  80. $this->profiler['dump']['start'] = microtime(TRUE);
  81. if (is_array($output))
  82. {
  83. // Merge arrays from default and given
  84. $this->output = array_merge($this->_output_echo, $output);
  85. }
  86. else
  87. {
  88. $output = '_output_'.$output;
  89. foreach ($this->$output as $var => $value)
  90. {
  91. // Load the output
  92. $this->output[$var] = $value;
  93. }
  94. }
  95. $dump = $this->_dump($this->_dataset);
  96. $this->profiler['dump']['end'] = microtime(TRUE);
  97. return $dump;
  98. }
  99. /**
  100. * Internal method for dumping
  101. *
  102. * @param object the dataset
  103. * @param string the spacer
  104. * @return string the dumped dataset
  105. */
  106. protected function _dump($dataset, $spacer = '')
  107. {
  108. $out = '';
  109. foreach ($dataset as $group => $elements)
  110. {
  111. // Load dictionaries (Forced loading)
  112. Nanodicom_Dictionary::load_dictionary($group, TRUE);
  113. foreach ($elements as $element => $indexes)
  114. {
  115. foreach ($indexes as $values)
  116. {
  117. $elem = $values;
  118. $elem['g'] = $group;
  119. $elem['e'] = $element;
  120. if ( ! isset($elem['done']))
  121. {
  122. // Read value if not read yet
  123. $this->_read_value_from_blob($elem, $group, $element);
  124. }
  125. // Indent back when a delimiter was found. Must be done before dumping.
  126. if ($group == Nanodicom::ITEMS_GROUP AND in_array($element, array(Nanodicom::ITEM_DELIMITER, Nanodicom::SEQUENCE_DELIMITER)))
  127. {
  128. $spacer = substr($spacer, 0, -1*strlen($this->output['spacer']));
  129. }
  130. // Start the dataset and dump the current element
  131. $out .= $this->output['dataset_begin'].$this->_dump_element($elem, $spacer);
  132. if (count($elem['ds']) > 0)
  133. {
  134. // Take care of items
  135. $out .= $this->_dump($elem['ds'], $spacer.$this->output['spacer']);
  136. }
  137. // Close the dataset
  138. $out .= $this->output['dataset_end'];
  139. }
  140. unset($values);
  141. }
  142. unset($element, $indexes);
  143. }
  144. unset($group, $elements);
  145. return $out;
  146. }
  147. /**
  148. * Dumps an element
  149. *
  150. * @param object the element
  151. * @param string the spacer
  152. * @return string the full dumped element
  153. */
  154. protected function _dump_element($element, $space = '')
  155. {
  156. $row = $this->_print_element($element);
  157. return $this->output['item_begin'].$this->output['text_begin'].$space.$row.$this->output['text_end'].$this->output['item_end'];
  158. }
  159. /**
  160. * Prints an element
  161. *
  162. * @param object the element
  163. * @return string the basic dumped element
  164. */
  165. protected function _print_element($element)
  166. {
  167. $out = '';
  168. foreach ($this->output['columns'] as $column => $values)
  169. {
  170. switch ($column)
  171. {
  172. case 'name' : $string = isset(Nanodicom_Dictionary::$dict[$element['g']][$element['e']])
  173. ? Nanodicom_Dictionary::$dict[$element['g']][$element['e']][2]
  174. : 'NA';
  175. break;
  176. case 'val' :
  177. if ($element['vr'] == 'AT')
  178. {
  179. // AT (Attribute Tags) look "nicer" being displayed in Hex to match Group, Elements format
  180. $elements = array();
  181. for($i = 0; $i < count($element['val']); $i++)
  182. {
  183. $elements[] = '['.sprintf("0x%04X", $element['val'][$i][0]).','.sprintf("0x%04X", $element['val'][$i][1]).']';
  184. }
  185. $element['val'] = $elements;
  186. }
  187. $string = ($element['bin'])
  188. ? 'BINARY. Element starts at '.$element['off']
  189. : ((is_array($element['val']))
  190. ? implode(',', $element['val'])
  191. : (isset(Nanodicom_Dictionary::$dict[$element['g']][$element['e']])
  192. ? trim($element['val'])
  193. : 'UNKNOWN'));
  194. break;
  195. case 'vr' :
  196. $vr_index = ($element['vr'] != $element['_vr'] AND ! empty($element['_vr'])) ? '_vr' : 'vr';
  197. $string = trim($element[$vr_index]);
  198. break;
  199. default : $string = trim($element[$column]);
  200. break;
  201. }
  202. $out .= sprintf($values[0], $string).$values[1];
  203. }
  204. return $out;
  205. }
  206. } // End Dicom_Dumper