Main Page | File List | Related Pages

gdcmHeader.cxx

00001 // gdcmHeader.cxx
00002 //-----------------------------------------------------------------------------
00003 #include "gdcmHeader.h"
00004 
00005 #include <stdio.h>
00006 #include <cerrno>
00007 #include <cctype>    // for isalpha
00008 
00009 #include "gdcmUtil.h"
00010 #include "gdcmTS.h"
00011 
00012 
00013 //-----------------------------------------------------------------------------
00014 // Constructor / Destructor
00026 gdcmHeader::gdcmHeader(const char *InFilename, 
00027                        bool exception_on_error,
00028                        bool enable_sequences, 
00029                        bool ignore_shadow):
00030    gdcmParser(InFilename,exception_on_error,enable_sequences,ignore_shadow)
00031 { 
00032    
00033    // for some ACR-NEMA images GrPixel, NumPixel is *not* 7fe0,0010
00034    // We may encounter the 'RETired' (0x0028, 0x0200) tag
00035    // (Image Location") . This Element contains the number of
00036    // the group that contains the pixel data (hence the "Pixel Data"
00037    // is found by indirection through the "Image Location").
00038    // Inside the group pointed by "Image Location" the searched element
00039    // is conventionally the element 0x0010 (when the norm is respected).
00040    // When the "Image Location" is absent we default to group 0x7fe0.
00041    
00042    // This IS the right place for the code
00043  
00044       std::string ImageLocation = GetEntryByNumber(0x0028, 0x0200);
00045       if ( ImageLocation == GDCM_UNFOUND ) { // Image Location
00046          GrPixel = 0x7fe0;                   // default value
00047       } else {
00048          GrPixel = (guint16) atoi( ImageLocation.c_str() );
00049       }   
00050       if (GrPixel == 0xe07f) // sometimes Image Location value doesn't follow 
00051          GrPixel = 0x7fe0;   // the supposed processor endianity. 
00052                              // see gdcmData/cr172241.dcm      
00053       if (GrPixel != 0x7fe0) 
00054          // This is a kludge for old dirty Philips imager.
00055          NumPixel = 0x1010;
00056       else
00057          NumPixel = 0x0010;
00058          
00059       TagKey key = gdcmDictEntry::TranslateToKey(GrPixel, NumPixel);
00060       countGrPixel = GetEntry().count(key);
00061 }
00062 
00068 gdcmHeader::gdcmHeader(bool exception_on_error) :
00069    gdcmParser(exception_on_error)
00070 {
00071 }
00072 
00077 gdcmHeader::~gdcmHeader (void) {
00078 }
00079 
00080 //-----------------------------------------------------------------------------
00081 // Print
00082 
00083 // see gdcmParser.cxx
00084 //-----------------------------------------------------------------------------
00085 // Public
00086 
00096 bool gdcmHeader::IsReadable(void) {
00097    if(!gdcmParser::IsReadable()) {
00098       return(false);
00099    }
00100    std::string res = GetEntryByNumber(0x0028, 0x0005);
00101    if ( res != GDCM_UNFOUND && atoi(res.c_str()) > 4 ) 
00102       return false; // Image Dimensions
00103    if ( !GetHeaderEntryByNumber(0x0028, 0x0100) )
00104       return false; // "Bits Allocated"
00105    if ( !GetHeaderEntryByNumber(0x0028, 0x0101) )
00106       return false; // "Bits Stored"
00107    if ( !GetHeaderEntryByNumber(0x0028, 0x0102) )
00108       return false; // "High Bit"
00109    if ( !GetHeaderEntryByNumber(0x0028, 0x0103) )
00110       return false; // "Pixel Representation" i.e. 'Sign'
00111    return true;
00112 }
00113 
00120 bool gdcmHeader::IsJPEGBaseLineProcess1TransferSyntax(void) {
00121    gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00122    if ( !Element )
00123       return false;
00124    LoadHeaderEntrySafe(Element);
00125 
00126    std::string Transfer = Element->GetValue();
00127    if ( Transfer == "1.2.840.10008.1.2.4.50" )
00128       return true;
00129    return false;
00130 }
00131 
00138 bool gdcmHeader::IsJPEGExtendedProcess2_4TransferSyntax(void) {
00139    gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00140    if ( !Element )
00141       return false;
00142    LoadHeaderEntrySafe(Element);
00143    return ( Element->GetValue() == "1.2.840.10008.1.2.4.51" );
00144 }
00145 
00152 bool gdcmHeader::IsJPEGExtendedProcess3_5TransferSyntax(void) {
00153    gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00154    if ( !Element )
00155       return false;
00156    LoadHeaderEntrySafe(Element);
00157 
00158    std::string Transfer = Element->GetValue();
00159    if ( Transfer == "1.2.840.10008.1.2.4.52" )
00160       return true;
00161    return false;
00162 }
00163 
00171 bool gdcmHeader::IsJPEGSpectralSelectionProcess6_8TransferSyntax(void) {
00172    gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00173    if ( !Element )
00174       return false;
00175    LoadHeaderEntrySafe(Element);
00176 
00177    std::string Transfer = Element->GetValue();
00178    if ( Transfer == "1.2.840.10008.1.2.4.53" )
00179       return true;
00180    return false;
00181 }
00182 
00190 bool gdcmHeader::IsRLELossLessTransferSyntax(void) {
00191    gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00192    if ( !Element )
00193       return false;
00194    LoadHeaderEntrySafe(Element);
00195 
00196    std::string Transfer = Element->GetValue();
00197    if ( Transfer == "1.2.840.10008.1.2.5" ) {
00198       return true;
00199     }
00200    return false;
00201 }
00202 
00210 bool gdcmHeader::IsJPEGLossless(void) {
00211    gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00212     // faire qq chose d'intelligent a la place de ça
00213    if ( !Element )
00214       return false;
00215    LoadHeaderEntrySafe(Element);
00216 
00217    const char * Transfert = Element->GetValue().c_str();
00218    if ( memcmp(Transfert+strlen(Transfert)-2 ,"70",2)==0) return true;
00219    if ( memcmp(Transfert+strlen(Transfert)-2 ,"55",2)==0) return true;
00220    if (Element->GetValue() == "1.2.840.10008.1.2.4.57")   return true;
00221 
00222    return false;
00223 }
00224 
00232 bool gdcmHeader::IsJPEG2000(void) {
00233    gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00234    if ( !Element )
00235       return false;
00236    LoadHeaderEntrySafe(Element);
00237 
00238    std::string Transfer = Element->GetValue();
00239    if (    (Transfer == "1.2.840.10008.1.2.4.90") 
00240         || (Transfer == "1.2.840.10008.1.2.4.91") )
00241       return true;
00242    return false;
00243 }
00244 
00250 bool gdcmHeader::IsDicomV3(void) {
00251    // Checking if Transfert Syntax exists is enough
00252    // Anyway, it's to late check if the 'Preamble' was found ...
00253    // And ... would it be a rich idea to check ?
00254    // (some 'no Preamble' DICOM images exist !)
00255    return (GetHeaderEntryByNumber(0x0002, 0x0010) != NULL);
00256 }
00257 
00264 int gdcmHeader::GetXSize(void) {
00265    std::string StrSize;
00266    StrSize = GetEntryByNumber(0x0028,0x0011);
00267    if (StrSize == GDCM_UNFOUND)
00268       return 0;
00269    return atoi(StrSize.c_str());
00270 }
00271 
00279 int gdcmHeader::GetYSize(void) {
00280    std::string StrSize = GetEntryByNumber(0x0028,0x0010);
00281    if (StrSize != GDCM_UNFOUND)
00282       return atoi(StrSize.c_str());
00283    if ( IsDicomV3() )
00284       return 0;
00285    else
00286       // The Rows (0028,0010) entry was optional for ACR/NEMA. It might
00287       // hence be a signal (1d image). So we default to 1:
00288       return 1;
00289 }
00290 
00300 int gdcmHeader::GetZSize(void) {
00301    // Both  DicomV3 and ACR/Nema consider the "Number of Frames"
00302    // as the third dimension.
00303    std::string StrSize = GetEntryByNumber(0x0028,0x0008);
00304    if (StrSize != GDCM_UNFOUND)
00305       return atoi(StrSize.c_str());
00306 
00307    // We then consider the "Planes" entry as the third dimension 
00308    StrSize = GetEntryByNumber(0x0028,0x0012);
00309    if (StrSize != GDCM_UNFOUND)
00310       return atoi(StrSize.c_str());
00311    return 1;
00312 }
00313 
00321 int gdcmHeader::GetBitsStored(void) {  
00322    std::string StrSize = GetEntryByNumber(0x0028,0x0101);
00323    if (StrSize == GDCM_UNFOUND)
00324       return 0;  // It's supposed to be mandatory
00325                  // the caller will have to check
00326    return atoi(StrSize.c_str());
00327 }
00328 
00336 int gdcmHeader::GetBitsAllocated(void) {
00337    std::string StrSize = GetEntryByNumber(0x0028,0x0100);
00338    if (StrSize == GDCM_UNFOUND)
00339       return 0; // It's supposed to be mandatory
00340                 // the caller will have to check
00341    return atoi(StrSize.c_str());
00342 }
00343 
00351 int gdcmHeader::GetSamplesPerPixel(void) {
00352    std::string StrSize = GetEntryByNumber(0x0028,0x0002);
00353    if (StrSize == GDCM_UNFOUND)
00354       return 1; // Well, it's supposed to be mandatory ...
00355                 // but sometimes it's missing : *we* assume Gray pixels
00356    return atoi(StrSize.c_str());
00357 }
00358 
00365 int gdcmHeader::GetPlanarConfiguration(void) {
00366    std::string StrSize = GetEntryByNumber(0x0028,0x0006);
00367    if (StrSize == GDCM_UNFOUND)
00368       return 0;
00369    return atoi(StrSize.c_str());
00370 }
00371 
00378 int gdcmHeader::GetPixelSize(void) {
00379    std::string PixelType = GetPixelType();
00380    if (PixelType == "8U"  || PixelType == "8S")
00381       return 1;
00382    if (PixelType == "16U" || PixelType == "16S")
00383       return 2;
00384    if (PixelType == "32U" || PixelType == "32S")
00385       return 4;
00386    if (PixelType == "FD")
00387       return 8;         
00388    dbg.Verbose(0, "gdcmHeader::GetPixelSize: Unknown pixel type");
00389    return 0;
00390 }
00391 
00407 std::string gdcmHeader::GetPixelType(void) { 
00408    std::string BitsAlloc = GetEntryByNumber(0x0028, 0x0100); // Bits Allocated
00409    if (BitsAlloc == GDCM_UNFOUND) {
00410       dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
00411       BitsAlloc = std::string("16");
00412    }
00413    if (BitsAlloc == "64")            // )
00414       return ("FD");
00415    if (BitsAlloc == "12")            // It will be unpacked
00416       BitsAlloc = std::string("16");
00417    else if (BitsAlloc == "24")       // (in order no to be messed up
00418       BitsAlloc = std::string("8");  // by old RGB images)
00419      
00420    std::string Signed = GetEntryByNumber(0x0028, 0x0103); // "Pixel Representation"
00421    if (Signed == GDCM_UNFOUND) {
00422       dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
00423       BitsAlloc = std::string("0");
00424    }
00425    if (Signed == "0")
00426       Signed = std::string("U");
00427    else
00428       Signed = std::string("S");
00429 
00430    return( BitsAlloc + Signed);
00431 }
00432 
00433 
00440 size_t gdcmHeader::GetPixelOffset(void) { 
00441    //
00442    // If the element (0x0088,0x0200) 'icone image sequence' is found
00443    // (grPixel,numPixel) is stored twice : the first one for the icon
00444    // the second one for the image ...
00445    // pb : sometimes , (0x0088,0x0200) exists, but doesn't contain *anything*
00446    // see gdcmData/MxTwinLossLess.dcm ...
00447 
00448    //std::string icone = GetEntryByNumber(0x0088,0x0200); //icone image sequence
00449       
00450    IterHT it = GetHeaderEntrySameNumber(GrPixel,NumPixel);          
00451    TagKey key = gdcmDictEntry::TranslateToKey(GrPixel,NumPixel);
00452    gdcmHeaderEntry* PixelElement;
00453    if (countGrPixel == 1)   
00454       PixelElement = (it.first)->second;
00455    else {
00456       PixelElement = (++it.first)->second; // hope there are no more than 2 !
00457    } 
00458    if (PixelElement) {
00459       return PixelElement->GetOffset();
00460    } else {
00461 /*      std::cout << "Big trouble : Pixel Element ("
00462                 << std::hex << GrPixel<<","<< NumPixel<< ") NOT found"
00463                 << std::endl;  */
00464       return 0;
00465    }     
00466 }
00467 // TODO : unify those two (previous one and next one)
00476 size_t gdcmHeader::GetPixelAreaLength(void) { 
00477           
00478    IterHT it = GetHeaderEntrySameNumber(GrPixel,NumPixel);          
00479    TagKey key = gdcmDictEntry::TranslateToKey(GrPixel,NumPixel);
00480    gdcmHeaderEntry* PixelElement;
00481   
00482   if (countGrPixel==1)  
00483       PixelElement = (it.first)->second;
00484    else
00485       PixelElement = (++it.first)->second;
00486 
00487    if (PixelElement) {
00488       return PixelElement->GetLength();
00489    } else {
00490 /*      std::cout << "Big trouble : Pixel Element ("
00491                 << std::hex << GrPixel<<","<< NumPixel<< ") NOT found"
00492                 << std::endl;*/
00493       return 0;
00494    }
00495 }
00496 
00506 bool gdcmHeader::HasLUT(void) {
00507 
00508    // Check the presence of the LUT Descriptors, and LUT Tables    
00509    // LutDescriptorRed    
00510    if ( !GetHeaderEntryByNumber(0x0028,0x1101) )
00511       return false;
00512    // LutDescriptorGreen 
00513    if ( !GetHeaderEntryByNumber(0x0028,0x1102) )
00514       return false;
00515    // LutDescriptorBlue 
00516    if ( !GetHeaderEntryByNumber(0x0028,0x1103) )
00517       return false;   
00518    // Red Palette Color Lookup Table Data
00519    if ( !GetHeaderEntryByNumber(0x0028,0x1201) )
00520       return false; 
00521    // Green Palette Color Lookup Table Data       
00522    if ( !GetHeaderEntryByNumber(0x0028,0x1202) )
00523       return false;
00524    // Blue Palette Color Lookup Table Data      
00525    if ( !GetHeaderEntryByNumber(0x0028,0x1203) )
00526       return false;   
00527    return true;
00528 }
00529 
00538 int gdcmHeader::GetLUTNbits(void) {
00539    std::vector<std::string> tokens;
00540    //int LutLength;
00541    //int LutDepth;
00542    int LutNbits;
00543    //Just hope Lookup Table Desc-Red = Lookup Table Desc-Red = Lookup Table Desc-Blue
00544    // Consistency already checked in GetLUTLength
00545    std::string LutDescription = GetEntryByNumber(0x0028,0x1101);
00546    if (LutDescription == GDCM_UNFOUND)
00547       return 0;
00548    tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
00549    Tokenize (LutDescription, tokens, "\\");
00550    //LutLength=atoi(tokens[0].c_str());
00551    //LutDepth=atoi(tokens[1].c_str());
00552    LutNbits=atoi(tokens[2].c_str());
00553    tokens.clear();
00554    return LutNbits;
00555 }
00556 
00573 unsigned char * gdcmHeader::GetLUTRGBA(void) {
00574 // Not so easy : see 
00575 // http://www.barre.nom.fr/medical/dicom2/limitations.html#Color%20Lookup%20Tables
00576 
00577 //  if Photometric Interpretation # PALETTE COLOR, no LUT to be done
00578    if (GetEntryByNumber(0x0028,0x0004) != "PALETTE COLOR ") {
00579         return NULL;
00580    }  
00581    int lengthR, debR, nbitsR;
00582    int lengthG, debG, nbitsG;
00583    int lengthB, debB, nbitsB;
00584    
00585 // Get info from Lut Descriptors
00586 // (the 3 LUT descriptors may be different)    
00587    std::string LutDescriptionR = GetEntryByNumber(0x0028,0x1101);
00588    if (LutDescriptionR == GDCM_UNFOUND)
00589       return NULL;
00590    std::string LutDescriptionG = GetEntryByNumber(0x0028,0x1102);
00591    if (LutDescriptionG == GDCM_UNFOUND)
00592       return NULL;   
00593    std::string LutDescriptionB = GetEntryByNumber(0x0028,0x1103);
00594    if (LutDescriptionB == GDCM_UNFOUND)
00595       return NULL;
00596       
00597    std::vector<std::string> tokens;
00598       
00599    tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
00600    Tokenize (LutDescriptionR, tokens, "\\");
00601    lengthR=atoi(tokens[0].c_str()); // Red LUT length in Bytes
00602    debR   =atoi(tokens[1].c_str()); // subscript of the first Lut Value
00603    nbitsR =atoi(tokens[2].c_str()); // Lut item size (in Bits)
00604    tokens.clear();
00605    
00606    tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
00607    Tokenize (LutDescriptionG, tokens, "\\");
00608    lengthG=atoi(tokens[0].c_str()); // Green LUT length in Bytes
00609    debG   =atoi(tokens[1].c_str()); // subscript of the first Lut Value
00610    nbitsG =atoi(tokens[2].c_str()); // Lut item size (in Bits)
00611    tokens.clear();  
00612    
00613    tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
00614    Tokenize (LutDescriptionB, tokens, "\\");
00615    lengthB=atoi(tokens[0].c_str()); // Blue LUT length in Bytes
00616    debB   =atoi(tokens[1].c_str()); // subscript of the first Lut Value
00617    nbitsB =atoi(tokens[2].c_str()); // Lut item size (in Bits)
00618    tokens.clear();
00619  
00620    // Load LUTs into memory, (as they were stored on disk)
00621    unsigned char *lutR = (unsigned char *)
00622                          GetEntryVoidAreaByNumber(0x0028,0x1201);
00623    unsigned char *lutG = (unsigned char *)
00624                          GetEntryVoidAreaByNumber(0x0028,0x1202);
00625    unsigned char *lutB = (unsigned char *)
00626                          GetEntryVoidAreaByNumber(0x0028,0x1203); 
00627    
00628    if (!lutR || !lutG || !lutB ) {
00629         return NULL;
00630    } 
00631    // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT 
00632    
00633    unsigned char *LUTRGBA = (unsigned char *)calloc(1024,1); // 256 * 4 (R, G, B, Alpha) 
00634    if (!LUTRGBA) {
00635       return NULL;
00636    }
00637    memset(LUTRGBA, 0, 1024);
00638         // Bits Allocated
00639    int nb;
00640    std::string str_nb = GetEntryByNumber(0x0028,0x0100);
00641    if (str_nb == GDCM_UNFOUND ) {
00642       nb = 16;
00643    } else {
00644       nb = atoi(str_nb.c_str() );
00645    }  
00646    int mult;
00647 
00648    if (nbitsR==16 && nb==8) // when LUT item size is different than pixel size
00649       mult=2;               // high byte must be = low byte 
00650    else                     // See PS 3.3-2003 C.11.1.1.2 p 619
00651       mult=1; 
00652  
00653    // if we get a black image, let's just remove the '+1'
00654    // from 'i*mult+1' and check again 
00655    // if it works, we shall have to check the 3 Palettes
00656    // to see which byte is ==0 (first one, or second one)
00657    // and fix the code
00658    // We give up the checking to avoid some (useless ?)overhead 
00659    // (optimistic asumption)
00660    unsigned char *a;      
00661    int i;
00662 
00663    a = LUTRGBA+0;
00664    for(i=0;i<lengthR;i++) {
00665       *a = lutR[i*mult+1]; 
00666       a+=4;       
00667    }        
00668    a = LUTRGBA+1;
00669    for(i=0;i<lengthG;i++) {
00670       *a = lutG[i*mult+1]; 
00671       a+=4;       
00672    }  
00673    a = LUTRGBA+2;
00674    for(i=0;i<lengthB;i++) {
00675       *a = lutB[i*mult+1]; 
00676       a+=4;       
00677    }  
00678    a = LUTRGBA+3;
00679    for(i=0;i<256;i++) {
00680       *a = 1; // Alpha component
00681       a+=4; 
00682    } 
00683    
00684    //How to free the now useless LUTs?
00685    //free(LutR); free(LutB); free(LutG); // Seg Fault when used
00686    return(LUTRGBA);   
00687 } 
00688 
00695 std::string gdcmHeader::GetTransfertSyntaxName(void) { 
00696    // use the gdcmTS (TS : Transfert Syntax)
00697    std::string TransfertSyntax = GetEntryByNumber(0x0002,0x0010);
00698    if (TransfertSyntax == GDCM_UNFOUND) {
00699       dbg.Verbose(0, "gdcmHeader::GetTransfertSyntaxName: unfound Transfert Syntax (0002,0010)");
00700       return "Uncompressed ACR-NEMA";
00701    }
00702    // we do it only when we need it
00703    gdcmTS * ts = gdcmGlobal::GetTS();
00704    std::string tsName=ts->GetValue(TransfertSyntax);
00705    //delete ts; // Seg Fault when deleted ?!
00706    return tsName;
00707 }
00708 
00716 void gdcmHeader::SetImageDataSize(size_t ImageDataSize) {
00717    std::string content1;
00718    char car[20];
00719         
00720    // Assumes HeaderEntry (GrPixel, NumPixel) is unique ...   
00721    // TODO deal with multiplicity (see gdcmData/icone.dcm)      
00722    sprintf(car,"%d",ImageDataSize);
00723  
00724    gdcmHeaderEntry *a = GetHeaderEntryByNumber(GrPixel, NumPixel);
00725    a->SetLength(ImageDataSize);
00726                 
00727    ImageDataSize+=8;
00728    sprintf(car,"%d",ImageDataSize);
00729    content1=car;        
00730    SetEntryByNumber(content1, GrPixel, NumPixel);
00731 }
00732 
00733 
00743  bool gdcmHeader::operator<(gdcmHeader &header){
00744    std::string s1,s2;
00745 
00746    // Patient Name
00747    s1=this->GetEntryByNumber(0x0010,0x0010);
00748    s2=header.GetEntryByNumber(0x0010,0x0010);
00749    if(s1 < s2)
00750            return(true);
00751    else if(s1 > s2)
00752            return(false);
00753    else
00754    {
00755       // Patient ID
00756       s1=this->GetEntryByNumber(0x0010,0x0020);
00757       s2=header.GetEntryByNumber(0x0010,0x0020);
00758       if (s1 < s2)
00759               return(true);
00760       else if (s1 > s2)
00761          return(1);
00762       else
00763       {
00764               // Study Instance UID
00765          s1=this->GetEntryByNumber(0x0020,0x000d);
00766          s2=header.GetEntryByNumber(0x0020,0x000d);
00767          if (s1 < s2)
00768                  return(true);
00769          else if(s1 > s2)
00770                  return(false);
00771          else
00772          {
00773                  // Serie Instance UID          
00774             s1=this->GetEntryByNumber(0x0020,0x000e);
00775             s2=header.GetEntryByNumber(0x0020,0x000e);
00776             if (s1 < s2)
00777                return(true);
00778             else if(s1 > s2)
00779                return(false);
00780          }
00781       }
00782    }
00783    return(false);
00784 }
00785 
00786 //-----------------------------------------------------------------------------
00787 // Protected
00788 
00795 bool gdcmHeader::anonymizeHeader() {
00796 
00797   gdcmHeaderEntry *patientNameHE = GetHeaderEntryByNumber (0x0010, 0x0010);
00798  // gdcmHeaderEntry *patientIDHE   = GetHeaderEntryByNumber (0x0010, 0x0020); 
00799     
00800   ReplaceIfExistByNumber ("  ",0x0010, 0x2154); // Telephone   
00801   ReplaceIfExistByNumber ("  ",0x0010, 0x1040); // Adress
00802   ReplaceIfExistByNumber ("  ",0x0010, 0x0020); // Patient ID
00803   
00804   if (patientNameHE) {
00805      std::string StudyInstanceUID =  GetEntryByNumber (0x0020, 0x000d);
00806      if (StudyInstanceUID !=GDCM_UNFOUND)
00807         ReplaceOrCreateByNumber(StudyInstanceUID, 0x0010, 0x0010);
00808      else
00809         ReplaceOrCreateByNumber("anonymised", 0x0010, 0x0010);            
00810   }
00811   
00812   // Just for fun :-(
00813   // (if any) remove or replace 
00814   
00815 //0008 0012 DA ID Instance Creation Date
00816 //0008 0020 DA ID Study Date
00817 //0008 0021 DA ID Series Date
00818 //0008 0022 DA ID Acquisition Date
00819 //0008 0023 DA ID Content Date
00820 //0008 0024 DA ID Overlay Date
00821 //0008 0025 DA ID Curve Date
00822 //0008 002a DT ID Acquisition Datetime
00823 //0018 9074 DT ACQ Frame Acquisition Datetime
00824 //0018 9151 DT ACQ Frame Reference Datetime
00825 //0018 a002 DT ACQ Contribution Date Time
00826 //0020 3403 SH REL Modified Image Date (RET)
00827 //0032 0032 DA SDY Study Verified Date
00828 //0032 0034 DA SDY Study Read Date
00829 //0032 1000 DA SDY Scheduled Study Start Date
00830 //0032 1010 DA SDY Scheduled Study Stop Date
00831 //0032 1040 DA SDY Study Arrival Date
00832 //0032 1050 DA SDY Study Completion Date
00833 //0038 001a DA VIS Scheduled Admission Date
00834 //0038 001c DA VIS Scheduled Discharge Date
00835 //0038 0020 DA VIS Admitting Date
00836 //0038 0030 DA VIS Discharge Date
00837 //0040 0002 DA PRC Scheduled Procedure Step Start Date
00838 //0040 0004 DA PRC Scheduled Procedure Step End Date
00839 //0040 0244 DA PRC Performed Procedure Step Start Date
00840 //0040 0250 DA PRC Performed Procedure Step End Date
00841 //0040 2004 DA PRC Issue Date of Imaging Service Request
00842 //0040 4005 DT PRC Scheduled Procedure Step Start Date and Time
00843 //0040 4011 DT PRC Expected Completion Date and Time
00844 //0040 a030 DT PRC Verification Date Time
00845 //0040 a032 DT PRC Observation Date Time
00846 //0040 a120 DT PRC DateTime
00847 //0040 a121 DA PRC Date
00848 //0040 a13a DT PRC Referenced Datetime
00849 //0070 0082 DA ??? Presentation Creation Date
00850 //0100 0420 DT ??? SOP Autorization Date and Time
00851 //0400 0105 DT ??? Digital Signature DateTime
00852 //2100 0040 DA PJ Creation Date
00853 //3006 0008 DA SSET Structure Set Date
00854 //3008 0024 DA ??? Treatment Control Point Date
00855 //3008 0054 DA ??? First Treatment Date
00856 //3008 0056 DA ??? Most Recent Treatment Date
00857 //3008 0162 DA ??? Safe Position Exit Date
00858 //3008 0166 DA ??? Safe Position Return Date
00859 //3008 0250 DA ??? Treatment Date
00860 //300a 0006 DA RT RT Plan Date
00861 //300a 022c DA RT Air Kerma Rate Reference Date
00862 //300e 0004 DA RT Review Date
00863  return true;  
00864  }
00865 //-----------------------------------------------------------------------------
00866 // Private
00867 
00868 //-----------------------------------------------------------------------------

Generated on Mon Feb 14 16:13:44 2005 for gdcm by doxygen 1.3.6