00001 #include <creaImageIOGimmickView.h>
00002 #include <creaImageIOSystem.h>
00003 #include "boost/filesystem.hpp"
00004
00005 #if defined(USE_GDCM)
00006 #include <gdcmGlobal.h>
00007 #include <gdcmSerieHelper.h>
00008 #include <vtkGdcmReader.h>
00009 #endif
00010
00011 #if defined(USE_GDCM2)
00012 #include <vtkGDCMImageReader.h>
00013 #include "gdcmSystem.h"
00014 #include "gdcmCryptographicMessageSyntax.h"
00015 #include "gdcmUIDGenerator.h"
00016 #include "gdcmAnonymizer.h"
00017 #include "gdcmGlobal.h"
00018 #endif
00019
00020
00021 namespace fs = boost::filesystem;
00022 namespace creaImageIO
00023 {
00024
00026 class ImageExtent
00027 {
00028 public:
00029 ImageExtent(const std::string& x, const std::string& y, const std::string& z, const std::string& t)
00030 {
00031 sscanf(x.c_str(),"%d",&mExtent[0]);
00032 sscanf(y.c_str(),"%d",&mExtent[1]);
00033 sscanf(z.c_str(),"%d",&mExtent[2]);
00034 sscanf(t.c_str(),"%d",&mExtent[3]);
00035 if(x==""){mExtent[0]=1;}
00036 if(y==""){mExtent[1]=1;}
00037 if(z==""){mExtent[2]=1;}
00038 if(t==""){mExtent[3]=1;}
00039
00040 if (mExtent[3]>1) mDim=4;
00041 else if (mExtent[2]>1) mDim=3;
00042 else if (mExtent[1]>1) mDim=2;
00043 else if (mExtent[0]>1) mDim=1;
00044 else mDim=0;
00045 }
00046
00047
00049 void Clear() { mExtent[0] = mExtent[1] = mExtent[2] = mExtent[3] = 1; }
00050
00052 bool IsCompatible( const ImageExtent& );
00053
00055 void Add ( const ImageExtent& );
00056
00058 int Get(int i) { return mExtent[i]; }
00059
00061 void SetDimension(int dim) { mDim=dim; }
00062
00064 int GetDimension() { return mDim; }
00065
00066 private:
00067 int mExtent[4];
00068 int mDim;
00069 };
00070
00071
00072
00073
00074
00075 GimmickView::GimmickView(boost::shared_ptr<Gimmick> gimmick, int threads)
00076 : mGimmick(gimmick),
00077 mReader(threads)
00078 {
00079 GimmickDebugMessage(1,"GimmickView::GimmickView"
00080 <<std::endl);
00081
00082
00083
00084
00085 }
00086
00087
00088
00090 GimmickView::~GimmickView()
00091 {
00092 GimmickDebugMessage(1,"GimmickView::~GimmickView"
00093 <<std::endl);
00094 }
00095
00096
00097
00101 void GimmickView::Initialize()
00102 {
00103 mReaderStarted=false;
00104 }
00105
00106
00107
00109 void GimmickView::Finalize()
00110 {
00111 }
00112
00113
00114
00115
00117 void GimmickView::CreateTreeViews()
00118 {
00119 GimmickMessage(2,"Creating the tree views"<<std::endl);
00120 Gimmick::TreeHandlerMapType::const_iterator i;
00121 for (i = mGimmick->GetTreeHandlerMap().begin();
00122 i!= mGimmick->GetTreeHandlerMap().end();
00123 ++i)
00124 {
00125 this->CreateTreeView(i->second);
00126 }
00127 }
00128
00130 void GimmickView::CreateSingleTreeView(std::string &i_name)
00131 {
00132 this->CreateTreeView(mGimmick->GetTreeHandlerMap()[i_name]);
00133
00134 }
00135
00136
00137
00138
00139
00142 void GimmickView::UpdateTreeViewLevel(const std::string& t, int l)
00143 {
00144 TreeViewMapType::iterator i;
00145 i = GetTreeViewMap().find(t);
00146 if ( i == GetTreeViewMap().end() )
00147 {
00148 GimmickError("INTERNAL ERROR : GimmickView::UpdateTreeView : '"
00149 <<t<<"' is not in TreeViewMap");
00150 }
00151 i->second->UpdateLevel(l);
00152 }
00153
00154
00156 void GimmickView::ResetExtent()
00157 {
00158 if(mImageExtent!=0)
00159 {
00160 mImageExtent.reset();
00161 }
00162 valid=true;
00163 }
00164
00165
00166
00167
00168 bool ImageExtent::IsCompatible(const ImageExtent& ie)
00169 {
00170 bool compatible=true;
00171 ImageExtent * extent= (ImageExtent*)&ie;
00172 if((*extent).Get(0)!=Get(0)
00173 || (*extent).Get(1)!=Get(1))
00174 {
00175 compatible=false;
00176 }
00177 return compatible;
00178 }
00179
00180
00181
00182
00183 void ImageExtent::Add(const ImageExtent& ie)
00184 {
00185 ImageExtent * extent= (ImageExtent*)&ie;
00186 mExtent[2]+=(*extent).Get(2);
00187 if(mExtent[2]>1)
00188 {
00189 SetDimension(3);
00190 }
00191 }
00192
00193
00195 bool GimmickView::NoValidateSelected ()
00196 {
00197 GimmickDebugMessage(2,"Validating selected"<<std::endl);
00198 std::string mMessage;
00199 mMessage="Cannot have 0 images selected!";
00200 valid=false;
00201 modifyValidationSignal(valid);
00202 SetMessage(mMessage);
00203 return valid;
00204 }
00205
00206
00209 bool GimmickView::ValidateSelected (tree::Node* sel, int min_dim, int max_dim)
00210 {
00211 GimmickDebugMessage(2,"Validating selected"<<std::endl);
00212 std::string mMessage;
00213
00214 if(sel==0)
00215 {
00216 mMessage="Cannot have 0 images selected!";
00217 valid=false;
00218 }
00219 else
00220 {
00221 boost::shared_ptr<ImageExtent> ie=boost::shared_ptr<ImageExtent>(new ImageExtent((*sel).GetAttribute("D0028_0010"),
00222 (*sel).GetAttribute("D0028_0011"),
00223 (*sel).GetAttribute("D0028_0012"),
00224 ""));
00225
00226 if(mImageExtent==0)
00227 {
00228 mImageExtent=ie;
00229 if((mImageExtent->Get(min_dim-1)<2)||(mImageExtent->Get(max_dim)>1))
00230 {
00231 valid=false;
00232 }
00233 else
00234 {
00235 std::stringstream out;
00236 out << mImageExtent->GetDimension() << "D image " << mImageExtent->Get(0) << "x"<< mImageExtent->Get(1) << "x"<< mImageExtent->Get(2) <<" selected";
00237 mMessage = out.str();
00238 mImageExtent->SetDimension(2);
00239 valid=true;
00240 }
00241 }
00242 else
00243 {
00244 if(mImageExtent->IsCompatible(*ie))
00245 {
00246 if(mImageExtent->GetDimension()==max_dim && mImageExtent->Get(max_dim)>2)
00247 {
00248 std::stringstream out;
00249 out<<"Cannot add this image to selection : would result in a "<<mImageExtent->GetDimension()+1<<"D image!";
00250 mMessage=out.str();
00251 valid=false;
00252 }
00253 else if(max_dim<3)
00254 {
00255 std::stringstream out;
00256 out<<"Selecting "<<mImageExtent->GetDimension()<<"D images is not allowed !";
00257 mMessage=out.str();
00258 valid=false;
00259 }
00260 else if(min_dim==3 && (ie->Get(2)+mImageExtent->Get(2))<2)
00261 {
00262 std::stringstream out;
00263 out << "Cannot build the selection as it would result in a ";
00264 out << mImageExtent->GetDimension();
00265 out << "D image, and the minimum is ";
00266 out << min_dim;
00267 out << "D!";
00268 mMessage=out.str();
00269 valid=false;
00270 }
00271 else
00272 {
00273 mImageExtent->Add(*ie);
00274 std::stringstream out;
00275 out << mImageExtent->GetDimension() << "D image " << mImageExtent->Get(0) << "x"<< mImageExtent->Get(1) << "x"<< mImageExtent->Get(2) <<" selected";
00276 mMessage = out.str();
00277 }
00278 }
00279 else
00280 {
00281 mMessage="The selected images are not compatible.";
00282 valid=false;
00283 }
00284 }
00285 }
00286
00287 modifyValidationSignal(valid);
00288 SetMessage(mMessage);
00289 return valid;
00290 }
00291
00292
00293 void GimmickView::modifyValidationSignal(bool ivalid)
00294 {
00295
00296 mValidationSignal(ivalid);
00297 }
00298
00299 void GimmickView::stopReader()
00300 {
00301 mReader.Stop();
00302 }
00303
00304
00306 void GimmickView::ReadImagesNotThreaded(std::vector<vtkImageData*>& s, std::vector<std::string> im, int dimension)
00307 {
00308 stopReader();
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 if (im.size()==1)
00323 {
00324 vtkImageData * out=vtkImageData::New();
00325 out->ShallowCopy(mReader.GetImage(im.front()));
00326 s.push_back(out);
00327 }
00328 else if (im.size()>1)
00329 {
00330 vtkImageData* first = mReader.GetImage( im.front());
00331 if (dimension == 2)
00332 {
00333
00334 std::vector<std::string>::iterator it;
00335 for (it=im.begin(); it!=im.end(); ++it)
00336 {
00337 vtkImageData* out = vtkImageData::New();
00338 out->ShallowCopy(mReader.GetImage(*it));
00339 s.push_back(out);
00340 }
00341 }
00342 else
00343 {
00344
00345 vtkImageData* out = vtkImageData::New();
00346
00347 out->SetScalarType(first->GetScalarType());
00348 out->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents());
00349 int ext[6];
00350
00351 first->GetWholeExtent(ext);
00352
00353 if(ext[5] == 0)
00354 {
00355 ext[5] = im.size()-1;
00356 }
00357 else
00358 {
00359 ext[5] = ext[5] * im.size()-1;
00360 }
00361 out->SetExtent(ext);
00362
00363
00364
00365 int dim[3];
00366 first->GetDimensions(dim);
00367
00368 out->SetDimensions(dim[0], dim[1], im.size() );
00369 out->AllocateScalars();
00370 out->Update();
00371
00372 unsigned long imsize = dim[0] * dim[1];
00373 imsize = imsize * dim[2] ;
00374
00375
00376
00377
00378
00379 imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents();
00380
00381
00382
00383
00384 double spc[3];
00385 first->GetSpacing(spc);
00386
00387
00388
00389
00390 spc[2] =1;
00391
00392 out->SetSpacing(spc);
00393
00394 int slice = 0;
00395 std::vector<std::string>::iterator it;
00396
00397 for (it=im.begin(); it!=im.end(); ++it)
00398 {
00399 vtkImageData* cur = mReader.GetImage( (*it) );
00400 memcpy(out->GetScalarPointer(0,0,slice), cur->GetScalarPointer(0,0,0), imsize);
00401 slice++;
00402 }
00403 s.push_back(out);
00404
00405 }
00406
00407 }
00408
00409 }
00410
00411
00412
00413
00415
00416
00417
00419 bool GimmickView::isSingle(const std::string i_file)
00420 {
00421 bool bres = true;
00422 vtkImageData* first = mReader.GetImage( i_file);
00423 int dim[3];
00424 first->GetDimensions(dim);
00425 if (dim[2] > 1)
00426 {
00427 bres = false;
00428 }
00429 else
00430 {
00431 }
00432 return bres;
00433 }
00434
00436
00438
00439 void GimmickView::getAttributes(const std::string i_file, std::map<std::string, std::string> &o_infos, OutputAttr i_attr)
00440 {
00441 if(i_attr.inside.size() >0)
00442 {
00443 mGimmick->GetAttributes(i_file,o_infos,i_attr);
00444 }
00445 if(i_attr.outside.size()>0)
00446 {
00447 mReader.getAttributes(i_file,o_infos, i_attr.outside);
00448 }
00449 }
00450
00452
00454 void GimmickView::readImages1(std::vector<OutStrGimmick>& o_output, std::vector<std::string> im,
00455 OutputAttr i_attr)
00456 {
00457 std::vector<std::string>::iterator it;
00458 for (it=im.begin(); it!=im.end(); ++it)
00459 {
00460 OutStrGimmick out;
00461 out.img = vtkImageData::New();
00462 out.img->ShallowCopy(mReader.GetImage(*it));
00463 if(i_attr.mult)
00464 getAttributes((*it),out.infos,i_attr);
00465 o_output.push_back(out);
00466 }
00467
00468 if(!i_attr.mult)
00469 {
00470 getAttributes(im.front(), o_output.front().infos, i_attr);
00471 }
00472
00473 }
00474
00476
00478 void GimmickView::readImages3(std::vector<OutStrGimmick>& o_output, std::vector<std::string> im,
00479 OutputAttr i_attr, double i_zspc)
00480 {
00481 OutStrGimmick out;
00482 vtkImageData* first = mReader.GetImage( im.front());
00483 out.img = vtkImageData::New();
00484 out.img->SetScalarType(first->GetScalarType());
00485 out.img->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents());
00486 int ext[6];
00487 first->GetWholeExtent(ext);
00488 if(ext[5] == 0)
00489 {
00490 ext[5] = im.size()-1;
00491 }
00492 else
00493 {
00494 ext[5] = ext[5] * im.size()-1;
00495 }
00496 out.img->SetExtent(ext);
00497 int dim[3];
00498 first->GetDimensions(dim);
00499 out.img->SetDimensions(dim[0], dim[1], im.size() );
00500 out.img->AllocateScalars();
00501 out.img->Update();
00502 unsigned long imsize = dim[0] * dim[1];
00503 imsize = imsize * dim[2] ;
00504
00505
00506 imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents();
00507
00509 int slice = 0;
00510 std::vector<std::string>::iterator it;
00511 for (it=im.begin(); it!=im.end(); ++it)
00512 {
00513 vtkImageData* cur = mReader.GetImage( (*it) );
00514 memcpy(out.img->GetScalarPointer(0,0,slice), cur->GetScalarPointer(0,0,0), imsize);
00515 slice++;
00516 }
00517 getAttributes(im.front(),out.infos, i_attr);
00518 o_output.push_back(out);
00519 }
00520
00521
00522
00524
00526 void GimmickView::readImages2(std::vector<OutStrGimmick>& o_output, std::vector<std::string> im,
00527 OutputAttr i_attr, double i_zspc)
00528 {
00529 vtkImageData* first = mReader.GetImage( im.front());
00530 int dim[3];
00531 first->GetDimensions(dim);
00532
00533
00534 unsigned long imsize = dim[0] * dim[1];
00535 imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents();
00536
00537
00538 std::vector<std::string>::iterator it;
00539 std::vector<OutStrGimmick>::iterator it_out = o_output.begin();
00540
00541 for (it=im.begin(); it!=im.end(); ++it, it_out += dim[2])
00542 {
00543 vtkImageData* cur = mReader.GetImage( (*it) );
00544 for (int slice= 0 ; slice <dim[2]; slice++)
00545 {
00546 OutStrGimmick out;
00547 out.img = vtkImageData::New();
00548 out.img->SetScalarType(first->GetScalarType());
00549
00550 out.img->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents());
00551 int ext[6];
00552 first->GetWholeExtent(ext);
00553 ext[5] = 0;
00554 out.img->SetExtent(ext);
00555
00556 out.img->SetDimensions(dim[0], dim[1], 1 );
00557 out.img->AllocateScalars();
00558 out.img->Update();
00559 memcpy(out.img->GetScalarPointer(0,0,0), cur->GetScalarPointer(0,0,slice), imsize);
00560 o_output.push_back(out);
00561 }
00562 if(i_attr.mult)
00563 getAttributes((*it),(*it_out).infos,i_attr);
00564 }
00565 if(!i_attr.mult)
00566 {
00567 getAttributes(im.front(), o_output.front().infos,i_attr);
00568 }
00569
00570 }
00571
00573
00575 void GimmickView::readImages4(std::vector<OutStrGimmick>& o_output, std::vector<std::string> im,
00576 OutputAttr i_attr)
00577 {
00578 std::vector<std::string>::iterator it;
00579 std::vector<OutStrGimmick>::iterator it_out = o_output.begin();
00580 vtkImageData* first = mReader.GetImage( im.front());
00581 int dim[3];
00582 first->GetDimensions(dim);
00583
00584 for (int slice= 0 ; slice <dim[2]; slice++)
00585 {
00586 OutStrGimmick out;
00587 out.img = vtkImageData::New();
00588 out.img->SetScalarType(first->GetScalarType());
00589 out.img->SetNumberOfScalarComponents(first->GetNumberOfScalarComponents());
00590
00591 int ext[6];
00592 first->GetWholeExtent(ext);
00593 ext[5] = 0;
00594 out.img->SetExtent(ext);
00595
00596 out.img->SetDimensions(dim[0], dim[1], im.size() );
00597 out.img->AllocateScalars();
00598 out.img->Update();
00599 unsigned long imsize = dim[0] * dim[1];
00600 imsize = imsize * first->GetScalarSize() * first->GetNumberOfScalarComponents();
00601 int index = 0;
00602
00603 for (it=im.begin(); it!=im.end(); ++it, index ++)
00604 {
00605 vtkImageData* cur = mReader.GetImage( (*it) );
00606 memcpy(out.img->GetScalarPointer(0,0,index), cur->GetScalarPointer(0,0,slice), imsize);
00607 o_output.push_back(out);
00608 }
00609 }
00610 if(!i_attr.mult)
00611 {
00612 getAttributes(im.front(), o_output.front().infos,i_attr);
00613 }
00614
00615 }
00616
00617
00619
00620
00622 void GimmickView::readImages(std::vector<OutStrGimmick>& o_output, std::vector<std::string> im,
00623 OutputAttr i_attr, int i_dim, double i_zspc)
00624 {
00625 int size = im.size();
00626 if ( size == 0)
00627 {
00628 return;
00629 }
00630 else if (size == 1)
00631 {
00632
00633
00634
00635 if ( isSingle(im.front()) || i_dim != 1)
00636 {
00637 readImages1(o_output,im, i_attr);
00638 }
00639 else
00640 {
00641 readImages2(o_output,im, i_attr,i_zspc);
00642 }
00643
00644 }
00645 else
00646 {
00647
00648 if ( isSingle(im.front()) )
00649 {
00650
00651 if(i_dim == 1)
00652 {
00653
00654 readImages3(o_output,im, i_attr,i_zspc);
00655 }
00656 else
00657 {
00658 readImages1(o_output,im, i_attr);
00659 }
00660 }
00661 else
00662 {
00663
00664
00665 if(i_dim == 1)
00666 {
00667
00668 readImages3(o_output,im, i_attr,i_zspc);
00669
00670 }
00671 else if( i_dim == 2)
00672 {
00673
00674 readImages2(o_output,im, i_attr,i_zspc);
00675 }
00676 else if( i_dim == 3)
00677 {
00678
00679
00680 readImages1(o_output,im, i_attr);
00681 }
00682 else
00683 {
00684
00685 readImages4(o_output,im, i_attr);
00686 }
00687 }
00688 }
00689 }
00690
00691
00692
00693 void GimmickView::ReadImagesNotThreadedInVector(std::vector<vtkImageData*>& s, std::vector<std::string> im, int dimension)
00694 {
00695
00696 if (im.size()==1)
00697 {
00698
00699 vtkImageData* out = vtkImageData::New();
00700 GimmickDebugMessage(3, "State Check: Full Filename: "
00701 <<im.front()
00702 <<std::endl);
00703 out->ShallowCopy(mReader.GetImage(im.front()));
00704 s.push_back( out );
00705 }
00706 else if (im.size()>1)
00707 {
00708 vtkImageData* first = mReader.GetImage( im.front());
00709 if (dimension == 2)
00710 {
00711
00712 std::vector<std::string>::iterator it;
00713 for (it=im.begin(); it!=im.end(); ++it)
00714 {
00715 vtkImageData* out = vtkImageData::New();
00716 out->ShallowCopy(mReader.GetImage(*it));
00717 s.push_back(out);
00718 }
00719 }
00720 else
00721 {
00722
00723
00724
00725 std::vector<std::string>::iterator it;
00726 for (it=im.begin(); it!=im.end(); ++it)
00727 {
00728 vtkImageData* out = mReader.GetImage( (*it));
00729 s.push_back(out);
00730 }
00731 }
00732 }
00733 }
00734
00735
00736
00738 void GimmickView::RequestReading(tree::Node* n,
00739 int prio, int selection_index, boost::shared_ptr<ImagePointerHolder> p)
00740 {
00741 if(!mReaderStarted)
00742 {
00743 mReader.Start();
00744 mReaderStarted=true;
00745 }
00746 ImageEventType t(n,selection_index);
00747 t.pointerHolder = p;
00748 mImageEventMap[n->GetAttribute("FullFileName")] = t;
00749 mReader.Request(this,n->GetAttribute("FullFileName"),prio);
00750 }
00751
00752
00753
00754 void GimmickView::
00755 OnMultiThreadImageReaderEvent(const std::string& filename,
00756 MultiThreadImageReaderUser::EventType e,
00757 vtkImageData* image)
00758 {
00759 GimmickDebugMessage(7,
00760 "MultiThreadImageReader event : "<<e<<std::endl);
00761 if (e==ImageLoaded)
00762 {
00763 if (filename.size()==0)
00764 {
00765
00766
00767
00768
00769
00770
00771 return;
00772 }
00773 ImageEventTypeMap::iterator i;
00774
00775 if(mImageEventMap.size()>0){
00776 i = mImageEventMap.find(filename);
00777 if (i!=mImageEventMap.end())
00778 {
00779 GimmickDebugMessage(5,
00780 "Putting image of file '"<<filename<<"' on pointer"
00781 <<std::endl);
00782 ImageEventType ie(i->second);
00783 ie.image = image;
00784 ie.pointerHolder->Set(ie.image);
00785
00786 }
00787 }
00788 }
00789 else if (e==Error)
00790 {
00791 std::string mess="ERROR: MultiThreadImageReader: Cannot read image in file ";
00792 mess+=filename;
00793 mess+="\n";
00794 GimmickMessage(1,mess);
00795 ImageEventTypeMap::iterator i;
00796 i = mImageEventMap.find(filename);
00797 if (i!=mImageEventMap.end())
00798 {
00799 ImageEventType ie(i->second);
00800 ie.image = image;
00801 ie.pointerHolder->Set(GetDefaultImage());
00802
00803 }
00804 }
00805
00806 else if (e==ImageUnloaded)
00807 {
00808 std::string mess="Unloaded image in file ";
00809 mess+=filename;
00810 mess+="\n";
00811 GimmickMessage(1,mess);
00812 ImageEventTypeMap::iterator i;
00813 i = mImageEventMap.find(filename);
00814 if (i!=mImageEventMap.end())
00815 {
00816 ImageEventType ie(i->second);
00817 ie.image = image;
00818 ie.pointerHolder->Set(GetDefaultImage());
00819
00820 }
00821 }
00822 }
00823
00824
00825
00826
00827 void GimmickView::ConnectValidationObserver(ValidationCallbackType callback)
00828 {
00829 mValidationSignal.connect(callback);
00830 }
00831
00832
00833
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 }