vil_dicom_header.cxx
Go to the documentation of this file.
1 // DicomHeaderFormat.cxx
2 // =====================
3 //
4 // The implementation of the vil_dicom_header_format class to read
5 // and write the header part of a dicom file.
6 //
7 // Author: Chris Wolstenholme
8 // E-mail: cwolstenholme@imorphics.com
9 // Copyright (c) 2001 iMorphics Ltd
10 
11 #include <iostream>
12 #include <cstdlib>
13 #include <vil/vil_config.h>
14 #if HAS_DCMTK
15 
16 #include "vil_dicom_header.h"
17 #include <vil/vil_stream.h>
18 #ifdef _MSC_VER
19 # include <vcl_msvc_warnings.h>
20 #endif
21 
22 //================================================================
23 
24 void
26 {
27  // Clear all the elements of the info structure
28 
29  // Identity info
30  info.header_valid_ = false;
35  info.image_id_type_ = "";
36  info.sop_cl_uid_ = "";
37  info.sop_in_uid_ = "";
46  info.accession_number_ = "";
47  info.modality_ = "";
48  info.manufacturer_ = "";
49  info.institution_name_ = "";
50  info.institution_addr_ = "";
51  info.ref_phys_name_ = "";
52  info.station_name_ = "";
53  info.study_desc_ = "";
54  info.att_phys_name_ = "";
55  info.operator_name_ = "";
56  info.model_name_ = "";
57 
58  // Patient info
59  info.patient_name_ = "";
60  info.patient_id_ = "";
62  info.patient_sex_ = "";
63  info.patient_age_ = "";
65  info.patient_hist_ = "";
66 
67  // Acquisition info
68  info.scanning_seq_ = "";
69  info.sequence_var_ = "";
70  info.scan_options_ = "";
71  info.mr_acq_type_ = "";
72  info.sequence_name_ = "";
73  info.angio_flag_ = "";
83  info.software_vers_ = "";
84  info.protocol_name_ = "";
90  info.receiving_coil_ = "";
91  info.phase_enc_dir_ = "";
94  info.patient_pos_ = "";
95 
96  // Relationship info
97  info.stud_ins_uid_= "";
98  info.ser_ins_uid_ = "";
99  info.study_id_ = "";
103  info.pat_orient_ = "";
104  info.image_pos_.clear();
105  info.image_orient_.clear();
106  info.frame_of_ref_ = "";
108  info.pos_ref_ind_ = "";
110 
111  // Image info
113  info.photo_interp_ = "";
123 
124  // Info for loading image
135 
136  // Info for image procedure
141 
142  // Info for non-standard Philips data
145 }
146 
147 
148 //================================================================
149 // Default constructor
150 //================================================================
152 info_valid_(false),
153 file_endian_(VIL_DICOM_HEADER_DEUNKNOWN),
154 image_type_(VIL_DICOM_HEADER_DITUNKNOWN)
155 {
156  // Work out the endianism of this architecture
157  endian_ = calculateEndian();
158 }
159 
160 //================================================================
161 
163 {
164  // Do Nothing
165 }
166 
167 //================================================================
168 
170 {
171  vil_dicom_header_type dtype;
172 
173  dtype = determineFileType(fs);
174 
175  return dtype!=VIL_DICOM_HEADER_DTUNKNOWN;
176 }
177 
178 //================================================================
179 
181 {
182  vil_dicom_header_type dtype;
183 
184  // Clear the current header
185  clearInfo();
186 
187  dtype = determineFileType(fs);
188  // Check if the file is dicom first
189  if (dtype != VIL_DICOM_HEADER_DTUNKNOWN)
190  {
191  last_read_.file_type_ = dtype;
193 
194  if (dtype == VIL_DICOM_HEADER_DTPART10)
195  {
197  }
198 
201 
202  readHeaderElements(fs);
203 
204  info_valid_ = true;
205  } // End of if (dtype != VIL_DICOM_HEADER_DTUNKNOWN)
206  else // It's not a dicom file, so can't read
207  {
208  std::cerr<<"Unknown file type - not a DICOM file...\n"
209  <<"File header not read\n";
210  }
211  return last_read_;
212 }
213 
214 //================================================================
215 
217 {
218  return last_read_;
219 }
220 
221 //================================================================
222 
224 {
225 return info_valid_;
226 }
227 
228 //================================================================
229 
231 {
232  return endian_;
233 }
234 
235 //================================================================
236 
238 {
239  return file_endian_;
240 }
241 
242 //================================================================
243 
245 {
246  return image_type_;
247 }
248 
249 //================================================================
250 
252 {
254 
255  // Check the file is open, otherwise fail - the std::fstream should
256  // be controlled outside of this class
257  if (fs.ok())
258  {
259  // There are four possibilities:
260  // The file is Part10 with 128 byte pre-amble
261  // The file is Part10 with no pre-amble
262  // The file is a non-Part10 dicom file
263  // The file is not a dicom file (or can't be determined as such)
264  char dicm_read[5];
265  std::string dicm_test;
266 
267  // Skip 128 byte pre-amble and test for DICM again
268  fs.seek(128);
269  fs.read(dicm_read,4);
270  dicm_read[4]=0;
271  dicm_test=dicm_read;
272 
273  if (dicm_test == "DICM")
274  {
275  result = VIL_DICOM_HEADER_DTPART10;
276  }
277  else
278  {
279  // Read the first four chars and see if they are the letters
280  // DICM
281  fs.seek(0);
282  fs.read(dicm_read,4);
283  dicm_read[4]=0; // Null terminate
284  dicm_test=dicm_read;
285 
286  if (dicm_test == "DICM")
287  {
288  result = VIL_DICOM_HEADER_DTPART10;
289  }
290  else
291  {
292  // Some other format - test it with both little and
293  // big endian
294  int num_tries = 0;
295  bool known = false;
298 
299  while (num_tries < 2 && !known)
300  {
301  // Go back to the beginning and search for the
302  // first element of the Identifying group
303  fs.seek(0);
304  vxl_uint_16 group, element;
305  vxl_uint_32 data_block_size, num_elements;
306 
307  fs.read(&group, sizeof(vxl_uint_16));
308  group = shortSwap(group);
309  fs.read(&element, sizeof(vxl_uint_16));
310  element = shortSwap(element);
311  fs.read(&data_block_size, sizeof(vxl_uint_32));
312  data_block_size = intSwap(data_block_size);
313  if (data_block_size > 0x1000000) {
314  std::cerr<< __FILE__ << ": " << __LINE__ << " : WARNING:\n"
315  <<"data_block_size=" << data_block_size << " is most probably too large\n";
316  break;
317  }
318 
319  num_elements = 0;
320 
321  while (group < VIL_DICOM_HEADER_IDENTIFYINGGROUP &&
322  num_elements < VIL_DICOM_HEADER_MAXHEADERSIZE &&
323  fs.ok())
324  {
325  // It's not what we want, so skip it and
326  // get the next one
327  fs.seek(data_block_size + fs.tell());
328 
329  fs.read(&group, sizeof(vxl_uint_16));
330  group = shortSwap(group);
331  fs.read(&element, sizeof(vxl_uint_16));
332  element = shortSwap(element);
333  fs.read(&data_block_size, sizeof(vxl_uint_32));
334  data_block_size = intSwap(data_block_size);
335  if (data_block_size > 0x1000000) {
336  std::cerr<< __FILE__ << ": " << __LINE__ << " : WARNING:\n"
337  <<"data_block_size=" << data_block_size << " is most probably too large\n";
338  break;
339  }
340 
341  num_elements++;
342  } // End of while (group...)
343 
344  // Check the elements read and see if it fits
345  // with a known header
347  {
348  // First, standard non-Part10 header
349  if (element == VIL_DICOM_HEADER_IDGROUPLENGTH &&
350  data_block_size == 4)
351  {
352  // Put the file back at the beginning
353  fs.seek(0);
355  known = true;
356  } // End of if (element...)
357  // Now a non-standard non-Part10
358  else if (element == VIL_DICOM_HEADER_IDIMAGETYPE ||
359  element == VIL_DICOM_HEADER_IDLENGTHTOEND ||
361  {
362  // Put the file back at the beginning
363  fs.seek(0);
365  known = true;
366  } // End of else if (element...)
367  } // End of if (group == VIL_DICOM_HEADER_IDENTIFYINGGROUP)
368 
369  if (!known)
370  {
372  }
373 
374  num_tries++;
375  } // End of while (num_tries < 2 && !known)
376 
377  if (!known)
378  {
379  file_endian_ = old_endian;
380  }
381  } // End of else
382  } // End of else
383  } // End of if (fs.ok())
384  else
385  {
386  std::cerr << "File not open for reading:\n"
387  << "vil_dicom_header_format::determineFileType()\n";
388  } // End of else
389 
390  return result;
391 }
392 
393 //================================================================
394 
396 {
397  vxl_uint_16 group, element; // The groups and elements read from the header part of the dicom file
398  vxl_uint_32 data_block_size; // The size of the information held for this group/element pair
399  std::cerr << "vil_dicom_header_format::readHeaderElements - Deprecated function called - use the DCMTK code instead!";
400  std::abort();
401 
402  // Read the first group/element pair
403  fs.read(&group, sizeof(vxl_uint_16));
404  fs.read(&element, sizeof(vxl_uint_16));
405 
406  // Swap them if necessary
407  group = shortSwap(group);
408  element = shortSwap(element);
409 
410  // Loop until the file ends (unexpectedly!) or the
411  // pixel data is found
412  while (fs.ok() && !pixelDataFound(group, element))
413  {
414  if (sizeof(vxl_uint_32) != fs.read(&data_block_size, sizeof(vxl_uint_32)))
415  break;
416  data_block_size = intSwap(data_block_size);
417  if (data_block_size > 0x1000000) {
418  std::cerr<< __FILE__ << ": " << __LINE__ << " : WARNING:\n"
419  <<"data_block_size=" << data_block_size << " is most probably too large\n";
420  break;
421  }
422  convertValueRepresentation(data_block_size, fs);
423 
424  switch (group)
425  {
426  // Read identifying info
428  readIdentifyingElements(element, data_block_size, fs);
429  break;
430 
431  // Read the patient info
433  readPatientElements(element, data_block_size, fs);
434  break;
435 
437  readAcquisitionElements(element, data_block_size, fs);
438  break;
439 
441  readRelationshipElements(element, data_block_size, fs);
442  break;
443 
445  readImageElements(element, data_block_size, fs);
446  break;
447 
449  readDelimiterElements(element, data_block_size, fs);
450  break;
451 
453  readProcedureElements(element, data_block_size, fs);
454  break;
455 
457  readNSPhilipsElements(element, data_block_size, fs);
458  break;
459 
460  // Nothing found, so skip this data block
461  default:
462  fs.seek(data_block_size + fs.tell());
463  break;
464  } // End of switch
465 
466  // Read the next group and element
467  fs.read(&group, sizeof(vxl_uint_16));
468  fs.read(&element, sizeof(vxl_uint_16));
469 
470  // Swap them if necessary
471  group = shortSwap(group);
472  element = shortSwap(element);
473  } // End of while
474 
475 
476  // Read the final block size info - throw away!
477  if (sizeof(vxl_uint_32) != fs.read(&data_block_size, sizeof(vxl_uint_32)))
478  return;
479  data_block_size = intSwap(data_block_size);
480  if (data_block_size > 0x1000000)
481  std::cerr << __FILE__ << ": " << __LINE__ << " : WARNING\n"
482  <<"data_block_size=" << data_block_size << " is most probably too large\n";
483  else
484  convertValueRepresentation(data_block_size, fs);
485 }
486 
487 //================================================================
488 
489 // These macros will be used a lot of times in the subsequent read* methods
490 #define CASE(X,M,F) \
491  case X : \
492  data_p = new char[dblock_size+1]; /* Ensure room for 0 */ \
493  if (data_p) \
494  { \
495  fs.read(data_p,dblock_size); \
496  data_p[dblock_size]=0; \
497  last_read_.M = F(data_p); \
498  } \
499  break
500 
501 #define CASE_SWP(X,M) \
502  case X : \
503  data_p = new char[dblock_size+1]; /* Ensure room for 0 */ \
504  if (data_p) \
505  { \
506  fs.read(data_p,dblock_size); \
507  data_p[dblock_size]=0; \
508  charSwap(data_p, sizeof(vxl_uint_16)); \
509  last_read_.M = *((vxl_uint_16*)data_p); \
510  } \
511  break
512 
514  int dblock_size,
515  vil_stream &fs)
516 {
517  // Pointer to any data read
518  char *data_p = 0;
519 
520  // Check the elements
521  switch ((vxl_uint_16)element)
522  {
523  CASE(VIL_DICOM_HEADER_IDIMAGETYPE, image_id_type_, (char *)); // It's the image type
524  CASE(VIL_DICOM_HEADER_IDSOPCLASSID, sop_cl_uid_, (char *)); // It's the SOP class ID
525  CASE(VIL_DICOM_HEADER_IDSOPINSTANCEID, sop_in_uid_, (char *)); // It's the SOP instance ID
526  CASE(VIL_DICOM_HEADER_IDSTUDYDATE, study_date_,std::atol); // It's the study date
527  CASE(VIL_DICOM_HEADER_IDSERIESDATE, series_date_,std::atol); // It's the series date
528  CASE(VIL_DICOM_HEADER_IDACQUISITIONDATE, acquisition_date_,std::atol); // It's the acquisition date
529  CASE(VIL_DICOM_HEADER_IDIMAGEDATE, image_date_,std::atol); // It's the image date
530  CASE(VIL_DICOM_HEADER_IDSTUDYTIME, study_time_,(float)std::atof); // It's the study time
531  CASE(VIL_DICOM_HEADER_IDSERIESTIME, series_time_,(float)std::atof); // It's the series time
532  CASE(VIL_DICOM_HEADER_IDACQUISITIONTIME, acquisition_time_,(float)std::atof); // It's the acquisition time
533  CASE(VIL_DICOM_HEADER_IDIMAGETIME, image_time_,(float)std::atof); // It's the image time
534  CASE(VIL_DICOM_HEADER_IDACCESSIONNUMBER, accession_number_, (char *)); // It's the accession number
535  CASE(VIL_DICOM_HEADER_IDMODALITY, modality_, (char *)); // It's the imaging modality
536  CASE(VIL_DICOM_HEADER_IDMANUFACTURER, manufacturer_, (char *)); // It's the manufacturer name
537  CASE(VIL_DICOM_HEADER_IDINSTITUTIONNAME, institution_name_, (char *)); // It's the institution name
538  CASE(VIL_DICOM_HEADER_IDINSTITUTIONADDRESS,institution_addr_, (char *)); // It's the institution address
539  CASE(VIL_DICOM_HEADER_IDREFERRINGPHYSICIAN,ref_phys_name_, (char *)); // It's the referring physician's name
540  CASE(VIL_DICOM_HEADER_IDSTATIONNAME, station_name_, (char *)); // It's the imaging station name
541  CASE(VIL_DICOM_HEADER_IDSTUDYDESCRIPTION, study_desc_, (char *)); // It's the study description
542  CASE(VIL_DICOM_HEADER_IDSERIESDESCRIPTION, series_desc_, (char *)); // It's the series description
543  CASE(VIL_DICOM_HEADER_IDATTENDINGPHYSICIAN,att_phys_name_, (char *)); // It's the name of the attending physician
544  CASE(VIL_DICOM_HEADER_IDOPERATORNAME, operator_name_, (char *)); // It's the name of the scanner operator
545  CASE(VIL_DICOM_HEADER_IDMANUFACTURERMODEL, model_name_, (char *)); // It's the scanner model
546  default: // It's nothing we want, so skip it!
547  fs.seek(dblock_size + fs.tell());
548  break;
549  } // End of switch
550 
551  delete[] data_p;
552 }
553 
554 //================================================================
555 
557  int dblock_size,
558  vil_stream &fs)
559 {
560  // Pointer to any data read
561  char *data_p = 0;
562 
563  // Check the elements
564  switch ((vxl_uint_16)element)
565  {
566  CASE(VIL_DICOM_HEADER_PIPATIENTNAME, patient_name_, (char *)); // It's the patient's name
567  CASE(VIL_DICOM_HEADER_PIPATIENTID, patient_id_, (char *)); // It's the patient's id
568  CASE(VIL_DICOM_HEADER_PIPATIENTBIRTHDATE,patient_dob_,std::atol); // It's the patient's date of birth
569  CASE(VIL_DICOM_HEADER_PIPATIENTSEX, patient_sex_, (char *)); // It's the patient's sex
570  CASE(VIL_DICOM_HEADER_PIPATIENTAGE, patient_age_, (char *)); // It's the patient's age
571  CASE(VIL_DICOM_HEADER_PIPATIENTWEIGHT, patient_weight_,(float)std::atof); // It's the patient's weight
572  CASE(VIL_DICOM_HEADER_PIPATIENTHISTORY, patient_hist_, (char *)); // It's the patient's history
573  default: // It's nothing we want, so skip it!
574  fs.seek(dblock_size + fs.tell());
575  break;
576  } // End of switch
577 
578  delete[] data_p;
579 }
580 
581 //================================================================
582 
584  int dblock_size,
585  vil_stream &fs)
586 {
587  // Pointer to any data read
588  char *data_p = 0;
589 
590  // Check the elements
591  switch ((vxl_uint_16)element)
592  {
593  CASE(VIL_DICOM_HEADER_AQSCANNINGSEQUENCE, scanning_seq_, (char *)); // It's the scanning sequence
594  CASE(VIL_DICOM_HEADER_AQSEQUENCEVARIANT, sequence_var_, (char *)); // It's the sequence variant
595  CASE(VIL_DICOM_HEADER_AQSCANOPTIONS, scan_options_, (char *)); // It's the scan options
596  CASE(VIL_DICOM_HEADER_AQMRACQUISITIONTYPE, mr_acq_type_, (char *)); // It's the MR acquisition type
597  CASE(VIL_DICOM_HEADER_AQSEQUENCENAME, sequence_name_, (char *)); // It's the sequence name
598  CASE(VIL_DICOM_HEADER_AQANGIOFLAG, angio_flag_, (char *)); // It's the angio flag
599  CASE(VIL_DICOM_HEADER_AQSLICETHICKNESS, slice_thickness_,(float)std::atof); // It's the slice thickness
600  CASE(VIL_DICOM_HEADER_AQREPETITIONTIME, repetition_time_,(float)std::atof); // It's the repetition time
601  CASE(VIL_DICOM_HEADER_AQECHOTIME, echo_time_,(float)std::atof); // It's the echo time
602  CASE(VIL_DICOM_HEADER_AQINVERSIONTIME, inversion_time_,(float)std::atof); // It's the inversion time
603  CASE(VIL_DICOM_HEADER_AQNUMBEROFAVERAGES, number_of_averages_,(float)std::atof); // It's the number of averages
604  CASE(VIL_DICOM_HEADER_AQECHONUMBERS, echo_numbers_,std::atoi); // It's the echo numbers
605  CASE(VIL_DICOM_HEADER_AQMAGNETICFIELDSTRENGTH, mag_field_strength_,(float)std::atof); // It's the magnetic field strength
606  CASE(VIL_DICOM_HEADER_AQSLICESPACING, spacing_slice_,(float)std::atof); // It's the slice spacing
607  CASE(VIL_DICOM_HEADER_AQECHOTRAINLENGTH, echo_train_length_,(int)std::atoi); // It's the echo train length
608  CASE(VIL_DICOM_HEADER_AQPIXELBANDWIDTH, pixel_bandwidth_,(float)std::atof); // It's the pixel bandwidth
609  CASE(VIL_DICOM_HEADER_AQSOFTWAREVERSION, software_vers_, (char *)); // It's the scanner software version
610  CASE(VIL_DICOM_HEADER_AQPROTOCOLNAME, protocol_name_, (char *)); // It's the protocol name
611  CASE(VIL_DICOM_HEADER_AQTRIGGERTIME, trigger_time_,(float)std::atof); // It's the trigger time
612  CASE(VIL_DICOM_HEADER_AQHEARTRATE, heart_rate_,std::atoi); // It's the heart rate
613  CASE(VIL_DICOM_HEADER_AQCARDIACNUMBEROFIMAGES, card_num_images_,std::atoi); // It's the cardiac number of images
614  CASE(VIL_DICOM_HEADER_AQTRIGGERWINDOW, trigger_window_,std::atoi); // It's the trigger window
615  CASE(VIL_DICOM_HEADER_AQRECONTRUCTIONDIAMETER, reconst_diameter_,(float)std::atof); // It's the reconstruction diameter
616  CASE(VIL_DICOM_HEADER_AQRECEIVINGCOIL, receiving_coil_, (char *)); // It's the receiving coil
617  CASE(VIL_DICOM_HEADER_AQPHASEENCODINGDIRECTION,phase_enc_dir_, (char *)); // It's the phase encoding direction
618  CASE(VIL_DICOM_HEADER_AQFLIPANGLE, flip_angle_,(float)std::atof); // It's the flip angle
619  CASE(VIL_DICOM_HEADER_AQSAR, sar_,(float)std::atof); // It's the sar
620  CASE(VIL_DICOM_HEADER_AQPATIENTPOSITION, patient_pos_, (char *)); // It's the patient position
621  case VIL_DICOM_HEADER_AQIMAGERPIXELSPACING : // It's the sensor pixel spacing
622  data_p = new char[dblock_size+1];
623  if (data_p)
624  {
625  fs.read(data_p,dblock_size);
626  data_p[dblock_size]=0;
627  last_read_.imager_spacing_x_ = (float) std::atof(data_p);
628 
629  // The y size should come after a '\'
630  // If only a 0 is found, ysize = xsize
631  char gone = 'x';
632  while (gone != 0 && gone != '\\')
633  {
634  gone = data_p[0];
635  for (int i=0; i<dblock_size; i++)
636  data_p[i] = data_p[i+1];
637  }
638  if (gone == '\\')
639  last_read_.imager_spacing_y_ = (float) std::atof(data_p);
640  else
642  }
643  break;
644  default: // It's nothing we want, so skip it!
645  fs.seek(dblock_size + fs.tell());
646  break;
647  } // End of switch
648 
649  delete[] data_p;
650 }
651 
652 //================================================================
653 
655  int dblock_size,
656  vil_stream &fs)
657 {
658  // Pointer to any data read
659  char *data_p = 0;
660 
661  // Check the elements
662  switch ((vxl_uint_16)element)
663  {
664  CASE(VIL_DICOM_HEADER_RSSTUDYINSTANCEUID, stud_ins_uid_, (char *)); // It's the study instance id
665  CASE(VIL_DICOM_HEADER_RSSERIESINSTANCEUID, ser_ins_uid_, (char *)); // It's the series instance id
666  CASE(VIL_DICOM_HEADER_RSSTUDYID, study_id_, (char *)); // It's the study id
667  CASE(VIL_DICOM_HEADER_RSSERIESNUMBER, series_number_,std::atoi); // It's the series number
668  CASE(VIL_DICOM_HEADER_RSAQUISITIONNUMBER, acquisition_number_,std::atoi); // It's the acqusition number
669  CASE(VIL_DICOM_HEADER_RSIMAGENUMBER, image_number_,std::atoi); // It's the image number
670  CASE(VIL_DICOM_HEADER_RSPATIENTORIENTATION, pat_orient_, (char *)); // It's the patient orientation
671 // CASE(VIL_DICOM_HEADER_RSIMAGEPOSITION, image_pos_, (float)std::atof); // It's the image position
672 // CASE(VIL_DICOM_HEADER_RSIMAGEORIENTATION, image_orient_, (float)std::atof); // It's the image orientation
673  CASE(VIL_DICOM_HEADER_RSFRAMEOFREFERENCEUID,frame_of_ref_, (char *)); // It's the frame of reference uid
674  CASE(VIL_DICOM_HEADER_RSIMAGESINACQUISITION,images_in_acq_,std::atoi); // It's the number of images in the acquisition
675  CASE(VIL_DICOM_HEADER_RSPOSITIONREFERENCE, pos_ref_ind_, (char *)); // It's the position reference
676  CASE(VIL_DICOM_HEADER_RSSLICELOCATION, slice_location_,(float) std::atof); // It's the slice location
677  default: // It's nothing we want, so skip it!
678  fs.seek(dblock_size + fs.tell());
679  break;
680  } // End of switch
681 
682  delete[] data_p;
683 }
684 
685 
686 //================================================================
687 
689  int dblock_size,
690  vil_stream &fs)
691 {
692  // Pointer to any data read
693  char *data_p = 0;
694 
695  // Check the elements
696  switch ((vxl_uint_16)element)
697  {
698  CASE_SWP(VIL_DICOM_HEADER_IMSAMPLESPERPIXEL, pix_samps_); // It's the samples per pixel
699  CASE(VIL_DICOM_HEADER_IMPHOTOMETRICINTERP, photo_interp_, (char *)); // It's the photometric interpretation
700  CASE_SWP(VIL_DICOM_HEADER_IMROWS, size_y_); // It's the rows
701  CASE_SWP(VIL_DICOM_HEADER_IMCOLUMNS, size_x_); // It's the columns
702  CASE_SWP(VIL_DICOM_HEADER_IMPLANES, size_z_); // It's the planes
703  CASE_SWP(VIL_DICOM_HEADER_IMBITSALLOCATED, allocated_bits_); // It's the allocated bits
704  CASE_SWP(VIL_DICOM_HEADER_IMBITSSTORED, stored_bits_); // It's the stored bits info
705  CASE_SWP(VIL_DICOM_HEADER_IMHIGHBIT, high_bit_); // It's the high bit
706  CASE_SWP(VIL_DICOM_HEADER_IMPIXELREPRESENTATION,pix_rep_); // It's the pixel representation
707  CASE_SWP(VIL_DICOM_HEADER_IMSMALLIMPIXELVALUE, small_im_pix_val_); // It's the smallest image pixel value
708  CASE_SWP(VIL_DICOM_HEADER_IMLARGEIMPIXELVALUE, large_im_pix_val_); // It's the largest image pixel value
709  CASE_SWP(VIL_DICOM_HEADER_IMPIXELPADDINGVALUE, pixel_padding_val_); // It's the pixel padding value
710  CASE(VIL_DICOM_HEADER_IMWINDOWCENTER, window_centre_,(float) std::atof); // It's the window centre
711  CASE(VIL_DICOM_HEADER_IMWINDOWWIDTH, window_width_,(float) std::atof); // It's the window width
712  CASE(VIL_DICOM_HEADER_IMRESCALEINTERCEPT, res_intercept_,(float) std::atof); // It's the rescale intercept
713  CASE(VIL_DICOM_HEADER_IMRESCALESLOPE, res_slope_,(float) std::atof); // It's the rescale slope
714  case VIL_DICOM_HEADER_IMPIXELSPACING : // It's the pixel spacing
715  data_p = new char[dblock_size+1];
716  if (data_p)
717  {
718  fs.read(data_p,dblock_size);
719  data_p[dblock_size]=0;
720  last_read_.spacing_x_ = (float) std::atof(data_p);
721 
722  // The y size should come after a '\'
723  // If only a 0 is found, ysize = xsize
724  char gone = 'x';
725  while (gone != 0 && gone != '\\')
726  {
727  gone = data_p[0];
728  for (int i=0; i<dblock_size; i++)
729  data_p[i] = data_p[i+1];
730  }
731  if (gone == '\\')
732  last_read_.spacing_y_ = (float) std::atof(data_p);
733  else
735  }
736  break;
737  default: // It's nothing we want, so skip it!
738  fs.seek(dblock_size + fs.tell());
739  break;
740  } // End of switch
741 
742  delete[] data_p;
743 }
744 
745 //================================================================
746 
748  int dblock_size,
749  vil_stream &fs)
750 {
751  // Check the elements
752  switch ((vxl_uint_16)element)
753  {
757  // There's no data block
758  break;
759  // It's nothing we want, so skip it!
760  default:
761  fs.seek(dblock_size + fs.tell());
762  break;
763  } // End of switch
764 }
765 
766 //================================================================
767 
769  int dblock_size,
770  vil_stream &fs)
771 {
772  // Pointer to any data read
773  char *data_p = 0;
774 
775  // Check the elements
776  //std::cout << "Proecedure group; element: " << element << std::endl;
777  switch ((vxl_uint_16)element)
778  {
779  CASE(VIL_DICOM_HEADER_PRREALWORLDVALUEINTERCEPT,real_world_value_intercept_,(double)std::atof); // It's the real world intercept value
780  CASE(VIL_DICOM_HEADER_PRREALWORLDVALUESLOPE ,real_world_value_slope_,(double)std::atof); // It's the real world intercept value
781  default: // It's nothing we want, so skip it!
782  std::cout << "Procedure group; unread element: " << element << std::endl;
783  fs.seek(dblock_size + fs.tell());
784  break;
785  } // End of switch
786 
787  delete[] data_p;
788 }
789 
790 //================================================================
791 
793  int dblock_size,
794  vil_stream &fs)
795 {
796  // Pointer to any data read
797  char *data_p = 0;
798 
799  // Check the elements
800  //std::cout << "Non-standard Philips group; element: " << element << std::endl;
801  switch ((vxl_uint_16)element)
802  {
803  CASE(VIL_DICOM_HEADER_NSPHILIPSPRIVATEINTERCEPT,philips_private_intercept_,(float)std::atof); // It's the Philips private intercept value
804  CASE(VIL_DICOM_HEADER_NSPHILIPSPRIVATESLOPE ,philips_private_slope_,(float)std::atof); // It's the Philips private slope value
805  default: // It's nothing we want, so skip it!
806  std::cout << "Non-standard Philips group; unread element: " << element << std::endl;
807  fs.seek(dblock_size + fs.tell());
808  break;
809  } // End of switch
810 
811  delete[] data_p;
812 }
813 
814 //================================================================
815 
816 bool vil_dicom_header_format::convertValueRepresentation(unsigned int &dblock_size,
817  vil_stream &fs)
818 {
819  bool result = false;
820  std::string first, last;
821  char temp[3];
822 
823  // Union to convert the int to chars
824  union int_char
825  {
826  vxl_uint_32 int_val;
827  char char_val[4];
828  } conv_dblock;
829 
831  {
832  conv_dblock.int_val = dblock_size;
833 
834  // Create the strings to check (the latter two positions in
835  // the std::string are swapped in case of little endian-ness)
836  temp[0] = conv_dblock.char_val[0];
837  temp[1] = conv_dblock.char_val[1];
838  temp[2] = 0;
839 
840  first = temp;
841 
842  temp[0] = conv_dblock.char_val[3];
843  temp[1] = conv_dblock.char_val[2];
844 
845  last = temp;
846 
847  // Check if VR is a nested sequence (SQ)
849  {
850  fs.read(&dblock_size, sizeof(int));
851  dblock_size = 0;
852  result = true;
853  } // End of if (first...)
854  else if (first == VIL_DICOM_HEADER_OTHERBYTE ||
855  first == VIL_DICOM_HEADER_OTHERWORD ||
856  last == VIL_DICOM_HEADER_OTHERBYTE ||
858  {
859  fs.read(&dblock_size, sizeof(int));
860  dblock_size = intSwap(dblock_size);
861  result = true;
862  } // End of else if (first...)
863  else if (dblock_size == VIL_DICOM_HEADER_ALLSET)
864  {
865  dblock_size = 0;
866  result = true;
867  } // End of else if (dblock_size == VIL_DICOM_HEADER_ALLSET)
868  else if (first == VIL_DICOM_HEADER_APPLICATIONENTRY ||
869  first == VIL_DICOM_HEADER_AGESTRING ||
871  first == VIL_DICOM_HEADER_CODESTRING ||
872  first == VIL_DICOM_HEADER_DATE ||
874  first == VIL_DICOM_HEADER_DATETIME ||
878  first == VIL_DICOM_HEADER_LONGSTRING ||
879  first == VIL_DICOM_HEADER_LONGTEXT ||
880  first == VIL_DICOM_HEADER_PERSONNAME ||
881  first == VIL_DICOM_HEADER_SHORTSTRING ||
882  first == VIL_DICOM_HEADER_SIGNEDLONG ||
883  first == VIL_DICOM_HEADER_SIGNEDSHORT ||
884  first == VIL_DICOM_HEADER_SHORTTEXT ||
885  first == VIL_DICOM_HEADER_TIME ||
889  {
891  {
892  dblock_size = (unsigned int)((256*conv_dblock.char_val[3]) + conv_dblock.char_val[2]);
893  }
894  else
895  {
896  dblock_size = (unsigned int)((256*conv_dblock.char_val[2]) + conv_dblock.char_val[3]);
897  }
898 
899  result = true;
900  } // End of else if (first...)
901  else if (last == VIL_DICOM_HEADER_APPLICATIONENTRY ||
902  last == VIL_DICOM_HEADER_AGESTRING ||
904  last == VIL_DICOM_HEADER_CODESTRING ||
905  last == VIL_DICOM_HEADER_DATE ||
907  last == VIL_DICOM_HEADER_DATETIME ||
911  last == VIL_DICOM_HEADER_LONGSTRING ||
912  last == VIL_DICOM_HEADER_LONGTEXT ||
913  last == VIL_DICOM_HEADER_PERSONNAME ||
915  last == VIL_DICOM_HEADER_SIGNEDLONG ||
917  last == VIL_DICOM_HEADER_SHORTTEXT ||
918  last == VIL_DICOM_HEADER_TIME ||
922  {
924  {
925  dblock_size = (unsigned int)((256*conv_dblock.char_val[1]) + conv_dblock.char_val[0]);
926  }
927  else
928  {
929  dblock_size = (unsigned int)((256*conv_dblock.char_val[0]) + conv_dblock.char_val[1]);
930  }
931 
932  result = true;
933  } // End of else if (last...)
934  } // End of if (last_read_.file_type_ != VIL_DICOM_HEADER_DTUNKNOWN)
935 
936  return result;
937 }
938 
939 //================================================================
940 
941 bool vil_dicom_header_format::pixelDataFound(short group, short element)
942 {
943  bool result = false;
944 
945  // Check if it's the pixel data
946  if ((vxl_uint_16)group == VIL_DICOM_HEADER_PIXELGROUP &&
947  (vxl_uint_16)element == VIL_DICOM_HEADER_PXPIXELDATA)
948  {
949  result = true;
950  }
951 
952  return result;
953 }
954 
955 //================================================================
956 
958 {
960 
961  // And make it invalid
962  info_valid_ = false;
963 }
964 
965 //================================================================
966 
968 {
969  // Create a union to test endian
970  union int_byte
971  {
972  vxl_uint_32 int_val;
973  vxl_byte by_val[4];
974  } calc_endian;
975 
976  // Put 1 into the union
977  calc_endian.int_val = 1;
978 
979  // Test which byte has the value 1 in it
980  return calc_endian.by_val[0] == 1 ?
983 }
984 
985 //===============================================================
986 
988 {
989  vil_dicom_header_endian ret_end = VIL_DICOM_HEADER_DELITTLEENDIAN; // Assume little if none found
990  //vil_dicom_header_endian ret_end = VIL_DICOM_HEADER_DEBIGENDIAN;
991 
992  vxl_uint_16 group, element;
993  vxl_uint_32 data_block_size;
994  vil_streampos ret_pos = fs.tell(); // Maintain the file position
995 
996  // The first section of the file header is always little endian,
997  // so set the file endian
1000 
1001  // Read the next group
1002  fs.read(&group,sizeof(vxl_uint_16));
1003  group = shortSwap(group);
1004 
1005  while (fs.ok() && group <= VIL_DICOM_HEADER_METAFILEGROUP)
1006  {
1007  // Read the element
1008 
1009  fs.read(&element,sizeof(vxl_uint_16));
1010  element = shortSwap(element);
1011 
1012  // Read the data block size
1013  if (sizeof(vxl_uint_32) != fs.read(&data_block_size, sizeof(vxl_uint_32)))
1014  break;
1015 
1016  data_block_size = intSwap(data_block_size);
1017 
1018  if (data_block_size > 0x1000000) {
1019  std::cerr<< __FILE__ << ": " << __LINE__ << " : WARNING:\n"
1020  <<"data_block_size=" << data_block_size << " is most probably too large\n";
1021  break;
1022  }
1023 
1024  convertValueRepresentation(data_block_size,fs);
1025 
1026  if (group == VIL_DICOM_HEADER_METAFILEGROUP &&
1028  {
1029  // This tells us the transfer syntax for the file
1030  char * tfx_type = new char[data_block_size+1]; // Ensure room for 0
1031  if (tfx_type)
1032  {
1033  fs.read(tfx_type, data_block_size);
1034  tfx_type[data_block_size]=0;
1035 
1036  // Now see what it is
1037 
1038  std::string temp = tfx_type;
1039  delete [] tfx_type;
1040 
1041  if (temp == VIL_DICOM_HEADER_IMPLICITLITTLE ||
1043  {
1044  // Little endian
1046  }
1047  else if (temp == VIL_DICOM_HEADER_EXPLICITBIG)
1048  {
1049  // Big endian
1050  ret_end = VIL_DICOM_HEADER_DEBIGENDIAN;
1051  }
1052  else if (temp == VIL_DICOM_HEADER_JPEGBASELINE_P1)
1053  {
1054  // Jpeg Baseline
1056  }
1057  else if (temp == VIL_DICOM_HEADER_JPEGDEFLOSSY_P2_4 ||
1059  {
1060  // Jpeg extended lossy
1062  }
1063  else if (temp == VIL_DICOM_HEADER_JPEGSPECTRAL_P6_8 ||
1065  {
1066  // Jpeg spectral selection non-hierarchical
1068  }
1069  else if (temp == VIL_DICOM_HEADER_JPEGFULLPROG_P10_12 ||
1071  {
1072  // Full progression non-hierarchical
1074  }
1075  else if (temp == VIL_DICOM_HEADER_JPEGLOSSLESS_P14 ||
1077  {
1078  // Lossless non-hierarchical
1080  }
1081  else if (temp == VIL_DICOM_HEADER_JPEGEXTHIER_P16_18 ||
1083  {
1084  // Extended hierarchical
1086  }
1087  else if (temp == VIL_DICOM_HEADER_JPEGSPECHIER_P20_22 ||
1089  {
1090  // Spectral selection hierarchical
1092  }
1093  else if (temp == VIL_DICOM_HEADER_JPEGFULLHIER_P24_26 ||
1095  {
1096  // Full progression hierarchical
1098  }
1099  else if (temp == VIL_DICOM_HEADER_JPEGLLESSHIER_P28 ||
1101  {
1102  // Lossless hierarchical
1104  }
1105  else if (temp == VIL_DICOM_HEADER_JPEGLLESSDEF_P14_SV1)
1106  {
1107  // The default for lossless jpeg
1109  }
1110  else if (temp == VIL_DICOM_HEADER_RLELOSSLESS)
1111  {
1112  // RLE encapsulated
1114  }
1115 
1116  } // End of if (tfx_type)
1117  } // End of if (group...)
1118  else if (group == VIL_DICOM_HEADER_DELIMITERGROUP &&
1119  (element == VIL_DICOM_HEADER_DLITEM ||
1122  {
1123  // Do nothing
1124  }
1125  else
1126  {
1127  // Ignore the data that's there
1128  fs.seek(data_block_size + fs.tell());
1129  }
1130 
1131  ret_pos = fs.tell();
1132 
1133  // Read the next group
1134 
1135  fs.read(&group,sizeof(vxl_uint_16));
1136  group = shortSwap(group);
1137 
1138  } // End of while
1139 
1140  // Reset the pointer before the last read group
1141  fs.seek(ret_pos);
1142 
1143  return ret_end;
1144 }
1145 
1146 //===============================================================
1147 
1148 vxl_uint_16 vil_dicom_header_format::shortSwap(vxl_uint_16 short_in)
1149 {
1150  vxl_uint_16 result = short_in;
1151 
1152  // Only swap if the architecture is different to the
1153  // file (the logic means that if one is unknown it swaps,
1154  // if both are unknown, it doesnt)
1155  if (file_endian_ != endian_)
1156  {
1157  // Create a short unioned with two chars
1158  union short_char
1159  {
1160  vxl_uint_16 short_val;
1161  vxl_byte byte_val[2];
1162  } short_swap;
1163 
1164  // Set the swapper
1165  short_swap.short_val = short_in;
1166 
1167  // Swap them over
1168  vxl_byte temp = short_swap.byte_val[0];
1169  short_swap.byte_val[0]=short_swap.byte_val[1];
1170  short_swap.byte_val[1]=temp;
1171 
1172  result = short_swap.short_val;
1173  } // End of if (file_endian_ != endian_)
1174 
1175  return result;
1176 }
1177 
1178 //===============================================================
1179 
1180 vxl_uint_32 vil_dicom_header_format::intSwap(vxl_uint_32 int_in)
1181 {
1182  vxl_uint_32 result = int_in;
1183 
1184  // Only swap if the architecture is different to the
1185  // file (the logic means that if one is unknown it swaps,
1186  // if both are unknown, it doesnt)
1187  if (file_endian_ != endian_)
1188  {
1189  // Create a vxl_uint_32 unioned with four chars
1190  union int_char
1191  {
1192  vxl_uint_32 int_val;
1193  vxl_byte byte_val[4];
1194  } int_swap;
1195 
1196  // Set the swapper
1197  int_swap.int_val = int_in;
1198 
1199  // Swap them over (end ones first)
1200  vxl_byte temp = int_swap.byte_val[0];
1201  int_swap.byte_val[0]=int_swap.byte_val[3];
1202  int_swap.byte_val[3]=temp;
1203 
1204  // Now the middle ones
1205  temp = int_swap.byte_val[1];
1206  int_swap.byte_val[1] = int_swap.byte_val[2];
1207  int_swap.byte_val[2] = temp;
1208 
1209  result = int_swap.int_val;
1210  } // End of if (file_endian_ != endian_)
1211 
1212  return result;
1213 }
1214 
1215 //===============================================================
1216 
1217 void vil_dicom_header_format::charSwap(char *char_in, int val_size)
1218 {
1219  // Only swap if the architecture is different to the
1220  // file (the logic means that if one is unknown it swaps,
1221  // if both are unknown, it doesnt)
1222  if (file_endian_ != endian_)
1223  {
1224  // Swap first with last, second with one-but-last, etc.
1225  for (int i=val_size/2-1; i>=0; --i)
1226  {
1227  char temp=char_in[i];
1228  char_in[i] = char_in[val_size-i-1];
1229  char_in[val_size-i-1] = temp;
1230  }
1231  }
1232 }
1233 
1234 
1235 void vil_dicom_header_print(std::ostream &os, const vil_dicom_header_info &s)
1236 {
1237  os << "\n\nGeneral info fields\n"
1238  << " file_type The type of dicom file: " << s.file_type_ << std::endl
1239  << " sys_endian The endian of the architecture: " << s.sys_endian_ << std::endl
1240  << " image_type The encapsulated (or not) image type: " <<s.image_type_ << std::endl
1241 
1242  << "\n\nIdentifying fields\n"
1243  << " image_id_type The image type from the dicom header: " << s.image_id_type_ << std::endl
1244  << " sop_cl_uid The class unique id for the Service/Object Pair: " << s.sop_cl_uid_ << std::endl
1245  << " sop_in_uid The instance uid for the SOP: " << s.sop_in_uid_ << std::endl
1246  << " study_date The date of the study: " << s.study_date_ << std::endl
1247  << " series_date The date this series was collected: " << s.series_date_ << std::endl
1248  << " acquisition_date The date of acquisition: " << s.acquisition_date_ << std::endl
1249  << " image_date The date of this image: " << s.image_date_ << std::endl
1250  << " study_time The time of the study: " << s.study_time_ << std::endl
1251  << " series_time The time of the series: " << s.series_time_ << std::endl
1252  << " acquisition_time The time acquisition: " << s.acquisition_time_ << std::endl
1253  << " image_time The time of the image: " << s.image_time_ << std::endl
1254  << " accession_number The accession number for this image: " << s.accession_number_ << std::endl
1255  << " modality The imaging modality: " << s.modality_ << std::endl
1256  << " manufacturer The name of the scanner manufacturer: " << s.manufacturer_ << std::endl
1257  << " institution_name The name of the institution: " << s.institution_name_ << std::endl
1258  << " institution_addr The address of the institution: " << s.institution_addr_ << std::endl
1259  << " ref_phys_name The name of the referring physician: " << s.ref_phys_name_ << std::endl
1260  << " station_name The name of the station used: " << s.station_name_ << std::endl
1261  << " study_desc A description of the study: " << s.study_desc_ << std::endl
1262  << " series_desc A description of the series: " << s.series_desc_ << std::endl
1263  << " att_phys_name The name of the attending physician: " << s.att_phys_name_ << std::endl
1264  << " operator_name The name of the MR operator: " << s.operator_name_ << std::endl
1265  << " model_name The name of the MR scanner model: " << s.model_name_ << std::endl
1266 
1267  << "\n\nPatient info\n"
1268  << " patient_name Patient's name: " << s.patient_name_ << std::endl
1269  << " patient_id Patient's ID: " << s.patient_id_ << std::endl
1270  << " patient_dob The patient's date of birth: " << s.patient_dob_ << std::endl
1271  << " patient_sex The sex of the patient: " << s.patient_sex_ << std::endl
1272  << " patient_age The age of the patient: " << s.patient_age_ << std::endl
1273  << " patient_weight_ The weight of the patient: " << s.patient_weight_ << std::endl
1274  << " patient_hist Any additional patient history: " << s.patient_hist_ << std::endl
1275 
1276  << "\n\nAcquisition Info\n"
1277  << " scanning_seq A description of the scanning sequence: " << s.scanning_seq_ << std::endl
1278  << " sequence_var A description of the sequence variant: " << s.sequence_var_ << std::endl
1279  << " scan_options A description of various scan options: " << s.scan_options_ << std::endl
1280  << " mr_acq_type The acquisition type for this scan: " << s.mr_acq_type_ << std::endl
1281  << " sequence_name The name of the sequence: " << s.sequence_name_ << std::endl
1282  << " angio_flag The angio flag for this sequence: " << s.angio_flag_ << std::endl
1283  << " slice_thickness_ Slice thickness (for voxel size): " << s.slice_thickness_ << std::endl
1284  << " repetition_time_ Scan repetition time: " << s.repetition_time_ << std::endl
1285  << " echo_time Scan echo time: " << s.echo_time_ << std::endl
1286  << " inversion_time Scan inversion time: " << s.inversion_time_ << std::endl
1287  << " number_of_averages The number of averages for this scan: " << s.number_of_averages_ << std::endl
1288  << " echo_numbers The echo numbers for this scan: " << s.echo_numbers_ << std::endl
1289  << " mag_field_strength The strength of the magnetic field: " << s.mag_field_strength_ << std::endl
1290  << " echo_train_length The length of the echo train: " << s.echo_train_length_ << std::endl
1291  << " pixel_bandwidth The bandwidth of the pixels: " << s.pixel_bandwidth_ << std::endl
1292  << " software_vers_ Versions of the scanner software used: " << s.software_vers_ << std::endl
1293  << " protocol_name The name of the protocol used: " << s.protocol_name_ << std::endl
1294  << " trigger_time The trigger time: " << s.trigger_time_ << std::endl
1295  << " heart_rate The patient's heart rate: " << s.heart_rate_ << std::endl
1296  << " card_num_images The cardiac number of images: " << s.card_num_images_ << std::endl
1297  << " trigger_window The trigger window for this image: " << s.trigger_window_ << std::endl
1298  << " reconst_diameter The reconstruction diameter: " << s.reconst_diameter_ << std::endl
1299  << " receiving_coil_ Details of the receiving coil: " << s.receiving_coil_ << std::endl
1300  << " phase_enc_dir The phase encoding direction: " << s.phase_enc_dir_ << std::endl
1301  << " flip_angle The flip angle: " << s.flip_angle_ << std::endl
1302  << " sar The specific absorption rate: " << s.sar_ << std::endl
1303  << " patient_pos The position of the patient in the scanner: " << s.patient_pos_ << std::endl
1304 
1305  << "\n\nRelationship info\n"
1306  << " stud_ins_uid The study instance unique id: " << s.stud_ins_uid_ << std::endl
1307  << " ser_ins_uid The series instance unique id: " << s.ser_ins_uid_ << std::endl
1308  << " study_id The id of this study: " << s.study_id_ << std::endl
1309  << " series_number The number of this series: " << s.series_number_ << std::endl
1310  << " acquisition_number The number of the acquisition: " << s.acquisition_number_ << std::endl
1311  << " image_number The number of this image instance: " << s.image_number_ << std::endl
1312  << " pat_orient The orientation of the patient: " << s.pat_orient_ << std::endl
1313  << " image_pos The image position relative to the patient: " << s.image_pos_[0] << '/' << s.image_pos_[1] << '/' << s.image_pos_[2] << std::endl
1314  << " image_orient The image orientation relative to the patient: " << s.image_orient_[0] << '/' << s.image_orient_[1] << '/' << s.image_orient_[2] << '/' << s.image_orient_[3] << '/' << s.image_orient_[4] << '/' << s.image_orient_[5] << std::endl
1315  << " frame_of_ref The frame of reference" << s.frame_of_ref_ << std::endl
1316  << " images_in_acq Then number ot images in the acquisition: " << s.images_in_acq_ << std::endl
1317  << " pos_ref_ind The position reference indicator: " << s.pos_ref_ind_ << std::endl
1318  << " slice_location The location of the slice: " << s.slice_location_ << std::endl
1319 
1320  << "\n\nImage info\n"
1321  << " pix_samps The number of samples per pixel: " << s.pix_samps_ << std::endl
1322  << " photo_interp The photometric interpretation: " << s.photo_interp_ << std::endl
1323  << " size_x The number of columns: " << s.size_x_ << std::endl
1324  << " size_y The number of rows: " << s.size_y_ << std::endl
1325  << " size_z The number of planes: " << s.size_z_ << std::endl
1326  << " high_bit The bit used as the high bit: " << s.high_bit_ << std::endl
1327  << " small_im_pix_val The smallest image pixel value: " << s.small_im_pix_val_ << std::endl
1328  << " large_im_pix_val The largest image pixel value: " << s.large_im_pix_val_ << std::endl
1329  << " pixel_padding_val The value used for padding pixels: " << s.pixel_padding_val_ << std::endl
1330  << " window_centre The value of the image window's centre: " << s.window_centre_ << std::endl
1331  << " window_width The actual width of the image window: " << s.window_width_ << std::endl
1332 
1333  << "\n\nInfo from the tags specifically for reading the image data\n"
1334  << " spaxing_x The pixel spacing in x: " << s.spacing_x_ << std::endl
1335  << " spacing_y The pixel spacing in y: " << s.spacing_y_ << std::endl
1336  << " spacing_slice The pixel spacing in z: " << s.spacing_slice_ << std::endl
1337  << " res_intercept The image rescale intercept: " << s.res_intercept_ << std::endl
1338  << " res_slope The image rescale slope: " << s.res_slope_ << std::endl
1339  << " pix_rep The pixel representation (+/-): " << s.pix_rep_ << std::endl
1340  << " stored_bits The bits stored: " << s.stored_bits_ << std::endl
1341  << " allocated_bits The bits allocated: " << s.allocated_bits_ << std::endl
1342  << " imager_spacing_x The sensor pixel spacing in x: " << s.imager_spacing_x_ << std::endl
1343  << " imager_spacing_y The sensor pixel spacing in y: " << s.imager_spacing_y_ << std::endl
1344 
1345  << "\n\nInfo from the tags specifically for the procedure group\n"
1346  << " real_world_value_intercept The real world intercept value: " << s.real_world_value_intercept_ << std::endl
1347  << " real_world_value_slope The real world slope value: " << s.real_world_value_slope_ << std::endl
1348  << " exposedarea_x The exposed area in x: " << s.exposedarea_x_ << std::endl
1349  << " exposedarea_y The exposed ares in y: " << s.exposedarea_y_ << std::endl
1350 
1351 
1352  << "\n\nInfo from the tags specifically for the Philips private group (2005)\n"
1353  << " philips_private_intercept The philips private intercept value: " << s.philips_private_intercept_ << std::endl
1354  << " philips_private_slope The philips private slope value: " << s.philips_private_slope_ << std::endl;
1355 }
1356 
1357 #endif // HAS_DCMTK
vil_dicom_header_type_of< vil_dicom_header_US >::type small_im_pix_val_
const vxl_uint_16 VIL_DICOM_HEADER_NSPHILIPSGROUP
Stream interface for VIL image loaders.
const vxl_uint_16 VIL_DICOM_HEADER_IDMANUFACTURER
vil_dicom_header_type_of< vil_dicom_header_CS >::type phase_enc_dir_
const char *const VIL_DICOM_HEADER_JPEGFULLPROG_P11_13
const vxl_uint_16 VIL_DICOM_HEADER_PIPATIENTHISTORY
vil_dicom_header_type
DICOM types.
const vxl_uint_16 VIL_DICOM_HEADER_DLITEMDELIMITATIONITEM
vil_dicom_header_type_of< vil_dicom_header_CS >::type modality_
vil_dicom_header_type_of< vil_dicom_header_IS >::type acquisition_number_
const vxl_uint_16 VIL_DICOM_HEADER_AQPATIENTPOSITION
virtual vil_streampos tell() const =0
Return file pointer.
vil_dicom_header_type_of< vil_dicom_header_IS >::type echo_train_length_
const char *const VIL_DICOM_HEADER_FLOATINGPOINTSINGLE
vil_dicom_header_type_of< vil_dicom_header_CS >::type angio_flag_
vil_dicom_header_type_of< vil_dicom_header_IS >::type echo_numbers_
const char *const VIL_DICOM_HEADER_JPEGSPECTRAL_P6_8
const vxl_uint_16 VIL_DICOM_HEADER_PIXELGROUP
const vxl_uint_16 VIL_DICOM_HEADER_RSPOSITIONREFERENCE
vil_dicom_header_type_of< vil_dicom_header_DS >::type spacing_x_
const vxl_uint_16 VIL_DICOM_HEADER_IDIMAGEDATE
vil_dicom_header_type_of< vil_dicom_header_US >::type exposedarea_y_
const char *const VIL_DICOM_HEADER_EXPLICITLITTLE
const vxl_uint_16 VIL_DICOM_HEADER_IMPIXELPADDINGVALUE
const vxl_uint_16 VIL_DICOM_HEADER_NSPHILIPSPRIVATEINTERCEPT
const vxl_uint_16 VIL_DICOM_HEADER_RSSERIESINSTANCEUID
vil_dicom_header_type_of< vil_dicom_header_US >::type allocated_bits_
vil_dicom_header_type_of< vil_dicom_header_DS >::type sar_
const vxl_uint_16 VIL_DICOM_HEADER_IDIMAGETYPE
const char *const VIL_DICOM_HEADER_APPLICATIONENTRY
const vxl_uint_16 VIL_DICOM_HEADER_IMROWS
const vxl_uint_16 VIL_DICOM_HEADER_IDSERIESDATE
vil_dicom_header_type_of< vil_dicom_header_IS >::type series_number_
vil_dicom_header_type_of< vil_dicom_header_SH >::type station_name_
const vxl_uint_16 VIL_DICOM_HEADER_AQECHOTIME
vil_dicom_header_type_of< vil_dicom_header_DS >::type trigger_time_
bool isDicomFormat(vil_stream &)
True if it is known DICOM format.
vil_dicom_header_type_of< vil_dicom_header_US >::type size_x_
vil_dicom_header_type_of< vil_dicom_header_IS >::type images_in_acq_
const vxl_uint_16 VIL_DICOM_HEADER_AQSOFTWAREVERSION
vil_dicom_header_type_of< vil_dicom_header_LO >::type manufacturer_
vil_dicom_header_type_of< vil_dicom_header_CS >::type sequence_var_
vil_dicom_header_type_of< vil_dicom_header_AS >::type patient_age_
void readIdentifyingElements(short element, int dblock_size, vil_stream &fs)
Method to read the identifying group's details.
vil_dicom_header_type_of< vil_dicom_header_PN >::type operator_name_
const vxl_uint_16 VIL_DICOM_HEADER_AQRECEIVINGCOIL
vil_dicom_header_endian fileEndian(void)
Return the endian of the header being read.
const vxl_uint_16 VIL_DICOM_HEADER_AQTRIGGERTIME
vil_dicom_header_type_of< vil_dicom_header_DS >::type window_centre_
vil_dicom_header_type_of< vil_dicom_header_IS >::type heart_rate_
vil_dicom_header_type_of< vil_dicom_header_LO >::type series_desc_
const char *const VIL_DICOM_HEADER_JPEGLLESSDEF_P14_SV1
vil_dicom_header_type_of< vil_dicom_header_LO >::type institution_name_
const vxl_uint_16 VIL_DICOM_HEADER_PIPATIENTBIRTHDATE
const char *const VIL_DICOM_HEADER_LONGTEXT
const vxl_uint_16 VIL_DICOM_HEADER_IDINSTITUTIONADDRESS
const char *const VIL_DICOM_HEADER_FLOATINGPOINTDOUBLE
const vxl_uint_16 VIL_DICOM_HEADER_AQSCANOPTIONS
const vxl_uint_16 VIL_DICOM_HEADER_IDSTUDYTIME
void vil_dicom_header_info_clear(vil_dicom_header_info &info)
Clears a header info struct.
const vxl_uint_16 VIL_DICOM_HEADER_PXPIXELDATA
virtual void seek(vil_streampos position)=0
Goto file pointer.
const vxl_uint_16 VIL_DICOM_HEADER_IDSERIESTIME
const vxl_uint_16 VIL_DICOM_HEADER_PIPATIENTAGE
void readAcquisitionElements(short element, int dblock_size, vil_stream &fs)
Method to read the acquisition group's details.
vil_dicom_header_type_of< vil_dicom_header_LO >::type patient_id_
void readRelationshipElements(short element, int dblock_size, vil_stream &fs)
Method to read the relationship group's details.
const vxl_uint_16 VIL_DICOM_HEADER_NSPHILIPSPRIVATESLOPE
const vxl_uint_16 VIL_DICOM_HEADER_IDIMAGETIME
const char *const VIL_DICOM_HEADER_JPEGSPECTRAL_P7_9
vil_dicom_header_type_of< vil_dicom_header_DS >::type number_of_averages_
vil_dicom_header_type_of< vil_dicom_header_PN >::type att_phys_name_
const vxl_uint_16 VIL_DICOM_HEADER_IDMODALITY
virtual vil_streampos read(void *buf, vil_streampos n)=0
Read n bytes into buf. Returns number of bytes read.
const vxl_uint_16 VIL_DICOM_HEADER_PRREALWORLDVALUESLOPE
const vxl_uint_16 VIL_DICOM_HEADER_IMPIXELSPACING
vil_dicom_header_type_of< vil_dicom_header_IS >::type card_num_images_
std::vector< vil_dicom_header_type_of< vil_dicom_header_DS >::type > image_orient_
vil_dicom_header_type_of< vil_dicom_header_DS >::type flip_angle_
vil_dicom_header_type_of< vil_dicom_header_DS >::type reconst_diameter_
vil_dicom_header_type_of< vil_dicom_header_US >::type size_y_
vil_dicom_header_endian calculateEndian(void)
Work out whether the current architecture is big or little endian.
const char *const VIL_DICOM_HEADER_JPEGFULLHIER_P25_27
const unsigned short VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED
const char *const VIL_DICOM_HEADER_JPEGLOSSLESS_P14
const float VIL_DICOM_HEADER_DEFAULTINTERCEPT
const vxl_uint_16 VIL_DICOM_HEADER_PIPATIENTWEIGHT
const char *const VIL_DICOM_HEADER_JPEGEXTHIER_P17_19
std::vector< vil_dicom_header_type_of< vil_dicom_header_DS >::type > image_pos_
vil_dicom_header_endian determineMetaInfo(vil_stream &fs)
Initialise all the necessary meta-file stuff.
const char *const VIL_DICOM_HEADER_JPEGFULLHIER_P24_26
vil_dicom_header_image_type image_type_
const vxl_uint_16 VIL_DICOM_HEADER_IMPHOTOMETRICINTERP
bool pixelDataFound(short group, short element)
Method to determine whether or not the actual pixel data has been reached.
const vxl_uint_16 VIL_DICOM_HEADER_AQSEQUENCENAME
vil_dicom_header_endian
Endian types.
const vxl_uint_16 VIL_DICOM_HEADER_PROCEDUREGROUP
const vxl_uint_16 VIL_DICOM_HEADER_RSIMAGENUMBER
vil_dicom_header_type_of< vil_dicom_header_DS >::type res_slope_
bool headerValid(void)
Method to indicate if the header info held is valid or not.
const vxl_uint_16 VIL_DICOM_HEADER_AQSEQUENCEVARIANT
vil_dicom_header_type_of< vil_dicom_header_UI >::type sop_cl_uid_
void vil_dicom_header_info_clear(vil_dicom_header_info &info)
Clears a header info struct.
const vxl_uint_16 VIL_DICOM_HEADER_DLITEM
const char *const VIL_DICOM_HEADER_JPEGEXTHIER_P16_18
const char *const VIL_DICOM_HEADER_AGESTRING
const vxl_uint_16 VIL_DICOM_HEADER_AQFLIPANGLE
vil_dicom_header_type_of< vil_dicom_header_FD >::type real_world_value_slope_
bool info_valid_
TRUE if the header info is valid (i.e. has been read) otherwise FALSE.
const vxl_uint_16 VIL_DICOM_HEADER_IDGROUPLENGTH
const char *const VIL_DICOM_HEADER_JPEGLLESSHIER_P28
const char *const VIL_DICOM_HEADER_JPEGLLESSHIER_P29
vil_dicom_header_type_of< vil_dicom_header_CS >::type image_id_type_
vil_dicom_header_type_of< vil_dicom_header_PN >::type patient_name_
vil_dicom_header_type_of< vil_dicom_header_LT >::type patient_hist_
const char *const VIL_DICOM_HEADER_SHORTSTRING
const vxl_uint_16 VIL_DICOM_HEADER_AQMRACQUISITIONTYPE
const vxl_uint_16 VIL_DICOM_HEADER_RELATIONSHIPGROUP
vil_dicom_header_endian file_endian_
vil_dicom_header_endian endian_
A variable to hold the discovered architecture endian.
const vxl_uint_16 VIL_DICOM_HEADER_IMBITSSTORED
vil_dicom_header_type_of< vil_dicom_header_DS >::type imager_spacing_y_
const vxl_uint_16 VIL_DICOM_HEADER_IMLARGEIMPIXELVALUE
const vxl_uint_16 VIL_DICOM_HEADER_AQCARDIACNUMBEROFIMAGES
vil_dicom_header_type_of< vil_dicom_header_DS >::type inversion_time_
vil_dicom_header_type_of< vil_dicom_header_DA >::type series_date_
vil_dicom_header_endian sys_endian_
const char *const VIL_DICOM_HEADER_CODESTRING
Stream interface for VIL image loaders.
Definition: vil_stream.h:21
vil_dicom_header_type_of< vil_dicom_header_SH >::type sequence_name_
void readPatientElements(short element, int dblock_size, vil_stream &fs)
Method to read the patient details.
vil_dicom_header_type_of< vil_dicom_header_DS >::type echo_time_
const vxl_uint_16 VIL_DICOM_HEADER_IDACCESSIONNUMBER
const vxl_uint_16 VIL_DICOM_HEADER_IDLENGTHTOEND
vil_dicom_header_type_of< vil_dicom_header_US >::type pixel_padding_val_
const vxl_uint_16 VIL_DICOM_HEADER_AQNUMBEROFAVERAGES
vil_dicom_header_type_of< vil_dicom_header_DS >::type slice_location_
const char *const VIL_DICOM_HEADER_JPEGLOSSLESS_P15
void readProcedureElements(short element, int dblock_size, vil_stream &fs)
Method to read the procedure group's details.
const float VIL_DICOM_HEADER_DEFAULTSIZE_FLOAT
vil_dicom_header_endian systemEndian(void)
Return the current system endian.
const vxl_uint_16 VIL_DICOM_HEADER_IDACQUISITIONTIME
const vxl_uint_16 VIL_DICOM_HEADER_DELIMITERGROUP
vil_dicom_header_type_of< vil_dicom_header_US >::type high_bit_
const short VIL_DICOM_HEADER_UNSPECIFIED
const vxl_uint_16 VIL_DICOM_HEADER_AQPHASEENCODINGDIRECTION
const vxl_uint_16 VIL_DICOM_HEADER_AQSLICETHICKNESS
const vxl_uint_16 VIL_DICOM_HEADER_ACQUISITIONGROUP
vil_dicom_header_info readHeader(vil_stream &fs)
Read the dicom header into a header struct.
vil_dicom_header_type_of< vil_dicom_header_DA >::type acquisition_date_
const vxl_uint_16 VIL_DICOM_HEADER_AQPIXELBANDWIDTH
DICOM information read from the header.
const vxl_uint_16 VIL_DICOM_HEADER_IMWINDOWCENTER
const vxl_uint_16 VIL_DICOM_HEADER_MFTRANSFERSYNTAX
const vxl_uint_16 VIL_DICOM_HEADER_IDENTIFYINGGROUP
const char *const VIL_DICOM_HEADER_OTHERBYTE
const vxl_uint_16 VIL_DICOM_HEADER_AQTRIGGERWINDOW
const vxl_uint_16 VIL_DICOM_HEADER_PIPATIENTID
const char *const VIL_DICOM_HEADER_JPEGFULLPROG_P10_12
vil_dicom_header_type_of< vil_dicom_header_TM >::type image_time_
const vxl_uint_16 VIL_DICOM_HEADER_RSFRAMEOFREFERENCEUID
const vxl_uint_16 VIL_DICOM_HEADER_AQIMAGERPIXELSPACING
vil_dicom_header_type_of< vil_dicom_header_US >::type size_z_
const vxl_uint_16 VIL_DICOM_HEADER_IDSOPCLASSID
const char *const VIL_DICOM_HEADER_IMPLICITLITTLE
const char *const VIL_DICOM_HEADER_LONGSTRING
vil_dicom_header_type_of< vil_dicom_header_IS >::type image_number_
vil_dicom_header_type_of< vil_dicom_header_CS >::type patient_sex_
const char *const VIL_DICOM_HEADER_RLELOSSLESS
const vxl_uint_16 VIL_DICOM_HEADER_IMHIGHBIT
vil_dicom_header_type_of< vil_dicom_header_US >::type large_im_pix_val_
vil_dicom_header_type_of< vil_dicom_header_US >::type pix_samps_
vil_dicom_header_type_of< vil_dicom_header_SH >::type accession_number_
const vxl_uint_16 VIL_DICOM_HEADER_DLSEQDELIMITATIONITEM
vxl_uint_16 shortSwap(vxl_uint_16 short_in)
Method to byte swap an unsigned short int if necessary.
vil_dicom_header_type_of< vil_dicom_header_DA >::type image_date_
const vxl_uint_16 VIL_DICOM_HEADER_IDACQUISITIONDATE
vil_dicom_header_type_of< vil_dicom_header_TM >::type study_time_
const float VIL_DICOM_HEADER_DEFAULTSLOPE
vil_dicom_header_type_of< vil_dicom_header_UI >::type ser_ins_uid_
const vxl_uint_16 VIL_DICOM_HEADER_METAFILEGROUP
const vxl_uint_16 VIL_DICOM_HEADER_IDSOPINSTANCEID
const char *const VIL_DICOM_HEADER_SIGNEDSHORT
void readNSPhilipsElements(short element, int dblock_size, vil_stream &fs)
Method to read the (non-standard, private) Philips group details.
const vxl_uint_16 VIL_DICOM_HEADER_RSSERIESNUMBER
vil_dicom_header_type_of< vil_dicom_header_DS >::type pixel_bandwidth_
const vxl_uint_16 VIL_DICOM_HEADER_IMSAMPLESPERPIXEL
vil_dicom_header_type_of< vil_dicom_header_US >::type pix_rep_
vil_dicom_header_type file_type_
const vxl_uint_16 VIL_DICOM_HEADER_AQANGIOFLAG
void readDelimiterElements(short element, int dblock_size, vil_stream &fs)
Method to read the delimiter group's details.
vil_dicom_header_endian file_endian_
A variable to hold the current header file's endian.
const vxl_uint_16 VIL_DICOM_HEADER_IDSPECIFICCHARACTER
const vxl_uint_16 VIL_DICOM_HEADER_AQHEARTRATE
vil_dicom_header_type_of< vil_dicom_header_DS >::type mag_field_strength_
vil_dicom_header_type_of< vil_dicom_header_DS >::type window_width_
vil_dicom_header_info lastHeader(void)
Method to return the last struct of header info set.
const vxl_uint_16 VIL_DICOM_HEADER_IDSTUDYDATE
const vxl_uint_16 VIL_DICOM_HEADER_IDOPERATORNAME
const vxl_uint_16 VIL_DICOM_HEADER_IMCOLUMNS
vxl_uint_32 intSwap(vxl_uint_32 int_in)
Method to byte swap an unsigned int if necessary.
vil_dicom_header_type_of< vil_dicom_header_DS >::type repetition_time_
const vxl_uint_16 VIL_DICOM_HEADER_AQPROTOCOLNAME
vil_dicom_header_type_of< vil_dicom_header_IS >::type trigger_window_
const vxl_uint_16 VIL_DICOM_HEADER_RSIMAGESINACQUISITION
vil_dicom_header_image_type
Encapsulated image types.
const vxl_uint_16 VIL_DICOM_HEADER_IDINSTITUTIONNAME
vil_dicom_header_type_of< vil_dicom_header_PN >::type ref_phys_name_
const vxl_uint_16 VIL_DICOM_HEADER_IDSTUDYDESCRIPTION
const char *const VIL_DICOM_HEADER_UNSIGNEDSHORT
void readImageElements(short element, int dblock_size, vil_stream &fs)
Method to read the image group's details.
const vxl_uint_16 VIL_DICOM_HEADER_RSSTUDYINSTANCEUID
const vxl_uint_32 VIL_DICOM_HEADER_ALLSET
vil_dicom_header_type determineFileType(vil_stream &fs)
Method to determine the file type.
const vxl_uint_16 VIL_DICOM_HEADER_AQSLICESPACING
const char *const VIL_DICOM_HEADER_JPEGSPECHIER_P20_22
DICOM Header reader and writer.
const vxl_uint_16 VIL_DICOM_HEADER_IMBITSALLOCATED
bool convertValueRepresentation(unsigned int &dblock_size, vil_stream &ifs)
Method to convert the Value Representation (VR) (if it exists).
virtual bool ok() const =0
Return false if the stream is broken.
const vxl_uint_16 VIL_DICOM_HEADER_RSSTUDYID
vil_dicom_header_type_of< vil_dicom_header_SH >::type study_id_
const vxl_uint_16 VIL_DICOM_HEADER_AQSAR
const vxl_uint_16 VIL_DICOM_HEADER_IMWINDOWWIDTH
const vxl_uint_16 VIL_DICOM_HEADER_IMAGEGROUP
vil_dicom_header_type_of< vil_dicom_header_DS >::type philips_private_slope_
vil_dicom_header_type_of< vil_dicom_header_LO >::type study_desc_
const vxl_uint_16 VIL_DICOM_HEADER_IDATTENDINGPHYSICIAN
const vxl_uint_16 VIL_DICOM_HEADER_IDSERIESDESCRIPTION
const vxl_uint_16 VIL_DICOM_HEADER_AQSCANNINGSEQUENCE
const vxl_uint_16 VIL_DICOM_HEADER_AQRECONTRUCTIONDIAMETER
const vxl_uint_16 VIL_DICOM_HEADER_IMSMALLIMPIXELVALUE
const vxl_uint_16 VIL_DICOM_HEADER_PIPATIENTSEX
vil_dicom_header_type_of< vil_dicom_header_ST >::type institution_addr_
vxl_int_32 vil_streampos
Definition: vil_stream.h:16
vil_dicom_header_type_of< vil_dicom_header_LO >::type model_name_
const vxl_uint_16 VIL_DICOM_HEADER_RSAQUISITIONNUMBER
const char *const VIL_DICOM_HEADER_INTEGERSTRING
const vxl_uint_16 VIL_DICOM_HEADER_PRREALWORLDVALUEINTERCEPT
vil_dicom_header_type_of< vil_dicom_header_DS >::type philips_private_intercept_
const vxl_uint_16 VIL_DICOM_HEADER_AQECHOTRAINLENGTH
const char *const VIL_DICOM_HEADER_OTHERWORD
const char *const VIL_DICOM_HEADER_UNIQUEIDENTIFIER
vil_dicom_header_type_of< vil_dicom_header_DS >::type slice_thickness_
vil_dicom_header_type_of< vil_dicom_header_CS >::type mr_acq_type_
vil_dicom_header_type_of< vil_dicom_header_DA >::type patient_dob_
vil_dicom_header_type_of< vil_dicom_header_UI >::type frame_of_ref_
vil_dicom_header_type_of< vil_dicom_header_FD >::type real_world_value_intercept_
const vxl_uint_16 VIL_DICOM_HEADER_AQECHONUMBERS
const vxl_uint_16 VIL_DICOM_HEADER_PIPATIENTNAME
vil_dicom_header_type_of< vil_dicom_header_CS >::type scanning_seq_
const vxl_uint_16 VIL_DICOM_HEADER_IMPLANES
const vxl_uint_16 VIL_DICOM_HEADER_IDREFERRINGPHYSICIAN
const vxl_uint_16 VIL_DICOM_HEADER_IMRESCALESLOPE
const vxl_uint_16 VIL_DICOM_HEADER_IMRESCALEINTERCEPT
vil_dicom_header_image_type imageType(void)
Return any encapsulated image type.
const char *const VIL_DICOM_HEADER_JPEGEXTENDED_P3_5
void readHeaderElements(vil_stream &fs)
Method to read the elements from the header.
const char *const VIL_DICOM_HEADER_DECIMALSTRING
const char *const VIL_DICOM_HEADER_DATE
const char *const VIL_DICOM_HEADER_JPEGSPECHIER_P21_23
const vxl_uint_16 VIL_DICOM_HEADER_IMPIXELREPRESENTATION
const char *const VIL_DICOM_HEADER_JPEGDEFLOSSY_P2_4
const vxl_uint_16 VIL_DICOM_HEADER_AQMAGNETICFIELDSTRENGTH
const char *const VIL_DICOM_HEADER_TIME
vil_dicom_header_type_of< vil_dicom_header_DS >::type res_intercept_
const char *const VIL_DICOM_HEADER_JPEGBASELINE_P1
vil_dicom_header_type_of< vil_dicom_header_UI >::type stud_ins_uid_
vil_dicom_header_type_of< vil_dicom_header_DS >::type spacing_y_
constexpr unsigned VIL_DICOM_HEADER_MAXHEADERSIZE
const char *const VIL_DICOM_HEADER_SHORTTEXT
const vxl_uint_16 VIL_DICOM_HEADER_IDMANUFACTURERMODEL
vil_dicom_header_type_of< vil_dicom_header_SH >::type receiving_coil_
vil_dicom_header_type_of< vil_dicom_header_DS >::type spacing_slice_
void vil_dicom_header_print(std::ostream &os, const vil_dicom_header_info &s)
vil_dicom_header_type_of< vil_dicom_header_CS >::type pat_orient_
vil_dicom_header_type_of< vil_dicom_header_US >::type exposedarea_x_
vil_dicom_header_type_of< vil_dicom_header_UI >::type sop_in_uid_
vil_dicom_header_type_of< vil_dicom_header_CS >::type patient_pos_
vil_dicom_header_type_of< vil_dicom_header_CS >::type scan_options_
const char *const VIL_DICOM_HEADER_DATETIME
const char *const VIL_DICOM_HEADER_ATTRIBUTETAG
vil_dicom_header_type_of< vil_dicom_header_CS >::type photo_interp_
vil_dicom_header_image_type image_type_
A variable to hole the current encapsulate file type (if any).
const char *const VIL_DICOM_HEADER_SEQUENCE
const vxl_uint_16 VIL_DICOM_HEADER_IDSTATIONNAME
vil_dicom_header_type_of< vil_dicom_header_LO >::type software_vers_
const char *const VIL_DICOM_HEADER_PERSONNAME
vil_dicom_header_type_of< vil_dicom_header_LO >::type protocol_name_
const char *const VIL_DICOM_HEADER_UNSIGNEDLONG
void charSwap(char *char_in, int val_size)
Method to swap a number inside a char array.
const char *const VIL_DICOM_HEADER_EXPLICITBIG
const vxl_uint_16 VIL_DICOM_HEADER_RSPATIENTORIENTATION
vil_dicom_header_type_of< vil_dicom_header_TM >::type acquisition_time_
const char *const VIL_DICOM_HEADER_SIGNEDLONG
vil_dicom_header_type_of< vil_dicom_header_DS >::type imager_spacing_x_
vil_dicom_header_type_of< vil_dicom_header_TM >::type series_time_
vil_dicom_header_type_of< vil_dicom_header_DA >::type study_date_
const vxl_uint_16 VIL_DICOM_HEADER_AQREPETITIONTIME
const vxl_uint_16 VIL_DICOM_HEADER_PATIENTINFOGROUP
vil_dicom_header_type_of< vil_dicom_header_LO >::type pos_ref_ind_
const vxl_uint_16 VIL_DICOM_HEADER_AQINVERSIONTIME
const vxl_uint_16 VIL_DICOM_HEADER_RSSLICELOCATION
vil_dicom_header_type_of< vil_dicom_header_DS >::type patient_weight_
vil_dicom_header_type_of< vil_dicom_header_US >::type stored_bits_
vil_dicom_header_info last_read_
Holds the info from the last header read.