10 #include <vil/vil_config.h> 17 # include <vcl_msvc_warnings.h> 20 #include <vxl_config.h> 30 #include <dcmtk/dcmdata/dcfilefo.h> 31 #include <dcmtk/dcmdata/dcmetinf.h> 32 #include <dcmtk/dcmdata/dcdatset.h> 33 #include <dcmtk/dcmdata/dctagkey.h> 34 #include <dcmtk/dcmdata/dcdeftag.h> 35 #include <dcmtk/dcmdata/dcstack.h> 36 #include <dcmtk/dcmimgle/diinpxt.h> 51 char const* vil_dicom_format_tag =
"dicom";
56 bool is_dicom =
false;
58 char magic[ DCM_MagicLen ];
59 vs->
seek( DCM_PreambleLen );
60 if ( vs->
read( magic, DCM_MagicLen ) == DCM_MagicLen ) {
61 if ( std::strncmp( magic, DCM_Magic, DCM_MagicLen ) == 0 ) {
78 std::cerr <<
"ERROR: vil_dicom_file doesn't support output yet\n";
84 std::cerr <<
"ERROR: vil_dicom_file_format::make_output_image\n" 85 <<
" Can only create DICOM images with a single plane\n" 86 <<
" and 32-bit integer pixels\n";
95 return vil_dicom_format_tag;
108 read_pixels_into_buffer(DiDocument* doc,
109 unsigned num_samples,
129 OFCondition cond = ffmt.read( dcis );
132 if ( cond != EC_Normal ) {
133 std::cerr <<
"vil_dicom ERROR: could not read file (" << cond.text() <<
")\n" 134 <<
"And the error code is: " << cond.code() << std::endl;
139 DcmDataset& dset = *ffmt.getDataset();
140 read_header( &dset, header_ );
143 correct_manufacturer_discrepancies();
148 if ( dset.tagExists( DCM_ModalityLUTSequence ) ) {
149 std::cerr <<
"vil_dicom ERROR: don't know (yet) how to handle modality LUTs\n";
157 Float64 slope, intercept;
158 if ( dset.findAndGetFloat64( DCM_RescaleSlope, slope ) != EC_Normal )
160 if ( dset.findAndGetFloat64( DCM_RescaleIntercept, intercept ) != EC_Normal )
165 #define Stringify( v ) #v 166 #define MustRead( func, key, var ) \ 168 if ( dset. func( key, var ) != EC_Normal ) { \ 169 std::cerr << "vil_dicom ERROR: couldn't read " Stringify(key) "; can't handle\n"; \ 173 Uint16 bits_alloc, bits_stored, high_bit, pixel_rep;
175 MustRead( findAndGetUint16, DCM_BitsAllocated, bits_alloc );
176 MustRead( findAndGetUint16, DCM_BitsStored, bits_stored );
177 MustRead( findAndGetUint16, DCM_HighBit, high_bit );
178 MustRead( findAndGetUint16, DCM_PixelRepresentation, pixel_rep );
192 DcmPixelData* pixels = 0;
194 if ( dset.search( DCM_PixelData, stack, ESM_fromHere,
true ) == EC_Normal )
196 if ( stack.card() == 0 ) {
197 std::cerr <<
"vil_dicom ERROR: no pixel data found\n";
201 assert( stack.top()->ident() == EVR_PixelData );
205 DiDocument doc(&dset, EXS_Unknown);
206 pixels = doc.getPixelData();
208 unsigned num_samples = ni() * nj() * nplanes();
209 read_pixels_into_buffer(&doc, num_samples, nplanes(),
210 bits_alloc, bits_stored, high_bit, pixel_rep,
212 pixel_buf, pixel_format);
217 #define DOCASE( fmt ) \ 219 typedef vil_pixel_format_type_of<fmt>::component_type T; \ 220 pixels_ = vil_new_image_resource_of_view( \ 221 vil_image_view<T>(pixel_buf, \ 222 (T*)pixel_buf->data(), \ 223 ni(), nj(), nplanes(), \ 224 nplanes(), ni()*nplanes(), 1));\ 227 switch ( pixel_format ) {
233 default: std::cerr <<
"vil_dicom ERROR: unexpected pixel format\n";
250 float *pixel_size = static_cast<float*>(value);
262 return vil_dicom_format_tag;
268 assert(!
"vil_dicom_image doesn't yet support output");
301 unsigned x0,
unsigned nx,
unsigned y0,
unsigned ny)
const 307 unsigned x0,
unsigned nx,
unsigned y0,
unsigned ny)
const 313 unsigned x0,
unsigned y0)
315 assert(!
"vil_dicom_image doesn't yet support output yet");
343 float xPixelSize=1.0;
344 float yPixelSize=1.0;
385 static const std::string HOLOGIC_PixelXSizeMM =
"<PixelXSizeMM>";
386 static const std::string HOLOGIC_PixelXSizeMM_END =
"</PixelXSizeMM>";
387 static const std::string HOLOGIC_PixelYSizeMM =
"<PixelYSizeMM>";
388 static const std::string HOLOGIC_PixelYSizeMM_END =
"</PixelYSizeMM>";
392 std::size_t ipxStart = src.find(HOLOGIC_PixelXSizeMM);
393 if (ipxStart==src.npos)
return false;
396 std::size_t ipxEnd = src.find(HOLOGIC_PixelXSizeMM_END,ipxStart);
397 if (ipxEnd==src.npos)
return false;
400 std::string strPixelXSizeMM=
"";
401 ipxStart+= HOLOGIC_PixelXSizeMM.size();
402 strPixelXSizeMM.append(src,ipxStart, ipxEnd-ipxStart);
404 if (strPixelXSizeMM.size()>0)
407 std::stringstream translate_is(strPixelXSizeMM,std::stringstream::in);
408 translate_is>>xpixSize;
409 if (!translate_is)
return false;
410 if (xpixSize<=0.0 || xpixSize>=1.0E6)
419 std::size_t ipyStart = src.find(HOLOGIC_PixelYSizeMM);
420 if (ipyStart==src.npos)
return false;
423 std::size_t ipyEnd = src.find(HOLOGIC_PixelYSizeMM_END,ipyStart);
424 if (ipyEnd==src.npos)
return false;
427 std::string strPixelYSizeMM=
"";
428 ipyStart+= HOLOGIC_PixelYSizeMM.size();
429 strPixelYSizeMM.append(src,ipyStart, ipyEnd-ipyStart);
431 if (strPixelYSizeMM.size()>0)
434 std::stringstream translate_is(strPixelYSizeMM,std::stringstream::in);
435 translate_is>>ypixSize;
436 if (!translate_is)
return false;
437 if (ypixSize<=0.0 || ypixSize>=1.0E6)
456 find_element( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element )
458 DcmElement* result = 0;
459 DcmTagKey key( group, element );
461 if ( dset->search( key, stack, ESM_fromHere,
true ) == EC_Normal )
463 if ( stack.card() == 0 ) {
464 std::cerr <<
"vil_dicom ERROR: no results on stack\n";
467 result = static_cast<DcmElement*>(stack.top());
468 if ( result->getVM() == 0 ) {
491 struct try_set_to_string
493 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element, std::string& value ) {
494 DcmElement* e = find_element( dset, group, element );
498 if ( e->getOFString( str, 0 ) != EC_Normal ) {
499 std::cerr <<
"vil_dicom Warning: value of ("<<group<<
','<<element<<
") is not string\n";
510 :
public try_set_to_string
516 :
public try_set_to_string
522 :
public try_set_to_string
528 :
public try_set_to_string
535 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element,
long& value ) {
536 DcmElement* e = find_element( dset, group, element );
540 if ( e->getOFString( str, 0 ) != EC_Normal ) {
541 std::cerr <<
"Warning: value of ("<<group<<
','<<element<<
") is not string\n";
544 value = std::atol( str.c_str() );
553 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element,
float& value ) {
554 DcmElement* e = find_element( dset, group, element );
558 if ( e->getOFString( str, 0 ) != EC_Normal ) {
559 std::cerr <<
"vil_dicom Warning: value of ("<<group<<
','<<element<<
") is not string\n";
562 value = static_cast<float>( std::atof( str.c_str() ) );
567 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element, std::vector<float>& value ) {
568 DcmElement* e = find_element( dset, group, element );
570 for (
unsigned pos = 0; pos < e->getVM(); ++pos )
573 if ( e->getOFString( str, pos ) != EC_Normal ) {
574 std::cerr <<
"Warning: value of ("<<group<<
','<<element<<
") at " << pos <<
" is not string\n";
577 value.push_back( static_cast<float>( std::atof( str.c_str() ) ) );
587 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element, vxl_ieee_64& value ) {
588 DcmElement* e = find_element( dset, group, element );
590 if ( e->getFloat64( value ) != EC_Normal ) {
591 std::cerr <<
"Warning: value of ("<<group<<
','<<element<<
") is not Float64\n";
600 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element, vxl_ieee_32& value ) {
601 DcmElement* e = find_element( dset, group, element );
603 if ( e->getFloat32( value ) != EC_Normal ) {
604 std::cerr <<
"Warning: value of ("<<group<<
','<<element<<
") is not Float32\n";
613 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element,
long& value ) {
614 DcmElement* e = find_element( dset, group, element );
618 if ( e->getOFString( str, 0 ) != EC_Normal ) {
619 std::cerr <<
"vil_dicom Warning: value of ("<<group<<
','<<element<<
") is not string\n";
622 value = std::atol( str.c_str() );
630 :
public try_set_to_string
636 :
public try_set_to_string
642 :
public try_set_to_string
648 :
public try_set_to_string
654 :
public try_set_to_string
660 :
public try_set_to_string
667 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element, vxl_sint_32& value ) {
668 DcmElement* e = find_element( dset, group, element );
670 if ( e->getSint32( reinterpret_cast<Sint32&>(value) ) != EC_Normal ) {
671 std::cerr <<
"vil_dicom Warning: value of ("<<group<<
','<<element<<
") is not Sint32\n";
679 :
public try_set_to_string
686 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element, vxl_sint_16& value ) {
687 DcmElement* e = find_element( dset, group, element );
689 if ( e->getSint16( reinterpret_cast<Sint16&>(value) ) != EC_Normal ) {
690 std::cerr <<
"vil_dicom Warning: value of ("<<group<<
','<<element<<
") is not Sint16\n";
698 :
public try_set_to_string
705 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element,
float& value ) {
706 DcmElement* e = find_element( dset, group, element );
710 if ( e->getOFString( str, 0 ) != EC_Normal ) {
711 std::cerr <<
"vil_dicom Warning: value of ("<<group<<
','<<element<<
") is not string\n";
714 value = static_cast<float>( std::atof( str.c_str() ) );
722 :
public try_set_to_string
729 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element, vxl_uint_32& value ) {
730 DcmElement* e = find_element( dset, group, element );
732 if ( e->getUint32( reinterpret_cast<Uint32&>(value) ) != EC_Normal ) {
733 std::cerr <<
"vil_dicom Warning: value of ("<<group<<
','<<element<<
") is not Uint32\n";
741 :
public try_set_to_string
748 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element, vxl_uint_16& value ) {
749 DcmElement* e = find_element( dset, group, element );
751 if ( e->getUint16( value ) != EC_Normal ) {
752 std::cerr <<
"vil_dicom Warning: value of ("<<group<<
','<<element<<
") is not Uint16\n";
757 static void proc( DcmObject* dset, vxl_uint_16 group, vxl_uint_16 element, std::vector<vxl_uint_16>& value ) {
758 DcmElement* e = find_element( dset, group, element );
760 vxl_uint_16 value_at_pos;
761 for (
unsigned long pos = 0; pos < e->getVM(); ++pos )
763 if ( e->getUint16( value_at_pos, pos ) != EC_Normal ) {
764 std::cerr <<
"vil_dicom Warning: value of ("<<group<<
','<<element<<
") at " << pos <<
" is not Uint16\n";
767 value.push_back(value_at_pos);
776 :
public try_set_to_string
787 #define ap_join(A,B) A ## B 788 #define ap_type(X) ap_join( vil_dicom_header_, X ) 789 #define ap_el(X) ap_join( VIL_DICOM_HEADER_, X ) 792 try_set< ap_type(CS) >::proc( f, group, ap_el(IDIMAGETYPE), i.
image_id_type_ );
793 try_set< ap_type(UI) >::proc( f, group, ap_el(IDSOPCLASSID), i.
sop_cl_uid_ );
794 try_set< ap_type(UI) >::proc( f, group, ap_el(IDSOPINSTANCEID), i.
sop_in_uid_ );
795 try_set< ap_type(DA) >::proc( f, group, ap_el(IDSTUDYDATE), i.
study_date_ );
796 try_set< ap_type(DA) >::proc( f, group, ap_el(IDSERIESDATE), i.
series_date_ );
797 try_set< ap_type(DA) >::proc( f, group, ap_el(IDACQUISITIONDATE), i.
acquisition_date_ );
798 try_set< ap_type(DA) >::proc( f, group, ap_el(IDIMAGEDATE), i.
image_date_ );
799 try_set< ap_type(TM) >::proc( f, group, ap_el(IDSTUDYTIME), i.
study_time_ );
800 try_set< ap_type(TM) >::proc( f, group, ap_el(IDSERIESTIME), i.
series_time_ );
801 try_set< ap_type(TM) >::proc( f, group, ap_el(IDACQUISITIONTIME), i.
acquisition_time_ );
802 try_set< ap_type(TM) >::proc( f, group, ap_el(IDIMAGETIME), i.
image_time_ );
803 try_set< ap_type(SH) >::proc( f, group, ap_el(IDACCESSIONNUMBER), i.
accession_number_ );
804 try_set< ap_type(CS) >::proc( f, group, ap_el(IDMODALITY), i.
modality_ );
805 try_set< ap_type(LO) >::proc( f, group, ap_el(IDMANUFACTURER), i.
manufacturer_ );
806 try_set< ap_type(LO) >::proc( f, group, ap_el(IDINSTITUTIONNAME), i.
institution_name_ );
807 try_set< ap_type(ST) >::proc( f, group, ap_el(IDINSTITUTIONADDRESS),i.
institution_addr_ );
808 try_set< ap_type(PN) >::proc( f, group, ap_el(IDREFERRINGPHYSICIAN),i.
ref_phys_name_ );
809 try_set< ap_type(SH) >::proc( f, group, ap_el(IDSTATIONNAME), i.
station_name_ );
810 try_set< ap_type(LO) >::proc( f, group, ap_el(IDSTUDYDESCRIPTION), i.
study_desc_ );
811 try_set< ap_type(LO) >::proc( f, group, ap_el(IDSERIESDESCRIPTION), i.
series_desc_ );
812 try_set< ap_type(PN) >::proc( f, group, ap_el(IDATTENDINGPHYSICIAN),i.
att_phys_name_);
813 try_set< ap_type(PN) >::proc( f, group, ap_el(IDOPERATORNAME), i.
operator_name_ );
814 try_set< ap_type(LO) >::proc( f, group, ap_el(IDMANUFACTURERMODEL), i.
model_name_ );
817 try_set< ap_type(PN) >::proc( f, group, ap_el(PIPATIENTNAME), i.
patient_name_ );
818 try_set< ap_type(LO) >::proc( f, group, ap_el(PIPATIENTID), i.
patient_id_ );
819 try_set< ap_type(DA) >::proc( f, group, ap_el(PIPATIENTBIRTHDATE),i.
patient_dob_ );
820 try_set< ap_type(CS) >::proc( f, group, ap_el(PIPATIENTSEX), i.
patient_sex_ );
821 try_set< ap_type(AS) >::proc( f, group, ap_el(PIPATIENTAGE), i.
patient_age_ );
822 try_set< ap_type(DS) >::proc( f, group, ap_el(PIPATIENTWEIGHT), i.
patient_weight_ );
823 try_set< ap_type(LT) >::proc( f, group, ap_el(PIPATIENTHISTORY), i.
patient_hist_ );
826 try_set< ap_type(CS) >::proc( f, group, ap_el(AQSCANNINGSEQUENCE), i.
scanning_seq_ );
827 try_set< ap_type(CS) >::proc( f, group, ap_el(AQSEQUENCEVARIANT), i.
sequence_var_ );
828 try_set< ap_type(CS) >::proc( f, group, ap_el(AQSCANOPTIONS), i.
scan_options_ );
829 try_set< ap_type(CS) >::proc( f, group, ap_el(AQMRACQUISITIONTYPE), i.
mr_acq_type_ );
830 try_set< ap_type(SH) >::proc( f, group, ap_el(AQSEQUENCENAME), i.
sequence_name_ );
831 try_set< ap_type(CS) >::proc( f, group, ap_el(AQANGIOFLAG), i.
angio_flag_ );
832 try_set< ap_type(DS) >::proc( f, group, ap_el(AQSLICETHICKNESS), i.
slice_thickness_ );
833 try_set< ap_type(DS) >::proc( f, group, ap_el(AQREPETITIONTIME), i.
repetition_time_ );
834 try_set< ap_type(DS) >::proc( f, group, ap_el(AQECHOTIME), i.
echo_time_ );
835 try_set< ap_type(DS) >::proc( f, group, ap_el(AQINVERSIONTIME), i.
inversion_time_ );
836 try_set< ap_type(DS) >::proc( f, group, ap_el(AQNUMBEROFAVERAGES), i.
number_of_averages_ );
837 try_set< ap_type(IS) >::proc( f, group, ap_el(AQECHONUMBERS), i.
echo_numbers_ );
838 try_set< ap_type(DS) >::proc( f, group, ap_el(AQMAGNETICFIELDSTRENGTH), i.
mag_field_strength_);
839 try_set< ap_type(DS) >::proc( f, group, ap_el(AQSLICESPACING), i.
spacing_slice_ );
840 try_set< ap_type(IS) >::proc( f, group, ap_el(AQECHOTRAINLENGTH), i.
echo_train_length_ );
841 try_set< ap_type(DS) >::proc( f, group, ap_el(AQPIXELBANDWIDTH), i.
pixel_bandwidth_ );
842 try_set< ap_type(LO) >::proc( f, group, ap_el(AQSOFTWAREVERSION), i.
software_vers_ );
843 try_set< ap_type(LO) >::proc( f, group, ap_el(AQPROTOCOLNAME), i.
protocol_name_ );
844 try_set< ap_type(DS) >::proc( f, group, ap_el(AQTRIGGERTIME), i.
trigger_time_ );
845 try_set< ap_type(IS) >::proc( f, group, ap_el(AQHEARTRATE), i.
heart_rate_ );
846 try_set< ap_type(IS) >::proc( f, group, ap_el(AQCARDIACNUMBEROFIMAGES), i.
card_num_images_ );
847 try_set< ap_type(IS) >::proc( f, group, ap_el(AQTRIGGERWINDOW), i.
trigger_window_ );
848 try_set< ap_type(DS) >::proc( f, group, ap_el(AQRECONTRUCTIONDIAMETER), i.
reconst_diameter_ );
849 try_set< ap_type(SH) >::proc( f, group, ap_el(AQRECEIVINGCOIL), i.
receiving_coil_ );
850 try_set< ap_type(CS) >::proc( f, group, ap_el(AQPHASEENCODINGDIRECTION),i.
phase_enc_dir_ );
851 try_set< ap_type(DS) >::proc( f, group, ap_el(AQFLIPANGLE), i.
flip_angle_ );
852 try_set< ap_type(DS) >::proc( f, group, ap_el(AQSAR), i.
sar_ );
853 try_set< ap_type(CS) >::proc( f, group, ap_el(AQPATIENTPOSITION), i.
patient_pos_ );
856 std::vector<DS_type> ps_ips;
857 try_set< ap_type(DS) >::proc( f, group, ap_el(AQIMAGERPIXELSPACING), ps_ips );
858 if ( ps_ips.size() > 0 )
862 if ( ps_ips.size() > 1 )
868 try_set< ap_type(UI) >::proc( f, group, ap_el(RSSTUDYINSTANCEUID), i.
stud_ins_uid_ );
869 try_set< ap_type(UI) >::proc( f, group, ap_el(RSSERIESINSTANCEUID), i.
ser_ins_uid_ );
870 try_set< ap_type(SH) >::proc( f, group, ap_el(RSSTUDYID), i.
study_id_ );
871 try_set< ap_type(IS) >::proc( f, group, ap_el(RSSERIESNUMBER), i.
series_number_ );
872 try_set< ap_type(IS) >::proc( f, group, ap_el(RSAQUISITIONNUMBER), i.
acquisition_number_ );
873 try_set< ap_type(IS) >::proc( f, group, ap_el(RSIMAGENUMBER), i.
image_number_ );
874 try_set< ap_type(CS) >::proc( f, group, ap_el(RSPATIENTORIENTATION), i.
pat_orient_ );
875 try_set< ap_type(DS) >::proc( f, group, ap_el(RSIMAGEPOSITION), i.
image_pos_ );
876 try_set< ap_type(DS) >::proc( f, group, ap_el(RSIMAGEORIENTATION), i.
image_orient_ );
877 try_set< ap_type(UI) >::proc( f, group, ap_el(RSFRAMEOFREFERENCEUID),i.
frame_of_ref_ );
878 try_set< ap_type(IS) >::proc( f, group, ap_el(RSIMAGESINACQUISITION),i.
images_in_acq_);
879 try_set< ap_type(LO) >::proc( f, group, ap_el(RSPOSITIONREFERENCE), i.
pos_ref_ind_ );
880 try_set< ap_type(LT) >::proc( f, group, ap_el(RSIMAGECOMMENTS), i.
image_comments_ );
883 try_set< ap_type(US) >::proc( f, group, ap_el(IMSAMPLESPERPIXEL), i.
pix_samps_ );
884 try_set< ap_type(CS) >::proc( f, group, ap_el(IMPHOTOMETRICINTERP), i.
photo_interp_ );
885 try_set< ap_type(US) >::proc( f, group, ap_el(IMROWS), i.
size_y_ );
886 try_set< ap_type(US) >::proc( f, group, ap_el(IMCOLUMNS), i.
size_x_ );
887 try_set< ap_type(US) >::proc( f, group, ap_el(IMPLANES), i.
size_z_ );
888 try_set< ap_type(US) >::proc( f, group, ap_el(IMBITSALLOCATED), i.
allocated_bits_ );
889 try_set< ap_type(US) >::proc( f, group, ap_el(IMBITSSTORED), i.
stored_bits_ );
890 try_set< ap_type(US) >::proc( f, group, ap_el(IMHIGHBIT), i.
high_bit_ );
891 try_set< ap_type(US) >::proc( f, group, ap_el(IMPIXELREPRESENTATION),i.
pix_rep_ );
892 try_set< ap_type(US) >::proc( f, group, ap_el(IMSMALLIMPIXELVALUE), i.
small_im_pix_val_ );
893 try_set< ap_type(US) >::proc( f, group, ap_el(IMLARGEIMPIXELVALUE), i.
large_im_pix_val_ );
894 try_set< ap_type(US) >::proc( f, group, ap_el(IMPIXELPADDINGVALUE), i.
pixel_padding_val_ );
895 try_set< ap_type(DS) >::proc( f, group, ap_el(IMWINDOWCENTER), i.
window_centre_ );
896 try_set< ap_type(DS) >::proc( f, group, ap_el(IMWINDOWWIDTH), i.
window_width_ );
897 try_set< ap_type(DS) >::proc( f, group, ap_el(IMRESCALEINTERCEPT), i.
res_intercept_ );
898 try_set< ap_type(DS) >::proc( f, group, ap_el(IMRESCALESLOPE), i.
res_slope_ );
900 std::vector<DS_type> ps;
901 try_set< ap_type(DS) >::proc( f, group, ap_el(IMPIXELSPACING), ps );
916 if (ps_ips.size() <= 0)
922 else if (ps_ips.size() > 1)
928 else if (ps_ips.size() > 0)
942 std::vector<US_type> psb;
943 try_set< ap_type(US) >::proc( f, group, ap_el(EXPOSEDAREA), psb );
944 if ( psb.size() > 0 )
948 if ( psb.size() > 1 )
970 convert_src_type(InT
const *,
971 DiDocument *document,
972 unsigned num_samples,
978 DiInputPixel *&pixel_data,
981 Uint32 firstFragment = 0;
982 if ( rep == 0 && stored <= 8 ) {
984 pixel_data =
new DiInputPixelTemplate<InT,Uint8>( document, alloc, stored, high, 0, num_samples, nplanes,
nullptr, firstFragment );
986 else if ( rep == 0 && stored <= 16 ) {
988 pixel_data =
new DiInputPixelTemplate<InT,Uint16>( document, alloc, stored, high, 0, num_samples, nplanes,
nullptr, firstFragment );
990 else if ( rep == 1 && stored <= 8 ) {
992 pixel_data =
new DiInputPixelTemplate<InT,Sint8>( document, alloc, stored, high, 0, num_samples, nplanes,
nullptr, firstFragment );
994 else if ( rep == 1 && stored <= 16 ) {
996 pixel_data =
new DiInputPixelTemplate<InT,Sint16>( document, alloc, stored, high, 0, num_samples, nplanes,
nullptr, firstFragment );
1000 template<
class IntType,
class OutType>
1002 rescale_values( IntType
const* int_begin,
1003 unsigned num_samples,
1004 OutType* float_begin,
1005 Float64 slope, Float64 intercept )
1007 IntType
const*
const int_end = int_begin + num_samples;
1008 for ( ; int_begin != int_end; ++int_begin, ++float_begin ) {
1009 *float_begin = static_cast<OutType>( *int_begin * slope + intercept );
1014 static unsigned short swap_short(
unsigned short v)
1020 static void swap_shorts(
unsigned short *ip,
unsigned short *op,
int count)
1024 *op++ = swap_short(*ip++);
1028 #endif //MIXED_ENDIAN 1031 read_pixels_into_buffer(DiDocument* doc,
1032 unsigned num_samples,
1054 DiInputPixel* pixel_data = 0;
1055 if ( doc->getPixelData()->getVR() == EVR_OW ) {
1056 convert_src_type((Uint16 *) 0, doc, num_samples, nplanes, alloc, stored, high, rep, pixel_data, act_format);
1059 convert_src_type((Uint8 *) 0, doc, num_samples, nplanes, alloc, stored, high, rep, pixel_data, act_format);
1064 slope = 1; intercept = 0;
1070 bool swap_data =
false;
1071 unsigned short* temp1 =
new unsigned short[num_samples];
1072 unsigned short* temp2 =
1073 reinterpret_cast<unsigned short*>(pixel_data->getData());
1074 swap_shorts(temp2, temp1, num_samples);
1075 vxl_byte* temp3 = reinterpret_cast<vxl_byte*>(temp1);
1076 #endif //MIXED_ENDIAN 1078 if ( pixel_data == 0 ) {
1083 doc->getPixelData()->clear();
1087 if ( slope == 1 && intercept == 0 ) {
1088 out_format = act_format;
1099 std::memcpy( out_buf->data(), temp3, out_buf->size() );
1101 std::memcpy( out_buf->data(), pixel_data->getData(), out_buf->size() );
1102 #endif //MIXED_ENDIAN 1108 void* in_begin = reinterpret_cast<void*>(temp1);
1110 void* in_begin = const_cast<void*>(pixel_data->getData());
1111 #endif //MIXED_ENDIAN 1112 float* out_begin = static_cast<float*>( out_buf->data() );
1114 switch ( act_format )
1117 rescale_values( (vxl_byte*)in_begin, num_samples, out_begin, slope, intercept );
1120 rescale_values( (vxl_sbyte*)in_begin, num_samples, out_begin, slope, intercept );
1123 rescale_values( (vxl_uint_16*)in_begin, num_samples, out_begin, slope, intercept );
1126 rescale_values( (vxl_sint_16*)in_begin, num_samples, out_begin, slope, intercept );
1129 std::cerr <<
"vil_dicom ERROR: unexpected internal pixel format\n";
1135 #endif //MIXED_ENDIAN
Stream interface for VIL image loaders.
An abstract base class of smart pointers to actual image data in memory.
virtual bool view_fits(const vil_image_view_base &im, unsigned i0, unsigned j0)
Check that a view will fit into the data at the given offset.
#define vil_property_pixel_size
Pixel width in metres.
vil_dicom_image(vil_stream *is, unsigned ni, unsigned nj, unsigned nplanes, vil_pixel_format format)
virtual void seek(vil_streampos position)=0
Goto file pointer.
virtual bool interpret_hologic_header(float &xpixSize, float &ypixSize)
try and interpret the hologic comments section to extract pixel size.
virtual vil_streampos read(void *buf, vil_streampos n)=0
Read n bytes into buf. Returns number of bytes read.
Exceptions thrown by vil, and a mechanism for turning them off.
vil_dicom_header_info header_
#define vil_property_quantisation_depth
The quantisation depth of pixel components.
char const * file_format() const
Return a string describing the file format.
Reader/Writer for DICOM format 2D images.
Stream interface for VIL image loaders.
virtual void correct_manufacturer_discrepancies()
correct known manufacturers drop-offs in header data!.
Indicates that some reference was made to pixels beyond the bounds of an image.
virtual enum vil_pixel_format pixel_format() const
Pixel Format.
virtual unsigned ni() const
Dimensions: Planes x ni x nj.
vil_image_view_base_sptr get_copy_view() const
Create a read/write view of a copy of all the data.
A base class reference-counting view of some image data.
There is no class or function called vil_property.
Ref. counted block of data on the heap.
void vil_exception_warning(T exception)
Throw an exception indicating a potential problem.
Representation of a generic image source or destination.
virtual bool put_view(const vil_image_view_base &im, unsigned i0, unsigned j0)
Put the data in this view back into the image source.
virtual unsigned nplanes() const
Dimensions: Planes x ni x nj.
vil_image_resource_sptr pixels_
Generic image implementation for DICOM files.
vil_image_view_base_sptr get_view() const
Create a read/write view of all the data.
bool get_property(char const *tag, void *prop=0) const
Extra property information.
virtual unsigned nj() const
Dimensions: Planes x ni x nj.