00001 
00002 
00003 #include "gdcmHeader.h"
00004 
00005 #include <stdio.h>
00006 #include <cerrno>
00007 #include <cctype>    
00008 
00009 #include "gdcmUtil.h"
00010 #include "gdcmTS.h"
00011 
00012 
00013 
00014 
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    
00034    
00035    
00036    
00037    
00038    
00039    
00040    
00041    
00042    
00043  
00044       std::string ImageLocation = GetEntryByNumber(0x0028, 0x0200);
00045       if ( ImageLocation == GDCM_UNFOUND ) { 
00046          GrPixel = 0x7fe0;                   
00047       } else {
00048          GrPixel = (guint16) atoi( ImageLocation.c_str() );
00049       }   
00050       if (GrPixel == 0xe07f) 
00051          GrPixel = 0x7fe0;   
00052                              
00053       if (GrPixel != 0x7fe0) 
00054          
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 
00082 
00083 
00084 
00085 
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; 
00103    if ( !GetHeaderEntryByNumber(0x0028, 0x0100) )
00104       return false; 
00105    if ( !GetHeaderEntryByNumber(0x0028, 0x0101) )
00106       return false; 
00107    if ( !GetHeaderEntryByNumber(0x0028, 0x0102) )
00108       return false; 
00109    if ( !GetHeaderEntryByNumber(0x0028, 0x0103) )
00110       return false; 
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     
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    
00252    
00253    
00254    
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       
00287       
00288       return 1;
00289 }
00290 
00300 int gdcmHeader::GetZSize(void) {
00301    
00302    
00303    std::string StrSize = GetEntryByNumber(0x0028,0x0008);
00304    if (StrSize != GDCM_UNFOUND)
00305       return atoi(StrSize.c_str());
00306 
00307    
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;  
00325                  
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; 
00340                 
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; 
00355                 
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); 
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")            
00416       BitsAlloc = std::string("16");
00417    else if (BitsAlloc == "24")       
00418       BitsAlloc = std::string("8");  
00419      
00420    std::string Signed = GetEntryByNumber(0x0028, 0x0103); 
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    
00443    
00444    
00445    
00446    
00447 
00448    
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; 
00457    } 
00458    if (PixelElement) {
00459       return PixelElement->GetOffset();
00460    } else {
00461 
00462 
00463 
00464       return 0;
00465    }     
00466 }
00467 
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 
00491 
00492 
00493       return 0;
00494    }
00495 }
00496 
00506 bool gdcmHeader::HasLUT(void) {
00507 
00508    
00509    
00510    if ( !GetHeaderEntryByNumber(0x0028,0x1101) )
00511       return false;
00512    
00513    if ( !GetHeaderEntryByNumber(0x0028,0x1102) )
00514       return false;
00515    
00516    if ( !GetHeaderEntryByNumber(0x0028,0x1103) )
00517       return false;   
00518    
00519    if ( !GetHeaderEntryByNumber(0x0028,0x1201) )
00520       return false; 
00521    
00522    if ( !GetHeaderEntryByNumber(0x0028,0x1202) )
00523       return false;
00524    
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    
00541    
00542    int LutNbits;
00543    
00544    
00545    std::string LutDescription = GetEntryByNumber(0x0028,0x1101);
00546    if (LutDescription == GDCM_UNFOUND)
00547       return 0;
00548    tokens.erase(tokens.begin(),tokens.end()); 
00549    Tokenize (LutDescription, tokens, "\\");
00550    
00551    
00552    LutNbits=atoi(tokens[2].c_str());
00553    tokens.clear();
00554    return LutNbits;
00555 }
00556 
00573 unsigned char * gdcmHeader::GetLUTRGBA(void) {
00574 
00575 
00576 
00577 
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 
00586 
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()); 
00600    Tokenize (LutDescriptionR, tokens, "\\");
00601    lengthR=atoi(tokens[0].c_str()); 
00602    debR   =atoi(tokens[1].c_str()); 
00603    nbitsR =atoi(tokens[2].c_str()); 
00604    tokens.clear();
00605    
00606    tokens.erase(tokens.begin(),tokens.end()); 
00607    Tokenize (LutDescriptionG, tokens, "\\");
00608    lengthG=atoi(tokens[0].c_str()); 
00609    debG   =atoi(tokens[1].c_str()); 
00610    nbitsG =atoi(tokens[2].c_str()); 
00611    tokens.clear();  
00612    
00613    tokens.erase(tokens.begin(),tokens.end()); 
00614    Tokenize (LutDescriptionB, tokens, "\\");
00615    lengthB=atoi(tokens[0].c_str()); 
00616    debB   =atoi(tokens[1].c_str()); 
00617    nbitsB =atoi(tokens[2].c_str()); 
00618    tokens.clear();
00619  
00620    
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    
00632    
00633    unsigned char *LUTRGBA = (unsigned char *)calloc(1024,1); 
00634    if (!LUTRGBA) {
00635       return NULL;
00636    }
00637    memset(LUTRGBA, 0, 1024);
00638         
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) 
00649       mult=2;               
00650    else                     
00651       mult=1; 
00652  
00653    
00654    
00655    
00656    
00657    
00658    
00659    
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; 
00681       a+=4; 
00682    } 
00683    
00684    
00685    
00686    return(LUTRGBA);   
00687 } 
00688 
00695 std::string gdcmHeader::GetTransfertSyntaxName(void) { 
00696    
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    
00703    gdcmTS * ts = gdcmGlobal::GetTS();
00704    std::string tsName=ts->GetValue(TransfertSyntax);
00705    
00706    return tsName;
00707 }
00708 
00716 void gdcmHeader::SetImageDataSize(size_t ImageDataSize) {
00717    std::string content1;
00718    char car[20];
00719         
00720    
00721    
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    
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       
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               
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                  
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 
00788 
00795 bool gdcmHeader::anonymizeHeader() {
00796 
00797   gdcmHeaderEntry *patientNameHE = GetHeaderEntryByNumber (0x0010, 0x0010);
00798  
00799     
00800   ReplaceIfExistByNumber ("  ",0x0010, 0x2154); 
00801   ReplaceIfExistByNumber ("  ",0x0010, 0x1040); 
00802   ReplaceIfExistByNumber ("  ",0x0010, 0x0020); 
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   
00813   
00814   
00815 
00816 
00817 
00818 
00819 
00820 
00821 
00822 
00823 
00824 
00825 
00826 
00827 
00828 
00829 
00830 
00831 
00832 
00833 
00834 
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  return true;  
00864  }
00865 
00866 
00867 
00868