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

📄 gdcmfile.cxx

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 CXX
📖 第 1 页 / 共 5 页
字号:
   std::string PhotometricInterp = GetEntryValue( 0x0028, 0x0004 );
   if (   PhotometricInterp == "YBR_FULL" )
   {
      return true;
   }
   if ( PhotometricInterp == GDCM_UNFOUND )
   {
      gdcmWarningMacro( "Not found : YBR Full (0028,0004)");
   }
   return false;
}

/**
  * \brief tells us if LUT are used
  * \warning Right now, 'Segmented xxx Palette Color Lookup Table Data'
  *          are NOT considered as LUT, since nobody knows
  *          how to deal with them
  *          Please warn me if you know sbdy that *does* know ... jprx
  * @return true if LUT Descriptors and LUT Tables were found 
  */
bool File::HasLUT()
{
   // Check the presence of the LUT Descriptors, and LUT Tables    
   // LutDescriptorRed    
   if ( !GetDocEntry(0x0028,0x1101) )
   {
      return false;
   }
   // LutDescriptorGreen 
   if ( !GetDocEntry(0x0028,0x1102) )
   {
      return false;
   }
   // LutDescriptorBlue 
   if ( !GetDocEntry(0x0028,0x1103) )
   {
      return false;
   }
   // Red Palette Color Lookup Table Data
   if ( !GetDocEntry(0x0028,0x1201) )
   {
      return false;
   }
   // Green Palette Color Lookup Table Data       
   if ( !GetDocEntry(0x0028,0x1202) )
   {
      return false;
   }
   // Blue Palette Color Lookup Table Data      
   if ( !GetDocEntry(0x0028,0x1203) )
   {
      return false;
   }

   // FIXME : (0x0028,0x3006) : LUT Data (CTX dependent)
   //         NOT taken into account, but we don't know how to use it ...   
   return true;
}

/**
  * \brief gets the info from 0028,1101 : Lookup Table Desc-Red
  *             else 0
  * @return Lookup Table number of Bits , 0 by default
  *          when (0028,0004),Photometric Interpretation = [PALETTE COLOR ]
  * @ return bit number of each LUT item 
  */
int File::GetLUTNbits()
{
   std::vector<std::string> tokens;
   int lutNbits;

   //Just hope Lookup Table Desc-Red = Lookup Table Desc-Red
   //                                = Lookup Table Desc-Blue
   // Consistency already checked in GetLUTLength
   std::string lutDescription = GetEntryValue(0x0028,0x1101);
   if ( lutDescription == GDCM_UNFOUND )
   {
      return 0;
   }

   tokens.clear(); // clean any previous value
   Util::Tokenize ( lutDescription, tokens, "\\" );
   //LutLength=atoi(tokens[0].c_str());
   //LutDepth=atoi(tokens[1].c_str());

   lutNbits = atoi( tokens[2].c_str() );
   tokens.clear();

   return lutNbits;
}

// Special case:
//  ts["1.2.840.10008.5.1.4.1.1.4.1"] = "Enhanced MR Image Storage"; 
bool File::GetRescaleSlopeIntercept(double &slope, double &intercept)
{
   slope = 1.0;
   intercept = 0.0;
   TS *ts = Global::GetTS();
   std::string sopclassuid_used;
   // D 0002|0002 [UI] [Media Storage SOP Class UID]
   const std::string &mediastoragesopclassuid_str = GetEntryValue(0x0002,0x0002);
   const std::string &mediastoragesopclassuid = ts->GetValue(mediastoragesopclassuid_str);
   //D 0008|0016 [UI] [SOP Class UID]
   const std::string &sopclassuid_str = GetEntryValue(0x0008,0x0016);
   const std::string &sopclassuid = ts->GetValue(sopclassuid_str);
   if ( mediastoragesopclassuid == GDCM_UNFOUND && sopclassuid == GDCM_UNFOUND )
     {
     return false;
     }
   else
     {
     if( mediastoragesopclassuid == sopclassuid )
       {
       sopclassuid_used = mediastoragesopclassuid;
       }
     else
       {
       gdcmWarningMacro( "Inconsistant SOP Class UID: "
         << mediastoragesopclassuid << " and " << sopclassuid );
       return false;
       }
     }
   // ok we have now the correc SOP Class UID
   if( sopclassuid_used == "Enhanced MR Image Storage" )
     {
     SeqEntry *PerframeFunctionalGroupsSequence = GetSeqEntry(0x5200,0x9230);
     unsigned int n = PerframeFunctionalGroupsSequence->GetNumberOfSQItems();
     if( !n ) return false;
     SQItem *item1 = PerframeFunctionalGroupsSequence->GetFirstSQItem();
     DocEntry *p = item1->GetDocEntry(0x0028,0x9145);
     if( !p ) return false;
     SeqEntry *seq = dynamic_cast<SeqEntry*>(p);
     unsigned int n1 = seq->GetNumberOfSQItems();
     if( !n1 ) return false;
     SQItem *item2 = seq->GetFirstSQItem();
     // D 0028|1052 [DS] [Rescale Intercept] [0 ]
     DocEntry *p2 = item2->GetDocEntry(0x0028,0x1052);
     if( !p2 ) return false;
     ContentEntry *entry = dynamic_cast<ContentEntry *>(p2);
     std::string intercept_str = entry->GetValue();
     if ( sscanf( intercept_str.c_str(), "%lf", &intercept) != 1 )
       {
       intercept = 0.;
       return false;
       }
     // D 0028|1053 [DS] [Rescale Slope] [5.65470085470085]
     DocEntry *p3 = item2->GetDocEntry(0x0028,0x1053);
     if( !p3 ) return false;
     ContentEntry *entry2 = dynamic_cast<ContentEntry *>(p3);
     std::string slope_str = entry2->GetValue();
     if ( sscanf( slope_str.c_str(), "%lf", &slope) != 1 )
       {
       slope = 1.;
       return false;
       }
     return true;
     }

  return false;
}

/**
 *\brief gets the info from 0028,1052 : Rescale Intercept
 * @return Rescale Intercept
 */
double File::GetRescaleIntercept()
{
   double resInter = 0.;
   double resSlope = 1.0;
   if ( GetRescaleSlopeIntercept(resSlope, resInter) )
     {
     return resInter;
     }
   /// 0028 1052 DS IMG Rescale Intercept
   const std::string &strRescInter = GetEntryValue(0x0028,0x1052);
   if ( strRescInter != GDCM_UNFOUND )
   {
      if ( sscanf( strRescInter.c_str(), "%lf ", &resInter) != 1 )
      {
         // bug in the element 0x0028,0x1052
         gdcmWarningMacro( "Rescale Intercept (0028,1052) is empty." );
      }
   }

   return resInter;
}

/**
 *\brief   gets the info from 0028,1053 : Rescale Slope
 * @return Rescale Slope. defaulted to 1.0 is not found, == 0.0 or empty
 */
double File::GetRescaleSlope()
{
   double resInter = 0.;
   double resSlope = 1.;
   if ( GetRescaleSlopeIntercept(resSlope, resInter) )
     {
     return resSlope;
     }
   //0028 1053 DS IMG Rescale Slope
   std::string strRescSlope = GetEntryValue(0x0028,0x1053);
   if ( strRescSlope != GDCM_UNFOUND )
   {
      if ( sscanf( strRescSlope.c_str(), "%lf ", &resSlope) != 1 )
      {
         // bug in the element 0x0028,0x1053
         gdcmWarningMacro( "Rescale Slope (0028,1053) is empty.");
      }
   }
   if( resSlope == 0. )
     {
     gdcmWarningMacro( "No such thing as a slope of 0.0. Defaulting to 1.0 value" );
     return 1.0;
     }

   return resSlope;
}

/**
 * \brief This function is intended to user who doesn't want 
 *   to have to manage a LUT and expects to get an RBG Pixel image
 *   (or a monochrome one ...) 
 * \warning to be used with GetImagePixels()
 * @return 1 if Gray level, 3 if Color (RGB, YBR, *or PALETTE COLOR*)
 */
int File::GetNumberOfScalarComponents()
{
   if ( GetSamplesPerPixel() == 3 )
   {
      return 3;
   }

   // 0028 0100 US IMG Bits Allocated
   // (in order no to be messed up by old RGB images)
   if ( GetEntryValue(0x0028,0x0100) == "24" )
   {
      return 3;
   }

   std::string strPhotometricInterpretation = GetEntryValue(0x0028,0x0004);

   if ( Util::DicomStringEqual(strPhotometricInterpretation, "PALETTE COLOR") )
   {
      if ( HasLUT() )// PALETTE COLOR is NOT enough
      {
         return 3;
      }
      else
      {
         return 1;
      }
   }

   // beware of trailing space at end of string      
   // DICOM tags are never of odd length
   if ( strPhotometricInterpretation == GDCM_UNFOUND   || 
        Util::DicomStringEqual(strPhotometricInterpretation, "MONOCHROME1") ||
        Util::DicomStringEqual(strPhotometricInterpretation, "MONOCHROME2") )
   {
      return 1;
   }
   else
   {
      // we assume that *all* kinds of YBR are dealt with
      return 3;
   }
}

/**
 * \brief This function is intended to user that DOESN'T want 
 *  to get RGB pixels image when it's stored as a PALETTE COLOR image
 *   - the (vtk) user is supposed to know how deal with LUTs - 
 * \warning to be used with GetImagePixelsRaw()
 * @return 1 if Gray level, 3 if Color (RGB or YBR - NOT 'PALETTE COLOR' -)
 */
int File::GetNumberOfScalarComponentsRaw()
{
   // 0028 0100 US IMG Bits Allocated
   // (in order no to be messed up by old RGB images)
   if ( File::GetEntryValue(0x0028,0x0100) == "24" )
   {
      return 3;
   }

   // we assume that *all* kinds of YBR are dealt with
   return GetSamplesPerPixel();
}

/**
 * \brief   Recover the offset (from the beginning of the file) 
 *          of *image* pixels (not *icone image* pixels, if any !)
 * @return Pixel Offset
 */
size_t File::GetPixelOffset()
{
   DocEntry *pxlElement = GetDocEntry(GrPixel, NumPixel);
   if ( pxlElement )
   {
      return pxlElement->GetOffset();
   }
   else
   {
      gdcmDebugMacro( "Big trouble : Pixel Element ("
                      << std::hex << GrPixel<<","<< NumPixel<< ") NOT found" );
      return 0;
   }
}

/**
 * \brief   Recover the pixel area length (in Bytes)
 * @return Pixel Element Length, as stored in the header
 *         (NOT the memory space necessary to hold the Pixels 
 *          -in case of embeded compressed image-)
 *         0 : NOT USABLE file. The caller has to check.
 */
size_t File::GetPixelAreaLength()
{
   DocEntry *pxlElement = GetDocEntry(GrPixel, NumPixel);
   if ( pxlElement )
   {
      return pxlElement->GetLength();
   }
   else
   {
      gdcmDebugMacro( "Big trouble : Pixel Element ("
                      << std::hex << GrPixel<<","<< NumPixel<< ") NOT found" );
      return 0;
   }
}

/**
 * \brief Adds the characteristics of a new element we want to anonymize
 * @param   group  Group number of the target tag.
 * @param   elem Element number of the target tag.
 * @param   value new value (string) to substitute with 
 */
void File::AddAnonymizeElement (uint16_t group, uint16_t elem, 
                                std::string const &value) 
{ 
   Element el;
   el.Group = group;
   el.Elem  = elem;
   el.Value = value;
   UserAnonymizeList.push_back(el); 
}

/**
 * \brief Overwrites in the file the values of the DicomElements
 *       held in the list 
 */
void File::AnonymizeNoLoad()
{
   std::fstream *fp = new std::fstream(Filename.c_str(), 
                              std::ios::in | std::ios::out | std::ios::binary); 
   gdcm::DocEntry *d;
   uint32_t offset;
   uint32_t lgth;
   uint32_t valLgth = 0;
   std::string *spaces;
   for (ListElements::iterator it = UserAnonymizeList.begin();  
                               it != UserAnonymizeList.end();
                             ++it)
   { 
      d = GetDocEntry( (*it).Group, (*it).Elem);

      if ( d == NULL)
         continue;

      if ( dynamic_cast<SeqEntry *>(d) )
      {
         gdcmWarningMacro( "You cannot 'Anonymize' a SeqEntry ");
         continue;
      }

      offset = (uint32_t)(d->GetOffset());
      lgth =   d->GetLength();
      if (valLgth < lgth)
      {
         spaces = new std::string( lgth-valLgth, ' ');
         (*it).Value = (*it).Value + *spaces;
         delete spaces;
      }
      fp->seekp( offset, std::ios::beg );
      fp->write( (*it).Value.c_str(), lgth );
     
   }
   fp->close();
   delete fp;
}

/**
 * \brief anonymize a File (remove Patient's personal info passed with
 *        AddAnonymizeElement()
 * \note You cannot Anonymize a BinEntry (to be fixed)
 */

⌨️ 快捷键说明

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