⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdcmdicomdir.cxx

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 CXX
📖 第 1 页 / 共 3 页
字号:
      else if ( v == "VISIT " )
      {
         si = new DicomDirVisit(true);
         if ( !AddVisitToEnd( static_cast<DicomDirVisit *>(si)) )
         {
            delete si;
            si = NULL;
            gdcmErrorMacro( "Add AddVisitToEnd failed");
         }
      }
      else if ( v == "STUDY " )
      {
         si = new DicomDirStudy(true);
         if ( !AddStudyToEnd( static_cast<DicomDirStudy *>(si)) )
         {
            delete si;
            si = NULL;
            gdcmErrorMacro( "Add AddStudyToEnd failed");
         }
      }
      else if ( v == "PATIENT " )
      {
         si = new DicomDirPatient(true);
         if ( !AddPatientToEnd( static_cast<DicomDirPatient *>(si)) )
         {
            delete si;
            si = NULL;
            gdcmErrorMacro( "Add PatientToEnd failed");
         }
      }
      else
      {
         // It was neither a 'PATIENT', nor a 'STUDY', nor a 'SERIE',
         // nor an 'IMAGE' SQItem. Skip to next item.
         gdcmDebugMacro( " -------------------------------------------"
         << "a non PATIENT/STUDY/SERIE/IMAGE SQItem was found : "
         << v);

        // FIXME : deal with other item types !
        tmpSI=s->GetNextSQItem(); // To avoid infinite loop
        continue;
      }
      if ( si )
         //MoveSQItem(si,tmpSI); // Old code : Copies each Entry
                                 //  -and then removes the source-
         si->MoveObject(tmpSI);  // New code : Copies the List

      tmpSI=s->GetNextSQItem();
   }
   ClearEntry();
}

/**
 * \brief  AddPatientToEnd 
 * @param   dd SQ Item to enqueue to the DicomPatient chained List
 */
bool DicomDir::AddPatientToEnd(DicomDirPatient *dd)
{
   Patients.push_back(dd);
   return true;
}

/**
 * \brief  AddStudyToEnd 
 * @param   dd SQ Item to enqueue to the DicomDirStudy chained List
 */
bool DicomDir::AddStudyToEnd(DicomDirStudy *dd)
{
   if ( Patients.size() > 0 )
   {
      ListDicomDirPatient::iterator itp = Patients.end();
      itp--;
      (*itp)->AddStudy(dd);
      return true;
   }
   return false;
}

/**
 * \brief  AddSerieToEnd 
 * @param   dd SQ Item to enqueue to the DicomDirSerie chained List
 */
bool DicomDir::AddSerieToEnd(DicomDirSerie *dd)
{
   if ( Patients.size() > 0 )
   {
      ListDicomDirPatient::iterator itp = Patients.end();
      itp--;

      DicomDirStudy *study = (*itp)->GetLastStudy();
      if ( study )
      {
         study->AddSerie(dd);
         return true;
      }
   }
   return false;
}

/**
 * \brief  AddVisitToEnd 
 * @param   dd SQ Item to enqueue to the DicomDirVisit chained List
 */
bool DicomDir::AddVisitToEnd(DicomDirVisit *dd)
{
   if ( Patients.size() > 0 )
   {
      ListDicomDirPatient::iterator itp = Patients.end();
      itp--;

      DicomDirStudy *study = (*itp)->GetLastStudy();
      if ( study )
      {
         study->AddVisit(dd);
         return true;
      }
   }
   return false;
}
/**
 * \brief   AddImageToEnd
 * @param   dd SQ Item to enqueue to the DicomDirImage chained List
 */
bool DicomDir::AddImageToEnd(DicomDirImage *dd)
{
   if ( Patients.size() > 0 )
   {
      ListDicomDirPatient::iterator itp = Patients.end();
      itp--;

      DicomDirStudy *study = (*itp)->GetLastStudy();
      if ( study )
      {
         DicomDirSerie *serie = study->GetLastSerie();
         if ( serie )
         {
            serie->AddImage(dd);
            return true;
         }
      }
   }
   return false;
}

/**
 * \brief  for each Header of the chained list, 
 *         add/update the Patient/Study/Serie/Image info 
 * @param   path path of the root directory
 * @param   list chained list of Headers
 */
void DicomDir::SetElements(std::string const &path, VectDocument const &list)
{
   ClearEntry();
   ClearPatient();

   std::string patPrevName         = "", patPrevID  = "";
   std::string studPrevInstanceUID = "", studPrevID = "";
   std::string serPrevInstanceUID  = "", serPrevID  = "";

   std::string patCurName,         patCurID;
   std::string studCurInstanceUID, studCurID;
   std::string serCurInstanceUID,  serCurID;

   bool first = true;
   for( VectDocument::const_iterator it = list.begin();
                                     it != list.end(); 
                                   ++it )
   {
      // get the current file characteristics
      patCurName         = (*it)->GetEntryValue(0x0010,0x0010);
      patCurID           = (*it)->GetEntryValue(0x0010,0x0011);
      studCurInstanceUID = (*it)->GetEntryValue(0x0020,0x000d);
      studCurID          = (*it)->GetEntryValue(0x0020,0x0010);
      serCurInstanceUID  = (*it)->GetEntryValue(0x0020,0x000e);
      serCurID           = (*it)->GetEntryValue(0x0020,0x0011);

      if ( patCurName != patPrevName || patCurID != patPrevID || first )
      {
         SetElement(path, GDCM_DICOMDIR_PATIENT, *it);
         first = true;
      }

      // if new Study, deal with 'STUDY' Elements   
      if ( studCurInstanceUID != studPrevInstanceUID || studCurID != studPrevID 
         || first )
      {
         SetElement(path, GDCM_DICOMDIR_STUDY, *it);
         first = true;
      }

      // if new Serie, deal with 'SERIE' Elements   
      if ( serCurInstanceUID != serPrevInstanceUID || serCurID != serPrevID
         || first )
      {
         SetElement(path, GDCM_DICOMDIR_SERIE, *it);
      }
      
      // Always Deal with 'IMAGE' Elements  
      SetElement(path, GDCM_DICOMDIR_IMAGE, *it);

      patPrevName         = patCurName;
      patPrevID           = patCurID;
      studPrevInstanceUID = studCurInstanceUID;
      studPrevID          = studCurID;
      serPrevInstanceUID  = serCurInstanceUID;
      serPrevID           = serCurID;
      first = false;
   }
}

/**
 * \brief   adds to the HTable 
 *          the Entries (Dicom Elements) corresponding to the given type
 * @param   path full path file name (only used when type = GDCM_DICOMDIR_IMAGE
 * @param   type DicomDirObject type to create (GDCM_DICOMDIR_PATIENT,
 *          GDCM_DICOMDIR_STUDY, GDCM_DICOMDIR_SERIE ...)
 * @param   header Header of the current file
 */
void DicomDir::SetElement(std::string const &path, DicomDirType type,
                          Document *header)
{
   ListDicomDirElem elemList;
   ListDicomDirElem::const_iterator it;
   uint16_t tmpGr, tmpEl;
   DictEntry *dictEntry;
   ValEntry *entry;
   std::string val;
   SQItem *si;

   switch( type )
   {
      case GDCM_DICOMDIR_IMAGE:
         elemList = Global::GetDicomDirElements()->GetDicomDirImageElements();
         si = new DicomDirImage(true);
         if ( !AddImageToEnd(static_cast<DicomDirImage *>(si)) )
         {
            delete si;
            gdcmErrorMacro( "Add ImageToEnd failed");
         }
         break;
      case GDCM_DICOMDIR_SERIE:
         elemList = Global::GetDicomDirElements()->GetDicomDirSerieElements();
         si = new DicomDirSerie(true);
         if ( !AddSerieToEnd(static_cast<DicomDirSerie *>(si)) )
         {
            delete si;
            gdcmErrorMacro( "Add SerieToEnd failed");
         }
         break;
      case GDCM_DICOMDIR_STUDY:
         elemList = Global::GetDicomDirElements()->GetDicomDirStudyElements();
         si = new DicomDirStudy(true);
         if ( !AddStudyToEnd(static_cast<DicomDirStudy *>(si)) )
         {
            delete si;
            gdcmErrorMacro( "Add StudyToEnd failed");
         }
         break;
      case GDCM_DICOMDIR_PATIENT:
         elemList = Global::GetDicomDirElements()->GetDicomDirPatientElements();
         si = new DicomDirPatient(true);
         if ( !AddPatientToEnd(static_cast<DicomDirPatient *>(si)) )
         {
            delete si;
            gdcmErrorMacro( "Add PatientToEnd failed");
         }
         break;
      case GDCM_DICOMDIR_META:
         elemList = Global::GetDicomDirElements()->GetDicomDirMetaElements();
         si = new DicomDirMeta(true);
         if ( MetaElems )
         {
            delete MetaElems;
            gdcmErrorMacro( "MetaElements already exist, they will be destroyed");
         }
         MetaElems = static_cast<DicomDirMeta *>(si);
         break;
      default:
         return;
   }

   // FIXME : troubles found when it's a SeqEntry

   // removed all the seems-to-be-useless stuff about Referenced Image Sequence
   // to avoid further troubles
   // imageElem 0008 1140 "" // Referenced Image Sequence
   // imageElem fffe e000 "" // 'no length' item : length to be set to 0xffffffff later
   // imageElem 0008 1150 "" // Referenced SOP Class UID    : to be set/forged later
   // imageElem 0008 1155 "" // Referenced SOP Instance UID : to be set/forged later
   // imageElem fffe e00d "" // Item delimitation : length to be set to ZERO later
 
   // for all the relevant elements found in their own spot of the DicomDir.dic
   for( it = elemList.begin(); it != elemList.end(); ++it)
   {
      tmpGr     = it->Group;
      tmpEl     = it->Elem;
      dictEntry = GetPubDict()->GetEntry(tmpGr, tmpEl);

      entry     = new ValEntry( dictEntry ); // Be sure it's never a BinEntry !

      entry->SetOffset(0); // just to avoid further missprinting

      if ( header )
      {
         // NULL when we Build Up (ex nihilo) a DICOMDIR
         //   or when we add the META elems
         val = header->GetEntryValue(tmpGr, tmpEl);
      }
      else
      {
         val = GDCM_UNFOUND;
      }

      if ( val == GDCM_UNFOUND) 
      {
         if ( tmpGr == 0x0004 && tmpEl == 0x1130 ) // File-set ID
         {
           // force to the *end* File Name
           val = Util::GetName( path );
         }
         else if ( tmpGr == 0x0004 && tmpEl == 0x1500 ) // Only used for image
         {
            if ( header->GetFileName().substr(0, path.length()) != path )
            {
               gdcmWarningMacro( "The base path of file name is incorrect");
               val = header->GetFileName();
            }
            else
            {
               val = &(header->GetFileName().c_str()[path.length()]);
            }
         }
         else
         {
            val = it->Value;
         }
      }
      else
      {
         if ( header->GetEntryLength(tmpGr,tmpEl) == 0 )
            val = it->Value;
      }

      entry->SetValue( val ); // troubles expected when vr=SQ ...

      if ( type == GDCM_DICOMDIR_META ) // fusible : should never print !
      {
         gdcmDebugMacro("GDCM_DICOMDIR_META ?!? should never print that");
      }
      si->AddEntry(entry);
   }
}

/**
 * \brief   Move the content of the source SQItem to the destination SQItem
 *          Only DocEntry's are moved
 * @param dst destination SQItem
 * @param src source SQItem
 */
void DicomDir::MoveSQItem(DocEntrySet *dst, DocEntrySet *src)
{ 
   DocEntry *entry;
// todo : rewrite the whole stuff, without using RemoveEntry an AddEntry,
//        to save time
   entry = src->GetFirstEntry();
   while(entry)
   {
      src->RemoveEntryNoDestroy(entry);
      dst->AddEntry(entry);
      // we destroyed -> the current iterator is not longer valid
      entry = src->GetFirstEntry();
   }
}

/**
 * \brief   compares two files
 */
bool DicomDir::HeaderLessThan(Document *header1, Document *header2)
{
   return *header1 < *header2;
}

//-----------------------------------------------------------------------------
// Print
/**
 * \brief  Canonical Printer 
 * @param   os ostream we want to print in
 * @param indent Indentation string to be prepended during printing
 */
void DicomDir::Print(std::ostream &os, std::string const & )
{
   if ( MetaElems )
   {
      MetaElems->SetPrintLevel(PrintLevel);
      MetaElems->Print(os);   
   }   
   for(ListDicomDirPatient::iterator cc  = Patients.begin();
                                     cc != Patients.end();
                                   ++cc)
   {
     (*cc)->SetPrintLevel(PrintLevel);
     (*cc)->Print(os);
   }
}

//-----------------------------------------------------------------------------
} // end namespace gdcm

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -