00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <vil/vil_config.h>
00012 #if HAS_DCMTK
00013
00014 #include "vil_dicom_header.h"
00015 #include <vil/vil_stream.h>
00016 #include <vcl_iostream.h>
00017 #include <vcl_cstdlib.h>
00018
00019
00020
00021 void
00022 vil_dicom_header_info_clear( vil_dicom_header_info& info )
00023 {
00024
00025
00026
00027 info.header_valid_ = false;
00028 info.file_type_ = VIL_DICOM_HEADER_DTUNKNOWN;
00029 info.file_endian_ = VIL_DICOM_HEADER_DEUNKNOWN;
00030 info.sys_endian_ = VIL_DICOM_HEADER_DEUNKNOWN;
00031 info.image_type_ = VIL_DICOM_HEADER_DITUNKNOWN;
00032 info.image_id_type_ = "";
00033 info.sop_cl_uid_ = "";
00034 info.sop_in_uid_ = "";
00035 info.study_date_ = VIL_DICOM_HEADER_UNSPECIFIED;
00036 info.series_date_ = VIL_DICOM_HEADER_UNSPECIFIED;
00037 info.acquisition_date_ = VIL_DICOM_HEADER_UNSPECIFIED;
00038 info.image_date_ = VIL_DICOM_HEADER_UNSPECIFIED;
00039 info.study_time_ = VIL_DICOM_HEADER_UNSPECIFIED;
00040 info.series_time_ = VIL_DICOM_HEADER_UNSPECIFIED;
00041 info.acquisition_time_ = VIL_DICOM_HEADER_UNSPECIFIED;
00042 info.image_time_ = VIL_DICOM_HEADER_UNSPECIFIED;
00043 info.accession_number_ = "";
00044 info.modality_ = "";
00045 info.manufacturer_ = "";
00046 info.institution_name_ = "";
00047 info.institution_addr_ = "";
00048 info.ref_phys_name_ = "";
00049 info.station_name_ = "";
00050 info.study_desc_ = "";
00051 info.att_phys_name_ = "";
00052 info.operator_name_ = "";
00053 info.model_name_ = "";
00054
00055
00056 info.patient_name_ = "";
00057 info.patient_id_ = "";
00058 info.patient_dob_ = VIL_DICOM_HEADER_UNSPECIFIED;
00059 info.patient_sex_ = "";
00060 info.patient_age_ = "";
00061 info.patient_weight_ = VIL_DICOM_HEADER_UNSPECIFIED;
00062 info.patient_hist_ = "";
00063
00064
00065 info.scanning_seq_ = "";
00066 info.sequence_var_ = "";
00067 info.scan_options_ = "";
00068 info.mr_acq_type_ = "";
00069 info.sequence_name_ = "";
00070 info.angio_flag_ = "";
00071 info.slice_thickness_ = VIL_DICOM_HEADER_UNSPECIFIED;
00072 info.repetition_time_ = VIL_DICOM_HEADER_UNSPECIFIED;
00073 info.echo_time_ = VIL_DICOM_HEADER_UNSPECIFIED;
00074 info.inversion_time_ = VIL_DICOM_HEADER_UNSPECIFIED;
00075 info.number_of_averages_ = VIL_DICOM_HEADER_UNSPECIFIED;
00076 info.echo_numbers_ = VIL_DICOM_HEADER_UNSPECIFIED;
00077 info.mag_field_strength_ = VIL_DICOM_HEADER_UNSPECIFIED;
00078 info.echo_train_length_ = VIL_DICOM_HEADER_UNSPECIFIED;
00079 info.pixel_bandwidth_ = VIL_DICOM_HEADER_UNSPECIFIED;
00080 info.software_vers_ = "";
00081 info.protocol_name_ = "";
00082 info.heart_rate_ = VIL_DICOM_HEADER_UNSPECIFIED;
00083 info.card_num_images_ = VIL_DICOM_HEADER_UNSPECIFIED;
00084 info.trigger_window_ = VIL_DICOM_HEADER_UNSPECIFIED;
00085 info.reconst_diameter_ = VIL_DICOM_HEADER_UNSPECIFIED;
00086 info.receiving_coil_ = "";
00087 info.phase_enc_dir_ = "";
00088 info.flip_angle_ = VIL_DICOM_HEADER_UNSPECIFIED;
00089 info.sar_ = VIL_DICOM_HEADER_UNSPECIFIED;
00090 info.patient_pos_ = "";
00091
00092
00093 info.stud_ins_uid_= "";
00094 info.ser_ins_uid_ = "";
00095 info.study_id_ = "";
00096 info.series_number_ = VIL_DICOM_HEADER_UNSPECIFIED;
00097 info.acquisition_number_ = VIL_DICOM_HEADER_UNSPECIFIED;
00098 info.image_number_ = VIL_DICOM_HEADER_UNSPECIFIED;
00099 info.pat_orient_ = "";
00100 info.image_pos_.clear();
00101 info.image_orient_.clear();
00102 info.frame_of_ref_ = "";
00103 info.images_in_acq_ = VIL_DICOM_HEADER_UNSPECIFIED;
00104 info.pos_ref_ind_ = "";
00105 info.slice_location_ = VIL_DICOM_HEADER_UNSPECIFIED;
00106
00107
00108 info.pix_samps_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00109 info.photo_interp_ = "";
00110 info.size_x_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00111 info.size_y_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00112 info.size_z_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00113 info.high_bit_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00114 info.small_im_pix_val_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00115 info.large_im_pix_val_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00116 info.pixel_padding_val_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00117 info.window_centre_ = VIL_DICOM_HEADER_UNSPECIFIED;
00118 info.window_width_ = VIL_DICOM_HEADER_UNSPECIFIED;
00119
00120
00121 info.spacing_x_ = VIL_DICOM_HEADER_DEFAULTSIZE_FLOAT;
00122 info.spacing_y_ = VIL_DICOM_HEADER_DEFAULTSIZE_FLOAT;
00123 info.spacing_slice_ = VIL_DICOM_HEADER_DEFAULTSIZE_FLOAT;
00124 info.res_intercept_ = VIL_DICOM_HEADER_DEFAULTINTERCEPT;
00125 info.res_slope_ = VIL_DICOM_HEADER_DEFAULTSLOPE;
00126 info.pix_rep_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00127 info.stored_bits_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00128 info.allocated_bits_ = VIL_DICOM_HEADER_UNSPECIFIED_UNSIGNED;
00129 }
00130
00131
00132
00133
00134
00135 vil_dicom_header_format::vil_dicom_header_format() :
00136 info_valid_(false),
00137 file_endian_(VIL_DICOM_HEADER_DEUNKNOWN),
00138 image_type_(VIL_DICOM_HEADER_DITUNKNOWN)
00139 {
00140
00141 endian_ = calculateEndian();
00142 }
00143
00144
00145
00146 vil_dicom_header_format::~vil_dicom_header_format()
00147 {
00148
00149 }
00150
00151
00152
00153 bool vil_dicom_header_format::isDicomFormat(vil_stream &fs)
00154 {
00155 vil_dicom_header_type dtype;
00156
00157 dtype = determineFileType(fs);
00158
00159 return dtype!=VIL_DICOM_HEADER_DTUNKNOWN;
00160 }
00161
00162
00163
00164 vil_dicom_header_info vil_dicom_header_format::readHeader(vil_stream &fs)
00165 {
00166 vil_dicom_header_type dtype;
00167
00168
00169 clearInfo();
00170
00171 dtype = determineFileType(fs);
00172
00173 if (dtype != VIL_DICOM_HEADER_DTUNKNOWN)
00174 {
00175 last_read_.file_type_ = dtype;
00176 last_read_.sys_endian_ = systemEndian();
00177
00178 if (dtype == VIL_DICOM_HEADER_DTPART10)
00179 {
00180 file_endian_ = determineMetaInfo(fs);
00181 }
00182
00183 last_read_.file_endian_ = fileEndian();
00184 last_read_.image_type_ = imageType();
00185
00186 readHeaderElements(fs);
00187
00188 info_valid_ = true;
00189 }
00190 else
00191 {
00192 vcl_cerr<<"Unknown file type - not a DICOM file...\n"
00193 <<"File header not read\n";
00194 }
00195 return last_read_;
00196 }
00197
00198
00199
00200 vil_dicom_header_info vil_dicom_header_format::lastHeader(void)
00201 {
00202 return last_read_;
00203 }
00204
00205
00206
00207 bool vil_dicom_header_format::headerValid(void)
00208 {
00209 return info_valid_;
00210 }
00211
00212
00213
00214 vil_dicom_header_endian vil_dicom_header_format::systemEndian(void)
00215 {
00216 return endian_;
00217 }
00218
00219
00220
00221 vil_dicom_header_endian vil_dicom_header_format::fileEndian(void)
00222 {
00223 return file_endian_;
00224 }
00225
00226
00227
00228 vil_dicom_header_image_type vil_dicom_header_format::imageType(void)
00229 {
00230 return image_type_;
00231 }
00232
00233
00234
00235 vil_dicom_header_type vil_dicom_header_format::determineFileType(vil_stream &fs)
00236 {
00237 vil_dicom_header_type result = VIL_DICOM_HEADER_DTUNKNOWN;
00238
00239
00240
00241 if (fs.ok())
00242 {
00243
00244
00245
00246
00247
00248 char dicm_read[5];
00249 vcl_string dicm_test;
00250
00251
00252 fs.seek(128);
00253 fs.read(dicm_read,4);
00254 dicm_read[4]=0;
00255 dicm_test=dicm_read;
00256
00257 if (dicm_test == "DICM")
00258 {
00259 result = VIL_DICOM_HEADER_DTPART10;
00260 }
00261 else
00262 {
00263
00264
00265 fs.seek(0);
00266 fs.read(dicm_read,4);
00267 dicm_read[4]=0;
00268 dicm_test=dicm_read;
00269
00270 if (dicm_test == "DICM")
00271 {
00272 result = VIL_DICOM_HEADER_DTPART10;
00273 }
00274 else
00275 {
00276
00277
00278 int num_tries = 0;
00279 bool known = false;
00280 vil_dicom_header_endian old_endian = file_endian_;
00281 file_endian_ = VIL_DICOM_HEADER_DEBIGENDIAN;
00282
00283 while (num_tries < 2 && !known)
00284 {
00285
00286
00287 fs.seek(0);
00288 vxl_uint_16 group, element;
00289 vxl_uint_32 data_block_size, num_elements;
00290
00291 fs.read(&group, sizeof(vxl_uint_16));
00292 group = shortSwap(group);
00293 fs.read(&element, sizeof(vxl_uint_16));
00294 element = shortSwap(element);
00295 fs.read(&data_block_size, sizeof(vxl_uint_32));
00296 data_block_size = intSwap(data_block_size);
00297 if (data_block_size > 0x1000000) {
00298 vcl_cerr<< __FILE__ << ": " << __LINE__ << " : WARNING:\n"
00299 <<"data_block_size=" << data_block_size << " is most probably too large\n";
00300 break;
00301 }
00302
00303 num_elements = 0;
00304
00305 while (group < VIL_DICOM_HEADER_IDENTIFYINGGROUP &&
00306 num_elements < VIL_DICOM_HEADER_MAXHEADERSIZE &&
00307 fs.ok())
00308 {
00309
00310
00311 fs.seek(data_block_size + fs.tell());
00312
00313 fs.read(&group, sizeof(vxl_uint_16));
00314 group = shortSwap(group);
00315 fs.read(&element, sizeof(vxl_uint_16));
00316 element = shortSwap(element);
00317 fs.read(&data_block_size, sizeof(vxl_uint_32));
00318 data_block_size = intSwap(data_block_size);
00319 if (data_block_size > 0x1000000) {
00320 vcl_cerr<< __FILE__ << ": " << __LINE__ << " : WARNING:\n"
00321 <<"data_block_size=" << data_block_size << " is most probably too large\n";
00322 break;
00323 }
00324
00325 num_elements++;
00326 }
00327
00328
00329
00330 if (group == VIL_DICOM_HEADER_IDENTIFYINGGROUP)
00331 {
00332
00333 if (element == VIL_DICOM_HEADER_IDGROUPLENGTH &&
00334 data_block_size == 4)
00335 {
00336
00337 fs.seek(0);
00338 result = VIL_DICOM_HEADER_DTNON_PART10;
00339 known = true;
00340 }
00341
00342 else if (element == VIL_DICOM_HEADER_IDIMAGETYPE ||
00343 element == VIL_DICOM_HEADER_IDLENGTHTOEND ||
00344 element == VIL_DICOM_HEADER_IDSPECIFICCHARACTER)
00345 {
00346
00347 fs.seek(0);
00348 result = VIL_DICOM_HEADER_DTNON_PART10;
00349 known = true;
00350 }
00351 }
00352
00353 if (!known)
00354 {
00355 file_endian_ = VIL_DICOM_HEADER_DELITTLEENDIAN;
00356 }
00357
00358 num_tries++;
00359 }
00360
00361 if (!known)
00362 {
00363 file_endian_ = old_endian;
00364 }
00365 }
00366 }
00367 }
00368 else
00369 {
00370 vcl_cerr << "File not open for reading:\n"
00371 << "vil_dicom_header_format::determineFileType()\n";
00372 }
00373
00374 return result;
00375 }
00376
00377
00378
00379 void vil_dicom_header_format::readHeaderElements(vil_stream &fs)
00380 {
00381 vxl_uint_16 group, element;
00382 vxl_uint_32 data_block_size;
00383 vcl_cerr << "vil_dicom_header_format::readHeaderElements - Deprecated function called - use the DCMTK code instead!";
00384 vcl_abort();
00385
00386
00387 fs.read(&group, sizeof(vxl_uint_16));
00388 fs.read(&element, sizeof(vxl_uint_16));
00389
00390
00391 group = shortSwap(group);
00392 element = shortSwap(element);
00393
00394
00395
00396 while (fs.ok() && !pixelDataFound(group, element))
00397 {
00398 if (sizeof(vxl_uint_32) != fs.read(&data_block_size, sizeof(vxl_uint_32)))
00399 break;
00400 data_block_size = intSwap(data_block_size);
00401 if (data_block_size > 0x1000000) {
00402 vcl_cerr<< __FILE__ << ": " << __LINE__ << " : WARNING:\n"
00403 <<"data_block_size=" << data_block_size << " is most probably too large\n";
00404 break;
00405 }
00406 convertValueRepresentation(data_block_size, fs);
00407
00408 switch (group)
00409 {
00410
00411 case VIL_DICOM_HEADER_IDENTIFYINGGROUP:
00412 readIdentifyingElements(element, data_block_size, fs);
00413 break;
00414
00415
00416 case VIL_DICOM_HEADER_PATIENTINFOGROUP:
00417 readPatientElements(element, data_block_size, fs);
00418 break;
00419
00420 case VIL_DICOM_HEADER_ACQUISITIONGROUP:
00421 readAcquisitionElements(element, data_block_size, fs);
00422 break;
00423
00424 case VIL_DICOM_HEADER_RELATIONSHIPGROUP:
00425 readRelationshipElements(element, data_block_size, fs);
00426 break;
00427
00428 case VIL_DICOM_HEADER_IMAGEGROUP:
00429 readImageElements(element, data_block_size, fs);
00430 break;
00431
00432 case VIL_DICOM_HEADER_DELIMITERGROUP:
00433 readDelimiterElements(element, data_block_size, fs);
00434 break;
00435
00436
00437 default:
00438 fs.seek(data_block_size + fs.tell());
00439 break;
00440 }
00441
00442
00443 fs.read(&group, sizeof(vxl_uint_16));
00444 fs.read(&element, sizeof(vxl_uint_16));
00445
00446
00447 group = shortSwap(group);
00448 element = shortSwap(element);
00449 }
00450
00451
00452
00453 if (sizeof(vxl_uint_32) != fs.read(&data_block_size, sizeof(vxl_uint_32)))
00454 return;
00455 data_block_size = intSwap(data_block_size);
00456 if (data_block_size > 0x1000000)
00457 vcl_cerr << __FILE__ << ": " << __LINE__ << " : WARNING\n"
00458 <<"data_block_size=" << data_block_size << " is most probably too large\n";
00459 else
00460 convertValueRepresentation(data_block_size, fs);
00461 }
00462
00463
00464
00465
00466 #define CASE(X,M,F) \
00467 case X : \
00468 data_p = new char[dblock_size+1]; \
00469 if (data_p) \
00470 { \
00471 fs.read(data_p,dblock_size); \
00472 data_p[dblock_size]=0; \
00473 last_read_.M = F(data_p); \
00474 } \
00475 break
00476
00477 #define CASE_SWP(X,M) \
00478 case X : \
00479 data_p = new char[dblock_size+1]; \
00480 if (data_p) \
00481 { \
00482 fs.read(data_p,dblock_size); \
00483 data_p[dblock_size]=0; \
00484 charSwap(data_p, sizeof(vxl_uint_16)); \
00485 last_read_.M = *((vxl_uint_16*)data_p); \
00486 } \
00487 break
00488
00489 void vil_dicom_header_format::readIdentifyingElements(short element,
00490 int dblock_size,
00491 vil_stream &fs)
00492 {
00493
00494 char *data_p = 0;
00495
00496
00497 switch ((vxl_uint_16)element)
00498 {
00499 CASE(VIL_DICOM_HEADER_IDIMAGETYPE, image_id_type_, (char *));
00500 CASE(VIL_DICOM_HEADER_IDSOPCLASSID, sop_cl_uid_, (char *));
00501 CASE(VIL_DICOM_HEADER_IDSOPINSTANCEID, sop_in_uid_, (char *));
00502 CASE(VIL_DICOM_HEADER_IDSTUDYDATE, study_date_,vcl_atol);
00503 CASE(VIL_DICOM_HEADER_IDSERIESDATE, series_date_,vcl_atol);
00504 CASE(VIL_DICOM_HEADER_IDACQUISITIONDATE, acquisition_date_,vcl_atol);
00505 CASE(VIL_DICOM_HEADER_IDIMAGEDATE, image_date_,vcl_atol);
00506 CASE(VIL_DICOM_HEADER_IDSTUDYTIME, study_time_,(float)vcl_atof);
00507 CASE(VIL_DICOM_HEADER_IDSERIESTIME, series_time_,(float)vcl_atof);
00508 CASE(VIL_DICOM_HEADER_IDACQUISITIONTIME, acquisition_time_,(float)vcl_atof);
00509 CASE(VIL_DICOM_HEADER_IDIMAGETIME, image_time_,(float)vcl_atof);
00510 CASE(VIL_DICOM_HEADER_IDACCESSIONNUMBER, accession_number_, (char *));
00511 CASE(VIL_DICOM_HEADER_IDMODALITY, modality_, (char *));
00512 CASE(VIL_DICOM_HEADER_IDMANUFACTURER, manufacturer_, (char *));
00513 CASE(VIL_DICOM_HEADER_IDINSTITUTIONNAME, institution_name_, (char *));
00514 CASE(VIL_DICOM_HEADER_IDINSTITUTIONADDRESS,institution_addr_, (char *));
00515 CASE(VIL_DICOM_HEADER_IDREFERRINGPHYSICIAN,ref_phys_name_, (char *));
00516 CASE(VIL_DICOM_HEADER_IDSTATIONNAME, station_name_, (char *));
00517 CASE(VIL_DICOM_HEADER_IDSTUDYDESCRIPTION, study_desc_, (char *));
00518 CASE(VIL_DICOM_HEADER_IDSERIESDESCRIPTION, series_desc_, (char *));
00519 CASE(VIL_DICOM_HEADER_IDATTENDINGPHYSICIAN,att_phys_name_, (char *));
00520 CASE(VIL_DICOM_HEADER_IDOPERATORNAME, operator_name_, (char *));
00521 CASE(VIL_DICOM_HEADER_IDMANUFACTURERMODEL, model_name_, (char *));
00522 default:
00523 fs.seek(dblock_size + fs.tell());
00524 break;
00525 }
00526
00527 delete[] data_p;
00528 }
00529
00530
00531
00532 void vil_dicom_header_format::readPatientElements(short element,
00533 int dblock_size,
00534 vil_stream &fs)
00535 {
00536
00537 char *data_p = 0;
00538
00539
00540 switch ((vxl_uint_16)element)
00541 {
00542 CASE(VIL_DICOM_HEADER_PIPATIENTNAME, patient_name_, (char *));
00543 CASE(VIL_DICOM_HEADER_PIPATIENTID, patient_id_, (char *));
00544 CASE(VIL_DICOM_HEADER_PIPATIENTBIRTHDATE,patient_dob_,vcl_atol);
00545 CASE(VIL_DICOM_HEADER_PIPATIENTSEX, patient_sex_, (char *));
00546 CASE(VIL_DICOM_HEADER_PIPATIENTAGE, patient_age_, (char *));
00547 CASE(VIL_DICOM_HEADER_PIPATIENTWEIGHT, patient_weight_,(float)vcl_atof);
00548 CASE(VIL_DICOM_HEADER_PIPATIENTHISTORY, patient_hist_, (char *));
00549 default:
00550 fs.seek(dblock_size + fs.tell());
00551 break;
00552 }
00553
00554 delete[] data_p;
00555 }
00556
00557
00558
00559 void vil_dicom_header_format::readAcquisitionElements(short element,
00560 int dblock_size,
00561 vil_stream &fs)
00562 {
00563
00564 char *data_p = 0;
00565
00566
00567 switch ((vxl_uint_16)element)
00568 {
00569 CASE(VIL_DICOM_HEADER_AQSCANNINGSEQUENCE, scanning_seq_, (char *));
00570 CASE(VIL_DICOM_HEADER_AQSEQUENCEVARIANT, sequence_var_, (char *));
00571 CASE(VIL_DICOM_HEADER_AQSCANOPTIONS, scan_options_, (char *));
00572 CASE(VIL_DICOM_HEADER_AQMRACQUISITIONTYPE, mr_acq_type_, (char *));
00573 CASE(VIL_DICOM_HEADER_AQSEQUENCENAME, sequence_name_, (char *));
00574 CASE(VIL_DICOM_HEADER_AQANGIOFLAG, angio_flag_, (char *));
00575 CASE(VIL_DICOM_HEADER_AQSLICETHICKNESS, slice_thickness_,(float)vcl_atof);
00576 CASE(VIL_DICOM_HEADER_AQREPETITIONTIME, repetition_time_,(float)vcl_atof);
00577 CASE(VIL_DICOM_HEADER_AQECHOTIME, echo_time_,(float)vcl_atof);
00578 CASE(VIL_DICOM_HEADER_AQINVERSIONTIME, inversion_time_,(float)vcl_atof);
00579 CASE(VIL_DICOM_HEADER_AQNUMBEROFAVERAGES, number_of_averages_,(float)vcl_atof);
00580 CASE(VIL_DICOM_HEADER_AQECHONUMBERS, echo_numbers_,vcl_atoi);
00581 CASE(VIL_DICOM_HEADER_AQMAGNETICFIELDSTRENGTH, mag_field_strength_,(float)vcl_atof);
00582 CASE(VIL_DICOM_HEADER_AQSLICESPACING, spacing_slice_,(float)vcl_atof);
00583 CASE(VIL_DICOM_HEADER_AQECHOTRAINLENGTH, echo_train_length_,(int)vcl_atoi);
00584 CASE(VIL_DICOM_HEADER_AQPIXELBANDWIDTH, pixel_bandwidth_,(float)vcl_atof);
00585 CASE(VIL_DICOM_HEADER_AQSOFTWAREVERSION, software_vers_, (char *));
00586 CASE(VIL_DICOM_HEADER_AQPROTOCOLNAME, protocol_name_, (char *));
00587 CASE(VIL_DICOM_HEADER_AQHEARTRATE, heart_rate_,vcl_atoi);
00588 CASE(VIL_DICOM_HEADER_AQCARDIACNUMBEROFIMAGES, card_num_images_,vcl_atoi);
00589 CASE(VIL_DICOM_HEADER_AQTRIGGERWINDOW, trigger_window_,vcl_atoi);
00590 CASE(VIL_DICOM_HEADER_AQRECONTRUCTIONDIAMETER, reconst_diameter_,(float)vcl_atof);
00591 CASE(VIL_DICOM_HEADER_AQRECEIVINGCOIL, receiving_coil_, (char *));
00592 CASE(VIL_DICOM_HEADER_AQPHASEENCODINGDIRECTION,phase_enc_dir_, (char *));
00593 CASE(VIL_DICOM_HEADER_AQFLIPANGLE, flip_angle_,(float)vcl_atof);
00594 CASE(VIL_DICOM_HEADER_AQSAR, sar_,(float)vcl_atof);
00595 CASE(VIL_DICOM_HEADER_AQPATIENTPOSITION, patient_pos_, (char *));
00596 default:
00597 fs.seek(dblock_size + fs.tell());
00598 break;
00599 }
00600
00601 delete[] data_p;
00602 }
00603
00604
00605
00606 void vil_dicom_header_format::readRelationshipElements(short element,
00607 int dblock_size,
00608 vil_stream &fs)
00609 {
00610
00611 char *data_p = 0;
00612
00613
00614 switch ((vxl_uint_16)element)
00615 {
00616 CASE(VIL_DICOM_HEADER_RSSTUDYINSTANCEUID, stud_ins_uid_, (char *));
00617 CASE(VIL_DICOM_HEADER_RSSERIESINSTANCEUID, ser_ins_uid_, (char *));
00618 CASE(VIL_DICOM_HEADER_RSSTUDYID, study_id_, (char *));
00619 CASE(VIL_DICOM_HEADER_RSSERIESNUMBER, series_number_,vcl_atoi);
00620 CASE(VIL_DICOM_HEADER_RSAQUISITIONNUMBER, acquisition_number_,vcl_atoi);
00621 CASE(VIL_DICOM_HEADER_RSIMAGENUMBER, image_number_,vcl_atoi);
00622 CASE(VIL_DICOM_HEADER_RSPATIENTORIENTATION, pat_orient_, (char *));
00623
00624
00625 CASE(VIL_DICOM_HEADER_RSFRAMEOFREFERENCEUID,frame_of_ref_, (char *));
00626 CASE(VIL_DICOM_HEADER_RSIMAGESINACQUISITION,images_in_acq_,vcl_atoi);
00627 CASE(VIL_DICOM_HEADER_RSPOSITIONREFERENCE, pos_ref_ind_, (char *));
00628 CASE(VIL_DICOM_HEADER_RSSLICELOCATION, slice_location_,(float) vcl_atof);
00629 default:
00630 fs.seek(dblock_size + fs.tell());
00631 break;
00632 }
00633
00634 delete[] data_p;
00635 }
00636
00637
00638
00639
00640 void vil_dicom_header_format::readImageElements(short element,
00641 int dblock_size,
00642 vil_stream &fs)
00643 {
00644
00645 char *data_p = 0;
00646
00647
00648 switch ((vxl_uint_16)element)
00649 {
00650 CASE_SWP(VIL_DICOM_HEADER_IMSAMPLESPERPIXEL, pix_samps_);
00651 CASE(VIL_DICOM_HEADER_IMPHOTOMETRICINTERP, photo_interp_, (char *));
00652 CASE_SWP(VIL_DICOM_HEADER_IMROWS, size_y_);
00653 CASE_SWP(VIL_DICOM_HEADER_IMCOLUMNS, size_x_);
00654 CASE_SWP(VIL_DICOM_HEADER_IMPLANES, size_z_);
00655 CASE_SWP(VIL_DICOM_HEADER_IMBITSALLOCATED, allocated_bits_);
00656 CASE_SWP(VIL_DICOM_HEADER_IMBITSSTORED, stored_bits_);
00657 CASE_SWP(VIL_DICOM_HEADER_IMHIGHBIT, high_bit_);
00658 CASE_SWP(VIL_DICOM_HEADER_IMPIXELREPRESENTATION,pix_rep_);
00659 CASE_SWP(VIL_DICOM_HEADER_IMSMALLIMPIXELVALUE, small_im_pix_val_);
00660 CASE_SWP(VIL_DICOM_HEADER_IMLARGEIMPIXELVALUE, large_im_pix_val_);
00661 CASE_SWP(VIL_DICOM_HEADER_IMPIXELPADDINGVALUE, pixel_padding_val_);
00662 CASE(VIL_DICOM_HEADER_IMWINDOWCENTER, window_centre_,(float) vcl_atof);
00663 CASE(VIL_DICOM_HEADER_IMWINDOWWIDTH, window_width_,(float) vcl_atof);
00664 CASE(VIL_DICOM_HEADER_IMRESCALEINTERCEPT, res_intercept_,(float) vcl_atof);
00665 CASE(VIL_DICOM_HEADER_IMRESCALESLOPE, res_slope_,(float) vcl_atof);
00666 case VIL_DICOM_HEADER_IMPIXELSPACING :
00667 data_p = new char[dblock_size+1];
00668 if (data_p)
00669 {
00670 fs.read(data_p,dblock_size);
00671 data_p[dblock_size]=0;
00672 last_read_.spacing_x_ = (float) vcl_atof(data_p);
00673
00674
00675
00676 char gone = 'x';
00677 while (gone != 0 && gone != '\\')
00678 {
00679 gone = data_p[0];
00680 for (int i=0; i<dblock_size; i++)
00681 data_p[i] = data_p[i+1];
00682 }
00683 if (gone == '\\')
00684 last_read_.spacing_y_ = (float) vcl_atof(data_p);
00685 else
00686 last_read_.spacing_y_ = (float) last_read_.spacing_x_;
00687 }
00688 break;
00689
00690 default:
00691 fs.seek(dblock_size + fs.tell());
00692 break;
00693 }
00694
00695 delete[] data_p;
00696 }
00697
00698
00699
00700 void vil_dicom_header_format::readDelimiterElements(short element,
00701 int dblock_size,
00702 vil_stream &fs)
00703 {
00704
00705 switch ((vxl_uint_16)element)
00706 {
00707 case VIL_DICOM_HEADER_DLITEM:
00708 case VIL_DICOM_HEADER_DLITEMDELIMITATIONITEM:
00709 case VIL_DICOM_HEADER_DLSEQDELIMITATIONITEM:
00710
00711 break;
00712
00713 default:
00714 fs.seek(dblock_size + fs.tell());
00715 break;
00716 }
00717 }
00718
00719
00720
00721 bool vil_dicom_header_format::convertValueRepresentation(unsigned int &dblock_size,
00722 vil_stream &fs)
00723 {
00724 bool result = false;
00725 vcl_string first, last;
00726 char temp[3];
00727
00728
00729 union int_char
00730 {
00731 vxl_uint_32 int_val;
00732 char char_val[4];
00733 } conv_dblock;
00734
00735 if (last_read_.file_type_ != VIL_DICOM_HEADER_DTUNKNOWN)
00736 {
00737 conv_dblock.int_val = dblock_size;
00738
00739
00740
00741 temp[0] = conv_dblock.char_val[0];
00742 temp[1] = conv_dblock.char_val[1];
00743 temp[2] = 0;
00744
00745 first = temp;
00746
00747 temp[0] = conv_dblock.char_val[3];
00748 temp[1] = conv_dblock.char_val[2];
00749
00750 last = temp;
00751
00752
00753 if (first == VIL_DICOM_HEADER_SEQUENCE || last == VIL_DICOM_HEADER_SEQUENCE)
00754 {
00755 fs.read(&dblock_size, sizeof(int));
00756 dblock_size = 0;
00757 result = true;
00758 }
00759 else if (first == VIL_DICOM_HEADER_OTHERBYTE ||
00760 first == VIL_DICOM_HEADER_OTHERWORD ||
00761 last == VIL_DICOM_HEADER_OTHERBYTE ||
00762 last == VIL_DICOM_HEADER_OTHERWORD)
00763 {
00764 fs.read(&dblock_size, sizeof(int));
00765 dblock_size = intSwap(dblock_size);
00766 result = true;
00767 }
00768 else if (dblock_size == VIL_DICOM_HEADER_ALLSET)
00769 {
00770 dblock_size = 0;
00771 result = true;
00772 }
00773 else if (first == VIL_DICOM_HEADER_APPLICATIONENTRY ||
00774 first == VIL_DICOM_HEADER_AGESTRING ||
00775 first == VIL_DICOM_HEADER_ATTRIBUTETAG ||
00776 first == VIL_DICOM_HEADER_CODESTRING ||
00777 first == VIL_DICOM_HEADER_DATE ||
00778 first == VIL_DICOM_HEADER_DECIMALSTRING ||
00779 first == VIL_DICOM_HEADER_DATETIME ||
00780 first == VIL_DICOM_HEADER_FLOATINGPOINTDOUBLE ||
00781 first == VIL_DICOM_HEADER_FLOATINGPOINTSINGLE ||
00782 first == VIL_DICOM_HEADER_INTEGERSTRING ||
00783 first == VIL_DICOM_HEADER_LONGSTRING ||
00784 first == VIL_DICOM_HEADER_LONGTEXT ||
00785 first == VIL_DICOM_HEADER_PERSONNAME ||
00786 first == VIL_DICOM_HEADER_SHORTSTRING ||
00787 first == VIL_DICOM_HEADER_SIGNEDLONG ||
00788 first == VIL_DICOM_HEADER_SIGNEDSHORT ||
00789 first == VIL_DICOM_HEADER_SHORTTEXT ||
00790 first == VIL_DICOM_HEADER_TIME ||
00791 first == VIL_DICOM_HEADER_UNIQUEIDENTIFIER ||
00792 first == VIL_DICOM_HEADER_UNSIGNEDLONG ||
00793 first == VIL_DICOM_HEADER_UNSIGNEDSHORT)
00794 {
00795 if (last_read_.sys_endian_ == VIL_DICOM_HEADER_DELITTLEENDIAN)
00796 {
00797 dblock_size = (unsigned int)((256*conv_dblock.char_val[3]) + conv_dblock.char_val[2]);
00798 }
00799 else
00800 {
00801 dblock_size = (unsigned int)((256*conv_dblock.char_val[2]) + conv_dblock.char_val[3]);
00802 }
00803
00804 result = true;
00805 }
00806 else if (last == VIL_DICOM_HEADER_APPLICATIONENTRY ||
00807 last == VIL_DICOM_HEADER_AGESTRING ||
00808 last == VIL_DICOM_HEADER_ATTRIBUTETAG ||
00809 last == VIL_DICOM_HEADER_CODESTRING ||
00810 last == VIL_DICOM_HEADER_DATE ||
00811 last == VIL_DICOM_HEADER_DECIMALSTRING ||
00812 last == VIL_DICOM_HEADER_DATETIME ||
00813 last == VIL_DICOM_HEADER_FLOATINGPOINTDOUBLE ||
00814 last == VIL_DICOM_HEADER_FLOATINGPOINTSINGLE ||
00815 last == VIL_DICOM_HEADER_INTEGERSTRING ||
00816 last == VIL_DICOM_HEADER_LONGSTRING ||
00817 last == VIL_DICOM_HEADER_LONGTEXT ||
00818 last == VIL_DICOM_HEADER_PERSONNAME ||
00819 last == VIL_DICOM_HEADER_SHORTSTRING ||
00820 last == VIL_DICOM_HEADER_SIGNEDLONG ||
00821 last == VIL_DICOM_HEADER_SIGNEDSHORT ||
00822 last == VIL_DICOM_HEADER_SHORTTEXT ||
00823 last == VIL_DICOM_HEADER_TIME ||
00824 last == VIL_DICOM_HEADER_UNIQUEIDENTIFIER ||
00825 last == VIL_DICOM_HEADER_UNSIGNEDLONG ||
00826 last == VIL_DICOM_HEADER_UNSIGNEDSHORT)
00827 {
00828 if (last_read_.sys_endian_ == VIL_DICOM_HEADER_DELITTLEENDIAN)
00829 {
00830 dblock_size = (unsigned int)((256*conv_dblock.char_val[1]) + conv_dblock.char_val[0]);
00831 }
00832 else
00833 {
00834 dblock_size = (unsigned int)((256*conv_dblock.char_val[0]) + conv_dblock.char_val[1]);
00835 }
00836
00837 result = true;
00838 }
00839 }
00840
00841 return result;
00842 }
00843
00844
00845
00846 bool vil_dicom_header_format::pixelDataFound(short group, short element)
00847 {
00848 bool result = false;
00849
00850
00851 if ((vxl_uint_16)group == VIL_DICOM_HEADER_PIXELGROUP &&
00852 (vxl_uint_16)element == VIL_DICOM_HEADER_PXPIXELDATA)
00853 {
00854 result = true;
00855 }
00856
00857 return result;
00858 }
00859
00860
00861
00862 void vil_dicom_header_format::clearInfo(void)
00863 {
00864 vil_dicom_header_info_clear( last_read_ );
00865
00866
00867 info_valid_ = false;
00868 }
00869
00870
00871
00872 vil_dicom_header_endian vil_dicom_header_format::calculateEndian(void)
00873 {
00874
00875 union int_byte
00876 {
00877 vxl_uint_32 int_val;
00878 vxl_byte by_val[4];
00879 } calc_endian;
00880
00881
00882 calc_endian.int_val = 1;
00883
00884
00885 return calc_endian.by_val[0] == 1 ?
00886 VIL_DICOM_HEADER_DELITTLEENDIAN :
00887 VIL_DICOM_HEADER_DEBIGENDIAN;
00888 }
00889
00890
00891
00892 vil_dicom_header_endian vil_dicom_header_format::determineMetaInfo(vil_stream &fs)
00893 {
00894 vil_dicom_header_endian ret_end = VIL_DICOM_HEADER_DELITTLEENDIAN;
00895
00896
00897 vxl_uint_16 group, element;
00898 vxl_uint_32 data_block_size;
00899 vil_streampos ret_pos = fs.tell();
00900
00901
00902
00903 file_endian_ = VIL_DICOM_HEADER_DELITTLEENDIAN;
00904 image_type_ = VIL_DICOM_HEADER_DITUNKNOWN;
00905
00906
00907 fs.read(&group,sizeof(vxl_uint_16));
00908 group = shortSwap(group);
00909
00910 while (fs.ok() && group <= VIL_DICOM_HEADER_METAFILEGROUP)
00911 {
00912
00913
00914 fs.read(&element,sizeof(vxl_uint_16));
00915 element = shortSwap(element);
00916
00917
00918 if (sizeof(vxl_uint_32) != fs.read(&data_block_size, sizeof(vxl_uint_32)))
00919 break;
00920
00921 data_block_size = intSwap(data_block_size);
00922
00923 if (data_block_size > 0x1000000) {
00924 vcl_cerr<< __FILE__ << ": " << __LINE__ << " : WARNING:\n"
00925 <<"data_block_size=" << data_block_size << " is most probably too large\n";
00926 break;
00927 }
00928
00929 convertValueRepresentation(data_block_size,fs);
00930
00931 if (group == VIL_DICOM_HEADER_METAFILEGROUP &&
00932 element == VIL_DICOM_HEADER_MFTRANSFERSYNTAX)
00933 {
00934
00935 char * tfx_type = new char[data_block_size+1];
00936 if (tfx_type)
00937 {
00938 fs.read(tfx_type, data_block_size);
00939 tfx_type[data_block_size]=0;
00940
00941
00942
00943 vcl_string temp = tfx_type;
00944 delete [] tfx_type;
00945
00946 if (temp == VIL_DICOM_HEADER_IMPLICITLITTLE ||
00947 temp == VIL_DICOM_HEADER_EXPLICITLITTLE)
00948 {
00949
00950 ret_end = VIL_DICOM_HEADER_DELITTLEENDIAN;
00951 }
00952 else if (temp == VIL_DICOM_HEADER_EXPLICITBIG)
00953 {
00954
00955 ret_end = VIL_DICOM_HEADER_DEBIGENDIAN;
00956 }
00957 else if (temp == VIL_DICOM_HEADER_JPEGBASELINE_P1)
00958 {
00959
00960 image_type_ = VIL_DICOM_HEADER_DITJPEGBASE;
00961 }
00962 else if (temp == VIL_DICOM_HEADER_JPEGDEFLOSSY_P2_4 ||
00963 temp == VIL_DICOM_HEADER_JPEGEXTENDED_P3_5)
00964 {
00965
00966 image_type_ = VIL_DICOM_HEADER_DITJPEGEXTLOSSY;
00967 }
00968 else if (temp == VIL_DICOM_HEADER_JPEGSPECTRAL_P6_8 ||
00969 temp == VIL_DICOM_HEADER_JPEGSPECTRAL_P7_9)
00970 {
00971
00972 image_type_ = VIL_DICOM_HEADER_DITJPEGSPECNH;
00973 }
00974 else if (temp == VIL_DICOM_HEADER_JPEGFULLPROG_P10_12 ||
00975 temp == VIL_DICOM_HEADER_JPEGFULLPROG_P11_13)
00976 {
00977
00978 image_type_ = VIL_DICOM_HEADER_DITJPEGFULLNH;
00979 }
00980 else if (temp == VIL_DICOM_HEADER_JPEGLOSSLESS_P14 ||
00981 temp == VIL_DICOM_HEADER_JPEGLOSSLESS_P15)
00982 {
00983
00984 image_type_ = VIL_DICOM_HEADER_DITJPEGLOSSLNH;
00985 }
00986 else if (temp == VIL_DICOM_HEADER_JPEGEXTHIER_P16_18 ||
00987 temp == VIL_DICOM_HEADER_JPEGEXTHIER_P17_19)
00988 {
00989
00990 image_type_ = VIL_DICOM_HEADER_DITJPEGEXTHIER;
00991 }
00992 else if (temp == VIL_DICOM_HEADER_JPEGSPECHIER_P20_22 ||
00993 temp == VIL_DICOM_HEADER_JPEGSPECHIER_P21_23)
00994 {
00995
00996 image_type_ = VIL_DICOM_HEADER_DITJPEGSPECHIER;
00997 }
00998 else if (temp == VIL_DICOM_HEADER_JPEGFULLHIER_P24_26 ||
00999 temp == VIL_DICOM_HEADER_JPEGFULLHIER_P25_27)
01000 {
01001
01002 image_type_ = VIL_DICOM_HEADER_DITJPEGFULLHIER;
01003 }
01004 else if (temp == VIL_DICOM_HEADER_JPEGLLESSHIER_P28 ||
01005 temp == VIL_DICOM_HEADER_JPEGLLESSHIER_P29)
01006 {
01007
01008 image_type_ = VIL_DICOM_HEADER_DITJPEGLOSSLHIER;
01009 }
01010 else if (temp == VIL_DICOM_HEADER_JPEGLLESSDEF_P14_SV1)
01011 {
01012
01013 image_type_ = VIL_DICOM_HEADER_DITJPEGLOSSLDEF;
01014 }
01015 else if (temp == VIL_DICOM_HEADER_RLELOSSLESS)
01016 {
01017
01018 image_type_ = VIL_DICOM_HEADER_DITRLE;
01019 }
01020
01021 }
01022 }
01023 else if (group == VIL_DICOM_HEADER_DELIMITERGROUP &&
01024 (element == VIL_DICOM_HEADER_DLITEM ||
01025 element == VIL_DICOM_HEADER_DLITEMDELIMITATIONITEM ||
01026 element == VIL_DICOM_HEADER_DLSEQDELIMITATIONITEM))
01027 {
01028
01029 }
01030 else
01031 {
01032
01033 fs.seek(data_block_size + fs.tell());
01034 }
01035
01036 ret_pos = fs.tell();
01037
01038
01039
01040 fs.read(&group,sizeof(vxl_uint_16));
01041 group = shortSwap(group);
01042
01043 }
01044
01045
01046 fs.seek(ret_pos);
01047
01048 return ret_end;
01049 }
01050
01051
01052
01053 vxl_uint_16 vil_dicom_header_format::shortSwap(vxl_uint_16 short_in)
01054 {
01055 vxl_uint_16 result = short_in;
01056
01057
01058
01059
01060 if (file_endian_ != endian_)
01061 {
01062
01063 union short_char
01064 {
01065 vxl_uint_16 short_val;
01066 vxl_byte byte_val[2];
01067 } short_swap;
01068
01069
01070 short_swap.short_val = short_in;
01071
01072
01073 vxl_byte temp = short_swap.byte_val[0];
01074 short_swap.byte_val[0]=short_swap.byte_val[1];
01075 short_swap.byte_val[1]=temp;
01076
01077 result = short_swap.short_val;
01078 }
01079
01080 return result;
01081 }
01082
01083
01084
01085 vxl_uint_32 vil_dicom_header_format::intSwap(vxl_uint_32 int_in)
01086 {
01087 vxl_uint_32 result = int_in;
01088
01089
01090
01091
01092 if (file_endian_ != endian_)
01093 {
01094
01095 union int_char
01096 {
01097 vxl_uint_32 int_val;
01098 vxl_byte byte_val[4];
01099 } int_swap;
01100
01101
01102 int_swap.int_val = int_in;
01103
01104
01105 vxl_byte temp = int_swap.byte_val[0];
01106 int_swap.byte_val[0]=int_swap.byte_val[3];
01107 int_swap.byte_val[3]=temp;
01108
01109
01110 temp = int_swap.byte_val[1];
01111 int_swap.byte_val[1] = int_swap.byte_val[2];
01112 int_swap.byte_val[2] = temp;
01113
01114 result = int_swap.int_val;
01115 }
01116
01117 return result;
01118 }
01119
01120
01121
01122 void vil_dicom_header_format::charSwap(char *char_in, int val_size)
01123 {
01124
01125
01126
01127 if (file_endian_ != endian_)
01128 {
01129
01130 for (int i=val_size/2-1; i>=0; --i)
01131 {
01132 char temp=char_in[i];
01133 char_in[i] = char_in[val_size-i-1];
01134 char_in[val_size-i-1] = temp;
01135 }
01136 }
01137 }
01138
01139
01140 void vil_dicom_header_print(vcl_ostream &os, const vil_dicom_header_info &s)
01141 {
01142 os << "\n\nGeneral info fields\n"
01143 << " file_type The type of dicom file: " << s.file_type_ << vcl_endl
01144 << " sys_endian The endian of the architecture: " << s.sys_endian_ << vcl_endl
01145 << " image_type The encapsulated (or not) image type: " <<s.image_type_ << vcl_endl
01146
01147 << "\n\nIdentifying fields\n"
01148 << " image_id_type The image type from the dicom header: " << s.image_id_type_ << vcl_endl
01149 << " sop_cl_uid The class unique id for the Service/Object Pair: " << s.sop_cl_uid_ << vcl_endl
01150 << " sop_in_uid The instance uid for the SOP: " << s.sop_in_uid_ << vcl_endl
01151 << " study_date The date of the study: " << s.study_date_ << vcl_endl
01152 << " series_date The date this series was collected: " << s.series_date_ << vcl_endl
01153 << " acquisition_date The date of acquisition: " << s.acquisition_date_ << vcl_endl
01154 << " image_date The date of this image: " << s.image_date_ << vcl_endl
01155 << " study_time The time of the study: " << s.study_time_ << vcl_endl
01156 << " series_time The time of the series: " << s.series_time_ << vcl_endl
01157 << " acquisition_time The time acquisition: " << s.acquisition_time_ << vcl_endl
01158 << " image_time The time of the image: " << s.image_time_ << vcl_endl
01159 << " accession_number The accession number for this image: " << s.accession_number_ << vcl_endl
01160 << " modality The imaging modality: " << s.modality_ << vcl_endl
01161 << " manufacturer The name of the scanner manufacturer: " << s.manufacturer_ << vcl_endl
01162 << " institution_name The name of the institution: " << s.institution_name_ << vcl_endl
01163 << " institution_addr The address of the institution: " << s.institution_addr_ << vcl_endl
01164 << " ref_phys_name The name of the referring physician: " << s.ref_phys_name_ << vcl_endl
01165 << " station_name The name of the station used: " << s.station_name_ << vcl_endl
01166 << " study_desc A description of the study: " << s.study_desc_ << vcl_endl
01167 << " series_desc A description of the series: " << s.series_desc_ << vcl_endl
01168 << " att_phys_name The name of the attending physician: " << s.att_phys_name_ << vcl_endl
01169 << " operator_name The name of the MR operator: " << s.operator_name_ << vcl_endl
01170 << " model_name The name of the MR scanner model: " << s.model_name_ << vcl_endl
01171
01172 << "\n\nPatient info\n"
01173 << " patient_name Patient's name: " << s.patient_name_ << vcl_endl
01174 << " patient_id Patient's ID: " << s.patient_id_ << vcl_endl
01175 << " patient_dob The patient's date of birth: " << s.patient_dob_ << vcl_endl
01176 << " patient_sex The sex of the patient: " << s.patient_sex_ << vcl_endl
01177 << " patient_age The age of the patient: " << s.patient_age_ << vcl_endl
01178 << " patient_weight_ The weight of the patient: " << s.patient_weight_ << vcl_endl
01179 << " patient_hist Any additional patient history: " << s.patient_hist_ << vcl_endl
01180
01181 << "\n\nAcquisition Info\n"
01182 << " scanning_seq A description of the scanning sequence: " << s.scanning_seq_ << vcl_endl
01183 << " sequence_var A description of the sequence variant: " << s.sequence_var_ << vcl_endl
01184 << " scan_options A description of various scan options: " << s.scan_options_ << vcl_endl
01185 << " mr_acq_type The acquisition type for this scan: " << s.mr_acq_type_ << vcl_endl
01186 << " sequence_name The name of the sequence: " << s.sequence_name_ << vcl_endl
01187 << " angio_flag The angio flag for this sequence: " << s.angio_flag_ << vcl_endl
01188 << " slice_thickness_ Slice thickness (for voxel size): " << s.slice_thickness_ << vcl_endl
01189 << " repetition_time_ Scan repetition time: " << s.repetition_time_ << vcl_endl
01190 << " echo_time Scan echo time: " << s.echo_time_ << vcl_endl
01191 << " inversion_time Scan inversion time: " << s.inversion_time_ << vcl_endl
01192 << " number_of_averages The number of averages for this scan: " << s.number_of_averages_ << vcl_endl
01193 << " echo_numbers The echo numbers for this scan: " << s.echo_numbers_ << vcl_endl
01194 << " mag_field_strength The strength of the magnetic field: " << s.mag_field_strength_ << vcl_endl
01195 << " echo_train_length The length of the echo train: " << s.echo_train_length_ << vcl_endl
01196 << " pixel_bandwidth The bandwidth of the pixels: " << s.pixel_bandwidth_ << vcl_endl
01197 << " software_vers_ Versions of the scanner software used: " << s.software_vers_ << vcl_endl
01198 << " protocol_name The name of the protocol used: " << s.protocol_name_ << vcl_endl
01199 << " heart_rate The patient's heart rate: " << s.heart_rate_ << vcl_endl
01200 << " card_num_images The cardiac number of images: " << s.card_num_images_ << vcl_endl
01201 << " trigger_window The trigger window for this image: " << s.trigger_window_ << vcl_endl
01202 << " reconst_diameter The reconstruction diameter: " << s.reconst_diameter_ << vcl_endl
01203 << " receiving_coil_ Details of the receiving coil: " << s.receiving_coil_ << vcl_endl
01204 << " phase_enc_dir The phase encoding direction: " << s.phase_enc_dir_ << vcl_endl
01205 << " flip_angle The flip angle: " << s.flip_angle_ << vcl_endl
01206 << " sar The specific absorption rate: " << s.sar_ << vcl_endl
01207 << " patient_pos The position of the patient in the scanner: " << s.patient_pos_ << vcl_endl
01208
01209 << "\n\nRelationship info\n"
01210 << " stud_ins_uid The study instance unique id: " << s.stud_ins_uid_ << vcl_endl
01211 << " ser_ins_uid The series instance unique id: " << s.ser_ins_uid_ << vcl_endl
01212 << " study_id The id of this study: " << s.study_id_ << vcl_endl
01213 << " series_number The number of this series: " << s.series_number_ << vcl_endl
01214 << " acquisition_number The number of the acquisition: " << s.acquisition_number_ << vcl_endl
01215 << " image_number The number of this image instance: " << s.image_number_ << vcl_endl
01216 << " pat_orient The orientation of the patient: " << s.pat_orient_ << vcl_endl
01217 << " image_pos The image position relative to the patient: " << s.image_pos_[0] << '/' << s.image_pos_[1] << '/' << s.image_pos_[2] << vcl_endl
01218 << " 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] << vcl_endl
01219 << " frame_of_ref The frame of reference" << s.frame_of_ref_ << vcl_endl
01220 << " images_in_acq Then number ot images in the acquisition: " << s.images_in_acq_ << vcl_endl
01221 << " pos_ref_ind The position reference indicator: " << s.pos_ref_ind_ << vcl_endl
01222 << " slice_location The location of the slice: " << s.slice_location_ << vcl_endl
01223
01224 << "\n\nImage info\n"
01225 << " pix_samps The number of samples per pixel: " << s.pix_samps_ << vcl_endl
01226 << " photo_interp The photometric interpretation: " << s.photo_interp_ << vcl_endl
01227 << " size_x The number of columns: " << s.size_x_ << vcl_endl
01228 << " size_y The number of rows: " << s.size_y_ << vcl_endl
01229 << " size_z The number of planes: " << s.size_z_ << vcl_endl
01230 << " high_bit The bit used as the high bit: " << s.high_bit_ << vcl_endl
01231 << " small_im_pix_val The smallest image pixel value: " << s.small_im_pix_val_ << vcl_endl
01232 << " large_im_pix_val The largest image pixel value: " << s.large_im_pix_val_ << vcl_endl
01233 << " pixel_padding_val The value used for padding pixels: " << s.pixel_padding_val_ << vcl_endl
01234 << " window_centre The value of the image window's centre: " << s.window_centre_ << vcl_endl
01235 << " window_width The actual width of the image window: " << s.window_width_ << vcl_endl
01236
01237 << "\n\nInfo from the tags specifically for reading the image data\n"
01238 << " spaxing_x The pixel spacing in x: " << s.spacing_x_ << vcl_endl
01239 << " spacing_y The pixel spacing in y: " << s.spacing_y_ << vcl_endl
01240 << " spacing_slice The pixel spacing in z: " << s.spacing_slice_ << vcl_endl
01241 << " res_intercept The image rescale intercept: " << s.res_intercept_ << vcl_endl
01242 << " res_slope The image rescale slope: " << s.res_slope_ << vcl_endl
01243 << " pix_rep The pixel representation (+/-): " << s.pix_rep_ << vcl_endl
01244 << " stored_bits The bits stored: " << s.stored_bits_ << vcl_endl
01245 << " allocated_bits The bits allocated: " << s.allocated_bits_ << vcl_endl;
01246 }
01247
01248 #endif // HAS_DCMTK