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

📄 gdcmdicomdir.cxx

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 CXX
📖 第 1 页 / 共 3 页
字号:
   return NULL;
}

/**
 * \brief  fills the whole structure, starting from a root Directory
 */
void DicomDir::ParseDirectory()
{
   CreateDicomDirChainedList( GetFileName() );
   CreateDicomDir();
}

void DicomDir::SetStartMethod( DicomDir::Method *method, void *arg )
{
   SetStartMethod(method,arg,NULL);
}

void DicomDir::SetProgressMethod( DicomDir::Method *method, void *arg )
{
   SetProgressMethod(method,arg,NULL);
}

void DicomDir::SetEndMethod( DicomDir::Method *method, void *arg )
{
   SetEndMethod(method,arg,NULL);
}

/**
 * \brief   Set the start method to call when the parsing of the
 *          directory starts.
 * @param   method Method to call
 * @param   arg    Argument to pass to the method
 * @param   argDelete    Argument 
 * \warning In python : the arg parameter isn't considered
 */
void DicomDir::SetStartMethod( DicomDir::Method *method, void *arg, 
                               DicomDir::Method *argDelete )
{
   if ( StartArg && StartMethodArgDelete )
   {
      StartMethodArgDelete( StartArg );
   }

   StartMethod          = method;
   StartArg             = arg;
   StartMethodArgDelete = argDelete;
}


/**
 * \brief   Set the progress method to call when the parsing of the
 *          directory progress
 * @param   method Method to call
 * @param   arg    Argument to pass to the method
 * @param   argDelete    Argument  
 * \warning In python : the arg parameter isn't considered
 */
void DicomDir::SetProgressMethod( DicomDir::Method *method, void *arg, 
                                  DicomDir::Method *argDelete )
{
   if ( ProgressArg && ProgressMethodArgDelete )
   {
      ProgressMethodArgDelete( ProgressArg );
   }

   ProgressMethod          = method;
   ProgressArg             = arg;
   ProgressMethodArgDelete = argDelete;
}

/**
 * \brief   Set the end method to call when the parsing of the directory ends
 * @param   method Method to call
 * @param   arg    Argument to pass to the method
 * @param   argDelete    Argument 
 * \warning In python : the arg parameter isn't considered
 */
void DicomDir::SetEndMethod( DicomDir::Method *method, void *arg, 
                             DicomDir::Method *argDelete )
{
   if ( EndArg && EndMethodArgDelete )
   {
      EndMethodArgDelete( EndArg );
   }

   EndMethod          = method;
   EndArg             = arg;
   EndMethodArgDelete = argDelete;
}

/**
 * \brief   Set the method to delete the argument
 *          The argument is destroyed when the method is changed or when the
 *          class is destroyed
 * @param   method Method to call to delete the argument
 */
void DicomDir::SetStartMethodArgDelete( DicomDir::Method *method ) 
{
   StartMethodArgDelete = method;
}

/**
 * \brief   Set the method to delete the argument
 *          The argument is destroyed when the method is changed or when the 
 *          class is destroyed          
 * @param   method Method to call to delete the argument
 */
void DicomDir::SetProgressMethodArgDelete( DicomDir::Method *method )
{
   ProgressMethodArgDelete = method;
}

/**
 * \brief   Set the method to delete the argument
 *          The argument is destroyed when the method is changed or when
 *          the class is destroyed
 * @param   method Method to call to delete the argument
 */
void DicomDir::SetEndMethodArgDelete( DicomDir::Method *method )
{
   EndMethodArgDelete = method;
}

/**
 * \brief    writes on disc a DICOMDIR
 * \ warning does NOT add the missing elements in the header :
 *           it's up to the user doing it !
 * @param  fileName file to be written to 
 * @return false only when fail to open
 */
 
bool DicomDir::Write(std::string const &fileName) 
{  
   int i;
   uint16_t sq[6] = { 0x0004, 0x1220, 0x5153, 0x0000, 0xffff, 0xffff };
   uint16_t sqt[4]= { 0xfffe, 0xe0dd, 0x0000, 0x0000 };

   std::ofstream *fp = new std::ofstream(fileName.c_str(),  
                                         std::ios::out | std::ios::binary);
   if ( !fp ) 
   {
      gdcmWarningMacro("Failed to open(write) File: " << fileName.c_str());
      return false;
   }

   char filePreamble[128];
   memset(filePreamble, 0, 128);
   fp->write(filePreamble, 128);
   binary_write( *fp, "DICM");
 
   DicomDirMeta *ptrMeta = GetMeta();
   ptrMeta->WriteContent(fp, ExplicitVR);
   
   // force writing 0004|1220 [SQ ], that CANNOT exist within DicomDirMeta
   for(i=0;i<6;++i)
   {
      binary_write(*fp, sq[i]);
   }
        
   for(ListDicomDirPatient::iterator cc  = Patients.begin();
                                     cc != Patients.end();
                                   ++cc )
   {
      (*cc)->WriteContent( fp, ExplicitVR );
   }
   
   // force writing Sequence Delimitation Item
   for(i=0;i<4;++i)
   {
      binary_write(*fp, sqt[i]);  // fffe e0dd 0000 0000 
   }

   fp->close();
   delete fp;

   return true;
}

/**
 * \brief    Anonymize a DICOMDIR
 * @return true 
 */
 
bool DicomDir::Anonymize() 
{
   ValEntry *v;
   // Something clever to be found to forge the Patient names
   itksys_ios::ostringstream s;
   int i = 1;
   for(ListDicomDirPatient::iterator cc = Patients.begin();
                                     cc!= Patients.end();
                                   ++cc)
   {
      s << i;
      v = (*cc)->GetValEntry(0x0010, 0x0010) ; // Patient's Name
      if (v)
      {
         v->SetValue(s.str());
      }

      v = (*cc)->GetValEntry(0x0010, 0x0020) ; // Patient ID
      if (v)
      {
         v->SetValue(" ");
      }

      v = (*cc)->GetValEntry(0x0010, 0x0030) ; // Patient's BirthDate
      if (v)
      {
         v->SetValue(" ");
      }
      s << "";
      i++;
   }
   return true;
}

//-----------------------------------------------------------------------------
// Protected
/**
 * \brief create a Document-like chained list from a root Directory 
 * @param path entry point of the tree-like structure
 */
void DicomDir::CreateDicomDirChainedList(std::string const &path)
{
   CallStartMethod();
   DirList dirList(path,1); // gets recursively the file list
   unsigned int count = 0;
   VectDocument list;
   File *f;

   DirListType fileList = dirList.GetFilenames();

   for( DirListType::iterator it  = fileList.begin();
                              it != fileList.end();
                              ++it )
   {
      Progress = (float)(count+1)/(float)fileList.size();
      CallProgressMethod();
      if ( Abort )
      {
         break;
      }

      f = new File( );
      f->SetLoadMode(LoadMode); // we allow user not to load Sequences, 
                                //        or Shadow groups, or ......
      f->SetFileName( it->c_str() );
   /*int res = */f->Load( );

      if ( f->IsReadable() )
      {
         // Add the file to the chained list:
         list.push_back(f);
         gdcmDebugMacro( "Readable " << it->c_str() );
       }
       else
       {
          delete f;
       }
       count++;
   }
   // sorts Patient/Study/Serie/
   std::sort(list.begin(), list.end(), DicomDir::HeaderLessThan );
   
   std::string tmp = dirList.GetDirName();      
   //for each File of the chained list, add/update the Patient/Study/Serie/Image info
   SetElements(tmp, list);
   CallEndMethod();

   for(VectDocument::iterator itDoc=list.begin();
       itDoc!=list.end();
       ++itDoc)
   {
      delete dynamic_cast<File *>(*itDoc);
   }
}

/**
 * \brief   CallStartMethod
 */
void DicomDir::CallStartMethod()
{
   Progress = 0.0f;
   Abort    = false;
   if ( StartMethod )
   {
      StartMethod( StartArg );
   }
}

/**
 * \brief   CallProgressMethod
 */
void DicomDir::CallProgressMethod()
{
   if ( ProgressMethod )
   {
      ProgressMethod( ProgressArg );
   }
}

/**
 * \brief   CallEndMethod
 */
void DicomDir::CallEndMethod()
{
   Progress = 1.0f;
   if ( EndMethod )
   {
      EndMethod( EndArg );
   }
}

//-----------------------------------------------------------------------------
// Private
/**
 * \brief Sets all fields to NULL
 */
void DicomDir::Initialize()
{
   StartMethod             = NULL;
   ProgressMethod          = NULL;
   EndMethod               = NULL;
   StartMethodArgDelete    = NULL;
   ProgressMethodArgDelete = NULL;
   EndMethodArgDelete      = NULL;
   StartArg                = NULL;
   ProgressArg             = NULL;
   EndArg                  = NULL;

   Progress = 0.0;
   Abort = false;

   MetaElems = NULL;   
}

/**
 * \brief create a 'gdcm::DicomDir' from a DICOMDIR Header 
 */
void DicomDir::CreateDicomDir()
{
   // The SeqEntries of "Directory Record Sequence" are parsed. 
   //  When a DicomDir tag ("PATIENT", "STUDY", "SERIE", "IMAGE") is found :
   //  1 - we save the beginning iterator
   //  2 - we continue to parse
   //  3 - we find an other tag
   //       + we create the object for the precedent tag
   //       + loop to 1 -
   gdcmDebugMacro("Create DicomDir");

   // Directory record sequence
   DocEntry *e = GetDocEntry(0x0004, 0x1220);
   if ( !e )
   {
      gdcmWarningMacro( "No Directory Record Sequence (0004,1220) found");
      return;         
   }
   
   SeqEntry *s = dynamic_cast<SeqEntry *>(e);
   if ( !s )
   {
      gdcmWarningMacro( "Element (0004,1220) is not a Sequence ?!?");
      return;
   }

   NewMeta();
   
   DocEntry *d;
   std::string v;
   SQItem *si;

   SQItem *tmpSI=s->GetFirstSQItem();
   while(tmpSI)
   {
      d = tmpSI->GetDocEntry(0x0004, 0x1430); // Directory Record Type
      if ( ValEntry* valEntry = dynamic_cast<ValEntry *>(d) )
      {
         v = valEntry->GetValue();
      }
      else
      {
         gdcmWarningMacro( "(0004,1430) not a ValEntry ?!?");
         continue;
      }

      // A decent DICOMDIR has much more images than series,
      // more series than studies, and so on.
      // This is the right order to perform the tests

      if ( v == "IMAGE " ) 
      {
         si = new DicomDirImage(true);
         if ( !AddImageToEnd( static_cast<DicomDirImage *>(si)) )
         {
            delete si;
            si = NULL;
            gdcmErrorMacro( "Add AddImageToEnd failed");
         }
      }
      else if ( v == "SERIES" )
      {
         si = new DicomDirSerie(true);
         if ( !AddSerieToEnd( static_cast<DicomDirSerie *>(si)) )
         {
            delete si;
            si = NULL;
            gdcmErrorMacro( "Add AddSerieToEnd failed");
         }
      }

⌨️ 快捷键说明

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