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