Hi I'm modifying octave-forge/extra/dicom/src/dicominfo.cpp to handle data which are arrays, i.e. VM>1. I realize that not many people will know DICOM, let alone GDCM, but I'd appreciate any feedback in any case. (There's some generic octave questions at the end)
Also, it would be good if someone could test the current dicominfo on systems with different byteorders. I suspect that it'll only work when the byteorder of the dicom file is the same as the one of the machine you're running it on. I had a look at gdcm example code and it seems to me that we cannot really use memcpy to get from the dicom raw data to octave data. This presumably wouldn't work when byteswapping is needed (or other "transfer syntax"). In any case, I wouldn't know if memcpy would work with arrays (I'm not sure if it's guaranteed by DICOM that the subsequent members are stored consecutively, although it's very likely of course). In an attempt to handle this (and avoid horrible code repetition) I came up with the following modification for element2value() in dicominfo.cpp: ------------------ current code ------------------- if (vr & gdcm::VR::US) {// unsigned short uint16_t usval ; memcpy(&usval, elem->GetByteValue()->GetPointer(), 2); *ov=usval; if(chatty) octave_stdout << '[' << usval << "]\n"; } else ... // almost repeated for lots of VRs and types return DICOM_OK; -------------------- new code ----------------- if (vr & gdcm::VR::US) {// unsigned short return element2intvalueHelper<gdcm::VR::US>(ov, elem, chatty); } else ... // repeated for lots of VRs ---------------------- new function definition (in dicominfo.cpp) --------------------- template <gdcm::VR::VRType vrtype> int element2intvalueHelper(octave_value *ov, const gdcm::DataElement * elem, const int chatty) { if( !elem->IsEmpty() ) { // find type that corresponds to this VR typedef typename gdcm::VRToType<vrtype >::Type actual_type; gdcm::Element<vrtype,gdcm::VM::VM1_n> el; el.Set( elem->GetValue() ); intNDArray<octave_int<actual_type> > val(dim_vector (el.GetLength(),1)); for (unsigned i=0; i<el.GetLength(); ++i) val(i) = el.GetValue(i); *ov=val; if(chatty) octave_stdout << '[' << val << "]\n"; return DICOM_OK; } else { return DICOM_NOTHING_ASSIGNED; } } ------------------------------------------------------------------------- This seems to work. It might be somewhat inefficient though, as we're creating a temporary array, copying to an octave_value, and then getting rid of it. I'm not sure how to avoid this, or even if it's an issue. Also, it's annoying that I need to have 2 separate code sets for ints and floats (as I need intNDArray<octave_int<short> > etc because of missing constructors in octave_value). Any suggestions for improvements? Thanks Kris Thielemans Algorithms and Software Consulting Ltd Honorary Lecturer at Imperial College London ------------------------------------------------------------------------------ All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense. http://p.sf.net/sfu/splunk-novd2d _______________________________________________ Octave-dev mailing list Octave-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/octave-dev