00001
00002
00003 #include "gdcmParser.h"
00004 #include "gdcmUtil.h"
00005 #include <errno.h>
00006
00007
00008 #ifdef _MSC_VER
00009 #include <winsock.h>
00010 #else
00011 #include <netinet/in.h>
00012 #endif
00013
00014 #ifdef GDCM_NO_ANSI_STRING_STREAM
00015 # include <strstream>
00016 # define ostringstream ostrstream
00017 # else
00018 # include <sstream>
00019 #endif
00020 # include <iomanip>
00021
00022 #define UI1_2_840_10008_1_2 "1.2.840.10008.1.2"
00023 #define UI1_2_840_10008_1_2_1 "1.2.840.10008.1.2.1"
00024 #define UI1_2_840_10008_1_2_2 "1.2.840.10008.1.2.2"
00025 #define UI1_2_840_10008_1_2_1_99 "1.2.840.10008.1.2.1.99"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 const unsigned int gdcmParser::HEADER_LENGTH_TO_READ = 256;
00070
00071
00072 const unsigned int gdcmParser::MAX_SIZE_LOAD_ELEMENT_VALUE = 4096;
00073
00074
00075
00076 const unsigned int gdcmParser::MAX_SIZE_PRINT_ELEMENT_VALUE = 64;
00077
00078
00079
00094 gdcmParser::gdcmParser(const char *InFilename,
00095 bool exception_on_error,
00096 bool enable_sequences,
00097 bool ignore_shadow) {
00098 enableSequences=enable_sequences;
00099 ignoreShadow =ignore_shadow;
00100
00101 SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE);
00102 filename = InFilename;
00103 Initialise();
00104
00105 if ( !OpenFile(exception_on_error))
00106 return;
00107 if (ParseHeader()) {
00108 LoadHeaderEntries();
00109 }
00110 CloseFile();
00111
00112 wasUpdated = 0;
00113 printLevel = 1;
00114 }
00115
00121 gdcmParser::gdcmParser(bool exception_on_error) {
00122 enableSequences=0;
00123
00124 SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE);
00125 Initialise();
00126
00127 wasUpdated = 0;
00128 printLevel = 1;
00129 }
00130
00135 gdcmParser::~gdcmParser (void) {
00136 RefPubDict = NULL;
00137 RefShaDict = NULL;
00138 }
00139
00140
00141
00148 void gdcmParser::PrintEntry(std::ostream & os) {
00149 std::ostringstream s;
00150
00151 for (ListTag::iterator i = listEntries.begin();
00152 i != listEntries.end();
00153 ++i)
00154 {
00155 (*i)->SetPrintLevel(printLevel);
00156 (*i)->Print(os);
00157 }
00158 os<<s.str();
00159 }
00160
00166 void gdcmParser::PrintPubDict(std::ostream & os) {
00167 RefPubDict->Print(os);
00168 }
00169
00175 void gdcmParser::PrintShaDict(std::ostream & os) {
00176 RefShaDict->Print(os);
00177 }
00178
00179
00180
00185 gdcmDict *gdcmParser::GetPubDict(void) {
00186 return(RefPubDict);
00187 }
00188
00193 gdcmDict *gdcmParser::GetShaDict(void) {
00194 return(RefShaDict);
00195 }
00196
00202 bool gdcmParser::SetShaDict(gdcmDict *dict){
00203 RefShaDict=dict;
00204 return(!RefShaDict);
00205 }
00206
00212 bool gdcmParser::SetShaDict(DictKey dictName){
00213 RefShaDict=gdcmGlobal::GetDicts()->GetDict(dictName);
00214 return(!RefShaDict);
00215 }
00216
00226 bool gdcmParser::IsReadable(void) {
00227 if(filetype==Unknown) {
00228 return(false);
00229 }
00230 if(listEntries.size()<=0) {
00231 return(false);
00232 }
00233
00234 return(true);
00235 }
00236
00243 bool gdcmParser::IsImplicitVRLittleEndianTransferSyntax(void) {
00244 gdcmHeaderEntry *Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00245 if ( !Element )
00246 return false;
00247 LoadHeaderEntrySafe(Element);
00248
00249 std::string Transfer = Element->GetValue();
00250 if ( Transfer == UI1_2_840_10008_1_2 )
00251 return true;
00252 return false;
00253 }
00254
00261 bool gdcmParser::IsExplicitVRLittleEndianTransferSyntax(void) {
00262 gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00263 if ( !Element )
00264 return false;
00265 LoadHeaderEntrySafe(Element);
00266
00267 std::string Transfer = Element->GetValue();
00268 if ( Transfer == UI1_2_840_10008_1_2_1 )
00269 return true;
00270 return false;
00271 }
00272
00279 bool gdcmParser::IsDeflatedExplicitVRLittleEndianTransferSyntax(void) {
00280 gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00281 if ( !Element )
00282 return false;
00283 LoadHeaderEntrySafe(Element);
00284
00285 std::string Transfer = Element->GetValue();
00286 if ( Transfer == UI1_2_840_10008_1_2_1_99 )
00287 return true;
00288 return false;
00289 }
00290
00297 bool gdcmParser::IsExplicitVRBigEndianTransferSyntax(void) {
00298 gdcmHeaderEntry* Element = GetHeaderEntryByNumber(0x0002, 0x0010);
00299 if ( !Element )
00300 return false;
00301 LoadHeaderEntrySafe(Element);
00302
00303 std::string Transfer = Element->GetValue();
00304 if ( Transfer == UI1_2_840_10008_1_2_2 )
00305 return true;
00306 return false;
00307 }
00308
00315 FileType gdcmParser::GetFileType(void) {
00316 return(filetype);
00317 }
00318
00325 FILE *gdcmParser::OpenFile(bool exception_on_error)
00326 throw(gdcmFileError)
00327 {
00328 fp=fopen(filename.c_str(),"rb");
00329 if(exception_on_error)
00330 {
00331 if(!fp)
00332 throw gdcmFileError("gdcmParser::gdcmParser(const char *, bool)");
00333 }
00334
00335 if ( fp )
00336 {
00337 guint16 zero;
00338 fread(&zero, (size_t)2, (size_t)1, fp);
00339
00340
00341 if( zero == 0x0008 || zero == 0x0800 || zero == 0x0002 || zero == 0x0200)
00342 return(fp);
00343
00344
00345 fseek(fp, 126L, SEEK_CUR);
00346 char dicm[4];
00347 fread(dicm, (size_t)4, (size_t)1, fp);
00348 if( memcmp(dicm, "DICM", 4) == 0 )
00349 return(fp);
00350
00351 fclose(fp);
00352 dbg.Verbose(0, "gdcmParser::OpenFile not DICOM/ACR", filename.c_str());
00353 }
00354 else {
00355 dbg.Verbose(0, "gdcmParser::OpenFile cannot open file", filename.c_str());
00356 }
00357 return(NULL);
00358 }
00359
00365 bool gdcmParser::CloseFile(void) {
00366 int closed = fclose(fp);
00367 fp = (FILE *)0;
00368 if (! closed)
00369 return false;
00370 return true;
00371 }
00372
00381 bool gdcmParser::Write(FILE *fp, FileType type) {
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 if (type == ImplicitVR)
00402 {
00403 std::string implicitVRTransfertSyntax = UI1_2_840_10008_1_2;
00404 ReplaceOrCreateByNumber(implicitVRTransfertSyntax,0x0002, 0x0010);
00405
00406
00407
00408
00409
00410 SetEntryLengthByNumber(18, 0x0002, 0x0010);
00411 }
00412
00413 if (type == ExplicitVR)
00414 {
00415 std::string explicitVRTransfertSyntax = UI1_2_840_10008_1_2_1;
00416 ReplaceOrCreateByNumber(explicitVRTransfertSyntax,0x0002, 0x0010);
00417
00418
00419
00420
00421
00422 SetEntryLengthByNumber(20, 0x0002, 0x0010);
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 WriteEntries(fp,type);
00434 return(true);
00435 }
00436
00446 bool gdcmParser::ReplaceOrCreateByNumber(std::string Value,
00447 guint16 Group,
00448 guint16 Elem ){
00449 if (CheckIfEntryExistByNumber(Group, Elem) == 0) {
00450 gdcmHeaderEntry *a =NewHeaderEntryByNumber(Group, Elem);
00451 if (a == NULL)
00452 return false;
00453 AddHeaderEntry(a);
00454 }
00455 SetEntryByNumber(Value, Group, Elem);
00456 return(true);
00457 }
00458
00469 bool gdcmParser::ReplaceOrCreateByNumber(char* Value, guint16 Group, guint16 Elem ) {
00470 gdcmHeaderEntry* nvHeaderEntry=NewHeaderEntryByNumber(Group, Elem);
00471
00472 if(!nvHeaderEntry)
00473 return(false);
00474
00475 AddHeaderEntry(nvHeaderEntry);
00476
00477 std::string v = Value;
00478 SetEntryByNumber(v, Group, Elem);
00479 return(true);
00480 }
00481
00491 bool gdcmParser::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem )
00492 {
00493 std::string v = Value;
00494 SetEntryByNumber(v, Group, Elem);
00495 return true;
00496 }
00497
00498
00499
00500
00509 int gdcmParser::CheckIfEntryExistByNumber(guint16 group, guint16 element ) {
00510 std::string key = gdcmDictEntry::TranslateToKey(group, element );
00511 return (tagHT.count(key));
00512 }
00513
00524 std::string gdcmParser::GetEntryByName(std::string tagName) {
00525 gdcmDictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName);
00526 if( dictEntry == NULL)
00527 return GDCM_UNFOUND;
00528
00529 return(GetEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement()));
00530 }
00531
00546 std::string gdcmParser::GetEntryVRByName(std::string tagName) {
00547 gdcmDictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName);
00548 if( dictEntry == NULL)
00549 return GDCM_UNFOUND;
00550
00551 gdcmHeaderEntry* elem = GetHeaderEntryByNumber(dictEntry->GetGroup(),
00552 dictEntry->GetElement());
00553 return elem->GetVR();
00554 }
00555
00566 std::string gdcmParser::GetEntryByNumber(guint16 group, guint16 element){
00567 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
00568 if ( ! tagHT.count(key))
00569 return GDCM_UNFOUND;
00570 return tagHT.find(key)->second->GetValue();
00571 }
00572
00588 std::string gdcmParser::GetEntryVRByNumber(guint16 group, guint16 element) {
00589 gdcmHeaderEntry* elem = GetHeaderEntryByNumber(group, element);
00590 if ( !elem )
00591 return GDCM_UNFOUND;
00592 return elem->GetVR();
00593 }
00594
00602 bool gdcmParser::SetEntryByName(std::string content,std::string tagName) {
00603 gdcmDictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName);
00604 if( dictEntry == NULL)
00605 return false;
00606
00607 return(SetEntryByNumber(content,dictEntry->GetGroup(),
00608 dictEntry->GetElement()));
00609 }
00610
00621 bool gdcmParser::SetEntryByNumber(std::string content,
00622 guint16 group,
00623 guint16 element)
00624 {
00625 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
00626 if ( ! tagHT.count(key))
00627 return false;
00628 int l = content.length();
00629 if(l%2)
00630 {
00631 l++;
00632 content = content + '\0';
00633 }
00634
00635 gdcmHeaderEntry * a;
00636 IterHT p;
00637 TagHeaderEntryHT::iterator p2;
00638
00639
00640
00641
00642
00643
00644 a = ((tagHT.equal_range(key)).first)->second;
00645
00646 a-> SetValue(content);
00647
00648 std::string vr = a->GetVR();
00649
00650 guint32 lgr;
00651 if( (vr == "US") || (vr == "SS") )
00652 lgr = 2;
00653 else if( (vr == "UL") || (vr == "SL") )
00654 lgr = 4;
00655 else
00656 lgr = l;
00657
00658 a->SetLength(lgr);
00659 return true;
00660 }
00661
00674 bool gdcmParser::SetEntryLengthByNumber(guint32 l,
00675 guint16 group,
00676 guint16 element)
00677 {
00678 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
00679 if ( ! tagHT.count(key))
00680 return false;
00681 if (l%2) l++;
00682 ( ((tagHT.equal_range(key)).first)->second )->SetLength(l);
00683
00684 return true ;
00685 }
00686
00695 size_t gdcmParser::GetEntryOffsetByNumber(guint16 Group, guint16 Elem)
00696 {
00697 gdcmHeaderEntry* Entry = GetHeaderEntryByNumber(Group, Elem);
00698 if (!Entry)
00699 {
00700 dbg.Verbose(1, "gdcmParser::GetHeaderEntryByNumber",
00701 "failed to Locate gdcmHeaderEntry");
00702 return (size_t)0;
00703 }
00704 return Entry->GetOffset();
00705 }
00706
00715 void * gdcmParser::GetEntryVoidAreaByNumber(guint16 Group, guint16 Elem)
00716 {
00717 gdcmHeaderEntry* Entry = GetHeaderEntryByNumber(Group, Elem);
00718 if (!Entry)
00719 {
00720 dbg.Verbose(1, "gdcmParser::GetHeaderEntryByNumber",
00721 "failed to Locate gdcmHeaderEntry");
00722 return (NULL);
00723 }
00724 return Entry->GetVoidArea();
00725 }
00726
00734 void *gdcmParser::LoadEntryVoidArea(guint16 Group, guint16 Elem)
00735 {
00736 gdcmHeaderEntry * Element= GetHeaderEntryByNumber(Group, Elem);
00737 if ( !Element )
00738 return NULL;
00739 size_t o =(size_t)Element->GetOffset();
00740 fseek(fp, o, SEEK_SET);
00741 int l=Element->GetLength();
00742 void * a = malloc(l);
00743 if(!a)
00744 return NULL;
00745
00746 SetEntryVoidAreaByNumber(a, Group, Elem);
00747
00748 size_t l2 = fread(a, 1, l ,fp);
00749 if(l != l2)
00750 {
00751 free(a);
00752 return NULL;
00753 }
00754
00755 return a;
00756 }
00757
00766 bool gdcmParser::SetEntryVoidAreaByNumber(void * area,
00767 guint16 group,
00768 guint16 element)
00769 {
00770 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
00771 if ( ! tagHT.count(key))
00772 return false;
00773 ( ((tagHT.equal_range(key)).first)->second )->SetVoidArea(area);
00774 return true;
00775 }
00776
00782 void gdcmParser::UpdateShaEntries(void) {
00783 gdcmDictEntry *entry;
00784 std::string vr;
00785
00786 for(ListTag::iterator it=listEntries.begin();
00787 it!=listEntries.end();
00788 ++it)
00789 {
00790
00791 if((*it)->GetGroup()%2==0)
00792 continue;
00793
00794
00795 if(RefShaDict)
00796 entry=RefShaDict->GetDictEntryByNumber((*it)->GetGroup(),(*it)->GetElement());
00797 else
00798 entry=NULL;
00799
00800 if((*it)->IsImplicitVR())
00801 vr="Implicit";
00802 else
00803 vr=(*it)->GetVR();
00804
00805 (*it)->SetValue(GetHeaderEntryUnvalue(*it));
00806 if(entry){
00807
00808 (*it)->SetDictEntry(entry);
00809 CheckHeaderEntryVR(*it,vr);
00810
00811 (*it)->SetValue(GetHeaderEntryValue(*it));
00812 }
00813 else
00814 {
00815
00816 (*it)->SetDictEntry(NewVirtualDictEntry((*it)->GetGroup(),(*it)->GetElement(),vr));
00817 }
00818 }
00819 }
00820
00829 gdcmHeaderEntry *gdcmParser::GetHeaderEntryByName(std::string tagName) {
00830 gdcmDictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName);
00831 if( dictEntry == NULL)
00832 return NULL;
00833
00834 return(GetHeaderEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement()));
00835 }
00836
00848 gdcmHeaderEntry* gdcmParser::GetHeaderEntryByNumber(guint16 group, guint16 element)
00849 {
00850 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
00851 if ( ! tagHT.count(key))
00852 return NULL;
00853 return tagHT.find(key)->second;
00854 }
00855
00864 IterHT gdcmParser::GetHeaderEntrySameNumber(guint16 group, guint16 element){
00865 TagKey key = gdcmDictEntry::TranslateToKey(group, element);
00866 return (tagHT.equal_range(key));
00867 }
00868
00877 void gdcmParser::LoadHeaderEntrySafe(gdcmHeaderEntry * entry) {
00878 long PositionOnEntry = ftell(fp);
00879 LoadHeaderEntry(entry);
00880 fseek(fp, PositionOnEntry, SEEK_SET);
00881 }
00882
00892 void gdcmParser::UpdateGroupLength(bool SkipSequence, FileType type) {
00893 guint16 gr, el;
00894 std::string vr;
00895
00896 gdcmHeaderEntry *elem;
00897 char trash[10];
00898 std::string str_trash;
00899
00900 GroupKey key;
00901 GroupHT groupHt;
00902 TagKey tk;
00903
00904
00905
00906 gdcmHeaderEntry *elemZ;
00907
00908
00909
00910 for (TagHeaderEntryHT::iterator tag2 = tagHT.begin();
00911 tag2 != tagHT.end();
00912 ++tag2)
00913 {
00914 elem = tag2->second;
00915 gr = elem->GetGroup();
00916 el = elem->GetElement();
00917 vr = elem->GetVR();
00918
00919 sprintf(trash, "%04x", gr);
00920 key = trash;
00921
00922
00923
00924
00925 if (SkipSequence && vr == "SQ")
00926 continue;
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938 if ( groupHt.count(key) == 0)
00939 {
00940 if (el == 0x0000)
00941 {
00942 groupHt[key] = 0;
00943 }
00944 else
00945 {
00946 groupHt[key] = 2 + 2 + 4 + elem->GetLength();
00947 }
00948 }
00949 else
00950 {
00951 if (type == ExplicitVR)
00952 {
00953 if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") )
00954 {
00955 groupHt[key] += 4;
00956 }
00957 }
00958 groupHt[key] += 2 + 2 + 4 + elem->GetLength();
00959 }
00960 }
00961
00962 unsigned short int gr_bid;
00963
00964 for (GroupHT::iterator g = groupHt.begin();
00965 g != groupHt.end();
00966 ++g)
00967 {
00968
00969
00970 sscanf(g->first.c_str(),"%x",&gr_bid);
00971 tk = g->first + "|0000";
00972
00973 if ( tagHT.count(tk) == 0)
00974 {
00975 gdcmDictEntry * tagZ = new gdcmDictEntry(gr_bid, 0x0000, "UL");
00976 elemZ = new gdcmHeaderEntry(tagZ);
00977 elemZ->SetLength(4);
00978 AddHeaderEntry(elemZ);
00979 }
00980 else
00981 {
00982 elemZ=GetHeaderEntryByNumber(gr_bid, 0x0000);
00983 }
00984 sprintf(trash ,"%d",g->second);
00985 str_trash=trash;
00986 elemZ->SetValue(str_trash);
00987 }
00988 }
00989
01003 void gdcmParser::WriteEntries(FILE *_fp,FileType type)
01004 {
01005 guint16 gr, el;
01006 guint32 lgr;
01007 std::string value;
01008 const char * val;
01009 std::string vr;
01010 guint32 val_uint32;
01011 guint16 val_uint16;
01012 guint16 valZero =0;
01013 void *voidArea;
01014 std::vector<std::string> tokens;
01015
01016
01017
01018
01019
01020
01021
01022
01023 void *ptr;
01024
01025
01026 int compte =0;
01027
01028 for (ListTag::iterator tag2=listEntries.begin();
01029 tag2 != listEntries.end();
01030 ++tag2)
01031 {
01032
01033
01034 if(((*tag2)->GetLength())%2==1)
01035 {
01036 (*tag2)->SetValue((*tag2)->GetValue()+"\0");
01037 (*tag2)->SetLength((*tag2)->GetLength()+1);
01038 }
01039
01040 gr = (*tag2)->GetGroup();
01041 el = (*tag2)->GetElement();
01042 lgr = (*tag2)->GetReadLength();
01043 val = (*tag2)->GetValue().c_str();
01044 vr = (*tag2)->GetVR();
01045 voidArea = (*tag2)->GetVoidArea();
01046
01047 if ( type == ACR )
01048 {
01049 if (gr < 0x0008) continue;
01050 if (gr %2) continue;
01051 if (vr == "SQ" ) continue;
01052
01053
01054 if (gr == 0xfffe ) continue;
01055 }
01056
01057 fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp);
01058 fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp);
01059
01060
01061 if ( (type == ExplicitVR) || (type == DICOMDIR) )
01062 {
01063
01064 guint16 z=0, shortLgr;
01065 if (vr == "unkn")
01066 {
01067 shortLgr=lgr;
01068 fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,_fp);
01069 fwrite ( &z, (size_t)2 ,(size_t)1 ,_fp);
01070 }
01071 else
01072 {
01073 if (gr != 0xfffe)
01074 {
01075 if (vr == "unkn")
01076 fwrite(&z,(size_t)2 ,(size_t)1 ,_fp);
01077 else
01078 fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,_fp);
01079 }
01080
01081 if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") || gr == 0xfffe)
01082 {
01083 if (gr != 0xfffe)
01084 fwrite ( &z, (size_t)2 ,(size_t)1 ,_fp);
01085 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);
01086 }
01087 else
01088 {
01089 shortLgr=lgr;
01090 fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,_fp);
01091 }
01092 }
01093 }
01094 else
01095 {
01096 fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);
01097 }
01098
01099
01100
01101 if (vr == "SQ") continue;
01102 if (gr == 0xfffe)continue;
01103
01104 if (voidArea != NULL)
01105 {
01106 fwrite ( voidArea,(size_t)lgr ,(size_t)1 ,_fp);
01107 continue;
01108 }
01109
01110 if (vr == "US" || vr == "SS")
01111 {
01112 tokens.erase(tokens.begin(),tokens.end());
01113 Tokenize ((*tag2)->GetValue(), tokens, "\\");
01114 for (unsigned int i=0; i<tokens.size();i++)
01115 {
01116 val_uint16 = atoi(tokens[i].c_str());
01117 ptr = &val_uint16;
01118 fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
01119 }
01120 tokens.clear();
01121 continue;
01122 }
01123 if (vr == "UL" || vr == "SL")
01124 {
01125 tokens.erase(tokens.begin(),tokens.end());
01126 Tokenize ((*tag2)->GetValue(), tokens, "\\");
01127 for (unsigned int i=0; i<tokens.size();i++)
01128 {
01129 val_uint32 = atoi(tokens[i].c_str());
01130 ptr = &val_uint32;
01131 fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
01132 }
01133 tokens.clear();
01134 continue;
01135 }
01136
01137
01138
01139
01140
01141 if ((gr == GrPixel) && (el == NumPixel) ) {
01142 compte++;
01143 if (compte == countGrPixel)
01144 break;
01145 }
01146 fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp);
01147 }
01148 }
01149
01156 guint32 gdcmParser::SwapLong(guint32 a) {
01157 switch (sw) {
01158 case 0 :
01159 break;
01160 case 4321 :
01161 a=( ((a<<24) & 0xff000000) | ((a<<8) & 0x00ff0000) |
01162 ((a>>8) & 0x0000ff00) | ((a>>24) & 0x000000ff) );
01163 break;
01164
01165 case 3412 :
01166 a=( ((a<<16) & 0xffff0000) | ((a>>16) & 0x0000ffff) );
01167 break;
01168
01169 case 2143 :
01170 a=( ((a<<8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff) );
01171 break;
01172 default :
01173 dbg.Error(" gdcmParser::SwapLong : unset swap code");
01174 a=0;
01175 }
01176 return(a);
01177 }
01178
01185 guint32 gdcmParser::UnswapLong(guint32 a) {
01186 return (SwapLong(a));
01187 }
01188
01194 guint16 gdcmParser::SwapShort(guint16 a) {
01195 if ( (sw==4321) || (sw==2143) )
01196 a =(((a<<8) & 0x0ff00) | ((a>>8)&0x00ff));
01197 return (a);
01198 }
01199
01205 guint16 gdcmParser::UnswapShort(guint16 a) {
01206 return (SwapShort(a));
01207 }
01208
01209
01210
01216 bool gdcmParser::ParseHeader(bool exception_on_error) throw(gdcmFormatError) {
01217
01218 rewind(fp);
01219 if (!CheckSwap())
01220 return false;
01221
01222 gdcmHeaderEntry *newHeaderEntry = (gdcmHeaderEntry *)0;
01223 while ( (newHeaderEntry = ReadNextHeaderEntry()) ) {
01224 SkipHeaderEntry(newHeaderEntry);
01225 if ( (ignoreShadow==0) || (newHeaderEntry->GetGroup()%2) == 0) {
01226 AddHeaderEntry(newHeaderEntry);
01227 }
01228 }
01229 return true;
01230 }
01231
01237 void gdcmParser::LoadHeaderEntries(void) {
01238 rewind(fp);
01239 for (ListTag::iterator i = GetListEntry().begin();
01240 i != GetListEntry().end();
01241 ++i)
01242 {
01243 LoadHeaderEntry(*i);
01244 }
01245
01246 rewind(fp);
01247
01248
01249 std::string PhotometricInterpretation = GetEntryByNumber(0x0028,0x0004);
01250 if( PhotometricInterpretation == "PALETTE COLOR " ) {
01251 LoadEntryVoidArea(0x0028,0x1200);
01252 LoadEntryVoidArea(0x0028,0x1201);
01253 LoadEntryVoidArea(0x0028,0x1202);
01254 LoadEntryVoidArea(0x0028,0x1203);
01255
01256 LoadEntryVoidArea(0x0028,0x1221);
01257 LoadEntryVoidArea(0x0028,0x1222);
01258 LoadEntryVoidArea(0x0028,0x1223);
01259 }
01260
01261 LoadEntryVoidArea(0x0028,0x3006);
01262
01263
01264
01265
01266
01267
01268
01269 std::string RecCode;
01270 RecCode = GetEntryByNumber(0x0008, 0x0010);
01271 if (RecCode == "ACRNEMA_LIBIDO_1.1" ||
01272 RecCode == "CANRME_AILIBOD1_1." )
01273 {
01274 filetype = ACR_LIBIDO;
01275 std::string rows = GetEntryByNumber(0x0028, 0x0010);
01276 std::string columns = GetEntryByNumber(0x0028, 0x0011);
01277 SetEntryByNumber(columns, 0x0028, 0x0010);
01278 SetEntryByNumber(rows , 0x0028, 0x0011);
01279 }
01280
01281 }
01282
01289 void gdcmParser::LoadHeaderEntry(gdcmHeaderEntry *Entry) {
01290 size_t item_read;
01291 guint16 group = Entry->GetGroup();
01292 std::string vr= Entry->GetVR();
01293 guint32 length = Entry->GetLength();
01294 bool SkipLoad = false;
01295
01296 fseek(fp, (long)Entry->GetOffset(), SEEK_SET);
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308 if( group == 0xfffe )
01309 SkipLoad = true;
01310
01311 if ( SkipLoad ) {
01312 Entry->SetLength(0);
01313 Entry->SetValue("gdcm::Skipped");
01314 return;
01315 }
01316
01317
01318 if ( length == 0 ) {
01319 Entry->SetValue("");
01320 return;
01321 }
01322
01323
01324
01325
01326 if (length > MaxSizeLoadEntry) {
01327 std::ostringstream s;
01328 s << "gdcm::NotLoaded.";
01329 s << " Address:" << (long)Entry->GetOffset();
01330 s << " Length:" << Entry->GetLength();
01331 s << " x(" << std::hex << Entry->GetLength() << ")";
01332 Entry->SetValue(s.str());
01333 return;
01334 }
01335
01336
01337
01338
01339
01340
01341
01342
01343 if ( IsHeaderEntryAnInteger(Entry) ) {
01344 guint32 NewInt;
01345 std::ostringstream s;
01346 int nbInt;
01347 if (vr == "US" || vr == "SS") {
01348 nbInt = length / 2;
01349 NewInt = ReadInt16();
01350 s << NewInt;
01351 if (nbInt > 1){
01352 for (int i=1; i < nbInt; i++) {
01353 s << '\\';
01354 NewInt = ReadInt16();
01355 s << NewInt;
01356 }
01357 }
01358 }
01359 else if (vr == "UL" || vr == "SL") {
01360 nbInt = length / 4;
01361 NewInt = ReadInt32();
01362 s << NewInt;
01363 if (nbInt > 1) {
01364 for (int i=1; i < nbInt; i++) {
01365 s << '\\';
01366 NewInt = ReadInt32();
01367 s << NewInt;
01368 }
01369 }
01370 }
01371 #ifdef GDCM_NO_ANSI_STRING_STREAM
01372 s << std::ends;
01373 #endif //GDCM_NO_ANSI_STRING_STREAM
01374
01375 Entry->SetValue(s.str());
01376 return;
01377 }
01378
01379
01380 std::string NewValue(length,0);
01381 item_read = fread(&(NewValue[0]), (size_t)length, (size_t)1, fp);
01382 if ( item_read != 1 ) {
01383 dbg.Verbose(1, "gdcmParser::LoadElementValue","unread element value");
01384 Entry->SetValue("gdcm::UnRead");
01385 return;
01386 }
01387
01388 if( (vr == "UI") )
01389 Entry->SetValue(NewValue.c_str());
01390 else
01391 Entry->SetValue(NewValue);
01392 }
01393
01404 void gdcmParser::AddHeaderEntry(gdcmHeaderEntry *newHeaderEntry) {
01405 tagHT.insert( PairHT( newHeaderEntry->GetKey(),newHeaderEntry) );
01406 listEntries.push_back(newHeaderEntry);
01407 wasUpdated = 1;
01408 }
01409
01416 void gdcmParser::FindHeaderEntryLength (gdcmHeaderEntry *Entry) {
01417 guint16 element = Entry->GetElement();
01418 guint16 group = Entry->GetGroup();
01419 std::string vr = Entry->GetVR();
01420 guint16 length16;
01421 if( (element == NumPixel) && (group == GrPixel) )
01422 {
01423 dbg.SetDebug(GDCM_DEBUG);
01424 dbg.Verbose(2, "gdcmParser::FindLength: ",
01425 "we reached (GrPixel,NumPixel)");
01426 }
01427
01428 if ( (filetype == ExplicitVR) && (! Entry->IsImplicitVR()) )
01429 {
01430 if ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") )
01431 {
01432
01433
01434
01435 fseek(fp, 2L, SEEK_CUR);
01436 guint32 length32 = ReadInt32();
01437
01438 if ( (vr == "OB") && (length32 == 0xffffffff) )
01439 {
01440 Entry->SetLength(FindHeaderEntryLengthOB());
01441 return;
01442 }
01443 FixHeaderEntryFoundLength(Entry, length32);
01444 return;
01445 }
01446
01447
01448 length16 = ReadInt16();
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477 if ( (element == 0x0000) && (length16 == 0x0400) )
01478 {
01479 if ( ! IsExplicitVRBigEndianTransferSyntax() )
01480 {
01481 dbg.Verbose(0, "gdcmParser::FindLength", "not explicit VR");
01482 errno = 1;
01483 return;
01484 }
01485 length16 = 4;
01486 SwitchSwapToBigEndian();
01487
01488
01489 guint16 CorrectGroup = SwapShort(Entry->GetGroup());
01490 guint16 CorrectElem = SwapShort(Entry->GetElement());
01491 gdcmDictEntry * NewTag = GetDictEntryByNumber(CorrectGroup,
01492 CorrectElem);
01493 if (!NewTag)
01494 {
01495
01496 NewTag = NewVirtualDictEntry(CorrectGroup, CorrectElem);
01497 }
01498
01499
01500 Entry->SetDictEntry(NewTag);
01501 }
01502
01503
01504 if ( length16 == 0xffff)
01505 {
01506 length16 = 0;
01507
01508
01509
01510
01511 }
01512
01513 FixHeaderEntryFoundLength(Entry, (guint32)length16);
01514 return;
01515 }
01516 else
01517 {
01518
01519
01520
01521
01522
01523
01524 FixHeaderEntryFoundLength(Entry, ReadInt32());
01525 return;
01526 }
01527 }
01528
01534 void gdcmParser::FindHeaderEntryVR( gdcmHeaderEntry *Entry)
01535 {
01536 if (filetype != ExplicitVR)
01537 return;
01538
01539 char VR[3];
01540
01541 long PositionOnEntry = ftell(fp);
01542
01543
01544
01545
01546
01547
01548
01549
01550 int lgrLue=fread (&VR, (size_t)2,(size_t)1, fp);
01551 VR[2]=0;
01552 if(!CheckHeaderEntryVR(Entry,VR))
01553 {
01554 fseek(fp, PositionOnEntry, SEEK_SET);
01555
01556
01557
01558
01559
01560 if ( Entry->IsVRUnknown() )
01561 Entry->SetVR("Implicit");
01562 Entry->SetImplicitVR();
01563 }
01564 }
01565
01576 bool gdcmParser::CheckHeaderEntryVR(gdcmHeaderEntry *Entry, VRKey vr)
01577 {
01578 char msg[100];
01579 bool RealExplicit = true;
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 if ( (!isalpha(vr[0])) && (!isalpha(vr[1])) )
01590 RealExplicit = false;
01591
01592
01593
01594
01595 if ( RealExplicit && !gdcmGlobal::GetVR()->Count(vr) )
01596 RealExplicit= false;
01597
01598 if ( !RealExplicit )
01599 {
01600
01601
01602 sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n",
01603 Entry->GetGroup(),Entry->GetElement());
01604 dbg.Verbose(1, "gdcmParser::FindVR: ",msg);
01605 if (Entry->GetGroup()%2 && Entry->GetElement() == 0x0000) {
01606 gdcmDictEntry* NewEntry = NewVirtualDictEntry(
01607 Entry->GetGroup(),Entry->GetElement(),
01608 "UL","FIXME","Group Length");
01609 Entry->SetDictEntry(NewEntry);
01610 }
01611 return(false);
01612 }
01613
01614 if ( Entry->IsVRUnknown() )
01615 {
01616
01617 if (Entry->GetElement() == 0x0000) {
01618 Entry->SetVR("UL");
01619 } else {
01620 Entry->SetVR(vr);
01621 }
01622 }
01623 else if ( Entry->GetVR() != vr )
01624 {
01625
01626
01627
01628
01629
01630 gdcmDictEntry* NewEntry = NewVirtualDictEntry(
01631 Entry->GetGroup(),Entry->GetElement(),
01632 vr,"FIXME",Entry->GetName());
01633 Entry->SetDictEntry(NewEntry);
01634 }
01635 return(true);
01636 }
01637
01646 std::string gdcmParser::GetHeaderEntryValue(gdcmHeaderEntry *Entry)
01647 {
01648 if ( (IsHeaderEntryAnInteger(Entry)) && (Entry->IsImplicitVR()) )
01649 {
01650 std::string val=Entry->GetValue();
01651 std::string vr=Entry->GetVR();
01652 guint32 length = Entry->GetLength();
01653 std::ostringstream s;
01654 int nbInt;
01655
01656 if (vr == "US" || vr == "SS")
01657 {
01658 guint16 NewInt16;
01659
01660 nbInt = length / 2;
01661 for (int i=0; i < nbInt; i++)
01662 {
01663 if(i!=0)
01664 s << '\\';
01665 NewInt16 = (val[2*i+0]&0xFF)+((val[2*i+1]&0xFF)<<8);
01666 NewInt16 = SwapShort(NewInt16);
01667 s << NewInt16;
01668 }
01669 }
01670
01671 else if (vr == "UL" || vr == "SL")
01672 {
01673 guint32 NewInt32;
01674
01675 nbInt = length / 4;
01676 for (int i=0; i < nbInt; i++)
01677 {
01678 if(i!=0)
01679 s << '\\';
01680 NewInt32= (val[4*i+0]&0xFF)+((val[4*i+1]&0xFF)<<8)+
01681 ((val[4*i+2]&0xFF)<<16)+((val[4*i+3]&0xFF)<<24);
01682 NewInt32=SwapLong(NewInt32);
01683 s << NewInt32;
01684 }
01685 }
01686 #ifdef GDCM_NO_ANSI_STRING_STREAM
01687 s << std::ends;
01688 #endif //GDCM_NO_ANSI_STRING_STREAM
01689 return(s.str());
01690 }
01691
01692 return(Entry->GetValue());
01693 }
01694
01704 std::string gdcmParser::GetHeaderEntryUnvalue(gdcmHeaderEntry *Entry)
01705 {
01706 if ( (IsHeaderEntryAnInteger(Entry)) && (Entry->IsImplicitVR()) )
01707 {
01708 std::string vr=Entry->GetVR();
01709 std::ostringstream s;
01710 std::vector<std::string> tokens;
01711
01712 if (vr == "US" || vr == "SS")
01713 {
01714 guint16 NewInt16;
01715
01716 tokens.erase(tokens.begin(),tokens.end());
01717 Tokenize (Entry->GetValue(), tokens, "\\");
01718 for (unsigned int i=0; i<tokens.size();i++)
01719 {
01720 NewInt16 = atoi(tokens[i].c_str());
01721 s<<(NewInt16&0xFF)<<((NewInt16>>8)&0xFF);
01722 }
01723 tokens.clear();
01724 }
01725 if (vr == "UL" || vr == "SL")
01726 {
01727 guint32 NewInt32;
01728
01729 tokens.erase(tokens.begin(),tokens.end());
01730 Tokenize (Entry->GetValue(), tokens, "\\");
01731 for (unsigned int i=0; i<tokens.size();i++)
01732 {
01733 NewInt32 = atoi(tokens[i].c_str());
01734 s<<(char)(NewInt32&0xFF)<<(char)((NewInt32>>8)&0xFF)
01735 <<(char)((NewInt32>>16)&0xFF)<<(char)((NewInt32>>24)&0xFF);
01736 }
01737 tokens.clear();
01738 }
01739
01740 #ifdef GDCM_NO_ANSI_STRING_STREAM
01741 s << std::ends;
01742 #endif //GDCM_NO_ANSI_STRING_STREAM
01743 return(s.str());
01744 }
01745
01746 return(Entry->GetValue());
01747 }
01748
01755 void gdcmParser::SkipHeaderEntry(gdcmHeaderEntry *entry)
01756 {
01757 SkipBytes(entry->GetLength());
01758 }
01759
01766 void gdcmParser::FixHeaderEntryFoundLength(gdcmHeaderEntry *Entry, guint32 FoundLength)
01767 {
01768 Entry->SetReadLength(FoundLength);
01769
01770 if ( FoundLength == 0xffffffff) {
01771 FoundLength = 0;
01772 }
01773
01774 guint16 gr =Entry->GetGroup();
01775 guint16 el =Entry->GetElement();
01776
01777 if (FoundLength%2) {
01778 std::ostringstream s;
01779 s << "Warning : Tag with uneven length " << FoundLength
01780 << " in x(" << std::hex << gr << "," << el <<")" << std::dec;
01781 dbg.Verbose(0,s.str().c_str());
01782 }
01783
01784
01785
01786 if (FoundLength == 13) {
01787
01788
01789 if ( (Entry->GetGroup() != 0x0008) ||
01790 ( (Entry->GetElement() != 0x0070) && (Entry->GetElement() != 0x0080) ) ){
01791
01792 FoundLength =10;
01793 Entry->SetReadLength(10);
01794 }
01795 }
01796
01797
01798
01799 else if ( (Entry->GetGroup() == 0x0009) &&
01800 ( (Entry->GetElement() == 0x1113) || (Entry->GetElement() == 0x1114) ) ){
01801 FoundLength =4;
01802 Entry->SetReadLength(4);
01803 }
01804
01805
01806
01807 else if ( Entry->GetVR() == "SQ")
01808 {
01809 if (enableSequences)
01810 FoundLength =0;
01811 }
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822 else if(Entry->GetGroup() == 0xfffe)
01823 {
01824
01825 FoundLength =0;
01826
01827
01828
01829 }
01830
01831 Entry->SetUsableLength(FoundLength);
01832 }
01833
01841 bool gdcmParser::IsHeaderEntryAnInteger(gdcmHeaderEntry *Entry) {
01842 guint16 element = Entry->GetElement();
01843 guint16 group = Entry->GetGroup();
01844 std::string vr = Entry->GetVR();
01845 guint32 length = Entry->GetLength();
01846
01847
01848
01849 if ( element == 0 )
01850 {
01851 if (length == 4)
01852 return true;
01853 else
01854 {
01855 std::ostringstream s;
01856 int filePosition = ftell(fp);
01857 s << "Erroneous Group Length element length on : (" \
01858 << std::hex << group << " , " << element
01859 << ") -before- position x(" << filePosition << ")"
01860 << "lgt : " << length;
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872 }
01873 }
01874 if ( (vr == "UL") || (vr == "US") || (vr == "SL") || (vr == "SS") )
01875 return true;
01876
01877 return false;
01878 }
01879
01886 guint32 gdcmParser::FindHeaderEntryLengthOB(void) {
01887
01888 guint16 g;
01889 guint16 n;
01890 long PositionOnEntry = ftell(fp);
01891 bool FoundSequenceDelimiter = false;
01892 guint32 TotalLength = 0;
01893 guint32 ItemLength;
01894
01895 while ( ! FoundSequenceDelimiter)
01896 {
01897 g = ReadInt16();
01898 n = ReadInt16();
01899 if (errno == 1)
01900 return 0;
01901 TotalLength += 4;
01902
01903 if ( g != 0xfffe && g!=0xb00c )
01904 {
01905 char msg[100];
01906 sprintf(msg,"wrong group (%04x) for an item sequence (%04x,%04x)\n",g, g,n);
01907 dbg.Verbose(1, "gdcmParser::FindLengthOB: ",msg);
01908 errno = 1;
01909 return 0;
01910 }
01911 if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) )
01912 FoundSequenceDelimiter = true;
01913 else if ( n != 0xe000 )
01914 {
01915 char msg[100];
01916 sprintf(msg,"wrong element (%04x) for an item sequence (%04x,%04x)\n",
01917 n, g,n);
01918 dbg.Verbose(1, "gdcmParser::FindLengthOB: ",msg);
01919 errno = 1;
01920 return 0;
01921 }
01922 ItemLength = ReadInt32();
01923 TotalLength += ItemLength + 4;
01924
01925 SkipBytes(ItemLength);
01926 }
01927 fseek(fp, PositionOnEntry, SEEK_SET);
01928 return TotalLength;
01929 }
01930
01937 guint16 gdcmParser::ReadInt16(void) {
01938 guint16 g;
01939 size_t item_read;
01940 item_read = fread (&g, (size_t)2,(size_t)1, fp);
01941 if ( item_read != 1 ) {
01942 if(ferror(fp))
01943 dbg.Verbose(0, "gdcmParser::ReadInt16", " File Error");
01944 errno = 1;
01945 return 0;
01946 }
01947 errno = 0;
01948 g = SwapShort(g);
01949 return g;
01950 }
01951
01958 guint32 gdcmParser::ReadInt32(void) {
01959 guint32 g;
01960 size_t item_read;
01961 item_read = fread (&g, (size_t)4,(size_t)1, fp);
01962 if ( item_read != 1 ) {
01963 if(ferror(fp))
01964 dbg.Verbose(0, "gdcmParser::ReadInt32", " File Error");
01965 errno = 1;
01966 return 0;
01967 }
01968 errno = 0;
01969 g = SwapLong(g);
01970 return g;
01971 }
01972
01979 void gdcmParser::SkipBytes(guint32 NBytes) {
01980
01981 (void)fseek(fp, (long)NBytes, SEEK_CUR);
01982 }
01983
01988 void gdcmParser::Initialise(void)
01989 {
01990 RefPubDict = gdcmGlobal::GetDicts()->GetDefaultPubDict();
01991 RefShaDict = (gdcmDict*)0;
01992 }
01993
02003 bool gdcmParser::CheckSwap() {
02004
02005
02006
02007
02008
02009
02010 guint32 x=4;
02011 bool net2host;
02012 guint32 s32;
02013 guint16 s16;
02014
02015 int lgrLue;
02016 char *entCur;
02017 char deb[HEADER_LENGTH_TO_READ];
02018
02019
02020
02021 if (x==ntohs(x))
02022 net2host = true;
02023 else
02024 net2host = false;
02025
02026
02027
02028 lgrLue = fread(deb, 1, HEADER_LENGTH_TO_READ, fp);
02029
02030 entCur = deb + 128;
02031 if(memcmp(entCur, "DICM", (size_t)4) == 0) {
02032 dbg.Verbose(1, "gdcmParser::CheckSwap:", "looks like DICOM Version3");
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049 entCur = deb + 136;
02050
02051
02052
02053
02054
02055
02056 if( (memcmp(entCur, "UL", (size_t)2) == 0) ||
02057 (memcmp(entCur, "OB", (size_t)2) == 0) ||
02058 (memcmp(entCur, "UI", (size_t)2) == 0) ||
02059 (memcmp(entCur, "CS", (size_t)2) == 0) )
02060
02061
02062
02063
02064
02065 {
02066 filetype = ExplicitVR;
02067 dbg.Verbose(1, "gdcmParser::CheckSwap:",
02068 "explicit Value Representation");
02069 }
02070 else
02071 {
02072 filetype = ImplicitVR;
02073 dbg.Verbose(1, "gdcmParser::CheckSwap:",
02074 "not an explicit Value Representation");
02075 }
02076
02077 if (net2host)
02078 {
02079 sw = 4321;
02080 dbg.Verbose(1, "gdcmParser::CheckSwap:",
02081 "HostByteOrder != NetworkByteOrder");
02082 }
02083 else
02084 {
02085 sw = 0;
02086 dbg.Verbose(1, "gdcmParser::CheckSwap:",
02087 "HostByteOrder = NetworkByteOrder");
02088 }
02089
02090
02091
02092 rewind(fp);
02093 fseek (fp, 132L, SEEK_SET);
02094 return true;
02095 }
02096
02097
02098
02099
02100 dbg.Verbose(1, "gdcmParser::CheckSwap:", "not a DICOM Version3 file");
02101 rewind(fp);
02102
02103
02104
02105
02106
02107
02108 entCur = deb + 4;
02109
02110
02111
02112 s32 = *((guint32 *)(entCur));
02113
02114 switch (s32) {
02115 case 0x00040000 :
02116 sw = 3412;
02117 filetype = ACR;
02118 return true;
02119 case 0x04000000 :
02120 sw = 4321;
02121 filetype = ACR;
02122 return true;
02123 case 0x00000400 :
02124 sw = 2143;
02125 filetype = ACR;
02126 return true;
02127 case 0x00000004 :
02128 sw = 0;
02129 filetype = ACR;
02130 return true;
02131 default :
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148 s16 = *((guint16 *)(deb));
02149
02150 switch (s16) {
02151 case 0x0002 :
02152 case 0x0004 :
02153 case 0x0008 :
02154 sw = 0;
02155 filetype = ACR;
02156 return true;
02157 case 0x0200 :
02158 case 0x0400 :
02159 case 0x0800 :
02160 sw = 4321;
02161 filetype = ACR;
02162 return true;
02163 default :
02164 dbg.Verbose(0, "gdcmParser::CheckSwap:",
02165 "ACR/NEMA unfound swap info (Really hopeless !)");
02166 filetype = Unknown;
02167 return false;
02168 }
02169
02170
02171
02172
02173
02174
02175
02176 }
02177 }
02178
02183 void gdcmParser::SwitchSwapToBigEndian(void)
02184 {
02185 dbg.Verbose(1, "gdcmParser::SwitchSwapToBigEndian",
02186 "Switching to BigEndian mode.");
02187 if ( sw == 0 )
02188 {
02189 sw = 4321;
02190 return;
02191 }
02192 if ( sw == 4321 )
02193 {
02194 sw = 0;
02195 return;
02196 }
02197 if ( sw == 3412 )
02198 {
02199 sw = 2143;
02200 return;
02201 }
02202 if ( sw == 2143 )
02203 sw = 3412;
02204 }
02205
02211 void gdcmParser::SetMaxSizeLoadEntry(long NewSize)
02212 {
02213 if (NewSize < 0)
02214 return;
02215 if ((guint32)NewSize >= (guint32)0xffffffff)
02216 {
02217 MaxSizeLoadEntry = 0xffffffff;
02218 return;
02219 }
02220 MaxSizeLoadEntry = NewSize;
02221 }
02222
02223
02234 void gdcmParser::SetMaxSizePrintEntry(long NewSize)
02235 {
02236 if (NewSize < 0)
02237 return;
02238 if ((guint32)NewSize >= (guint32)0xffffffff)
02239 {
02240 MaxSizePrintEntry = 0xffffffff;
02241 return;
02242 }
02243 MaxSizePrintEntry = NewSize;
02244 }
02245
02254 gdcmDictEntry *gdcmParser::GetDictEntryByName(std::string Name)
02255 {
02256 gdcmDictEntry *found = (gdcmDictEntry *)0;
02257 if (!RefPubDict && !RefShaDict)
02258 {
02259 dbg.Verbose(0, "gdcmParser::GetDictEntry",
02260 "we SHOULD have a default dictionary");
02261 }
02262 if (RefPubDict)
02263 {
02264 found = RefPubDict->GetDictEntryByName(Name);
02265 if (found)
02266 return found;
02267 }
02268 if (RefShaDict)
02269 {
02270 found = RefShaDict->GetDictEntryByName(Name);
02271 if (found)
02272 return found;
02273 }
02274 return found;
02275 }
02276
02287 gdcmDictEntry *gdcmParser::GetDictEntryByNumber(guint16 group,guint16 element)
02288 {
02289 gdcmDictEntry *found = (gdcmDictEntry *)0;
02290 if (!RefPubDict && !RefShaDict)
02291 {
02292 dbg.Verbose(0, "gdcmParser::GetDictEntry",
02293 "we SHOULD have a default dictionary");
02294 }
02295 if (RefPubDict)
02296 {
02297 found = RefPubDict->GetDictEntryByNumber(group, element);
02298 if (found)
02299 return found;
02300 }
02301 if (RefShaDict)
02302 {
02303 found = RefShaDict->GetDictEntryByNumber(group, element);
02304 if (found)
02305 return found;
02306 }
02307 return found;
02308 }
02309
02315 gdcmHeaderEntry *gdcmParser::ReadNextHeaderEntry(void) {
02316 guint16 g,n;
02317 gdcmHeaderEntry *NewEntry;
02318 g = ReadInt16();
02319 n = ReadInt16();
02320
02321 if (errno == 1)
02322
02323
02324 return (gdcmHeaderEntry *)0;
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335 NewEntry = NewHeaderEntryByNumber(g, n);
02336 FindHeaderEntryVR(NewEntry);
02337 FindHeaderEntryLength(NewEntry);
02338
02339 if (errno == 1) {
02340
02341 return NULL;
02342 }
02343 NewEntry->SetOffset(ftell(fp));
02344 return NewEntry;
02345 }
02346
02354 gdcmHeaderEntry *gdcmParser::NewHeaderEntryByName(std::string Name)
02355 {
02356 gdcmDictEntry *NewTag = GetDictEntryByName(Name);
02357 if (!NewTag)
02358 NewTag = NewVirtualDictEntry(0xffff, 0xffff, "LO", "unkn", Name);
02359
02360 gdcmHeaderEntry* NewEntry = new gdcmHeaderEntry(NewTag);
02361 if (!NewEntry)
02362 {
02363 dbg.Verbose(1, "gdcmParser::ObtainHeaderEntryByName",
02364 "failed to allocate gdcmHeaderEntry");
02365 return (gdcmHeaderEntry *)0;
02366 }
02367 return NewEntry;
02368 }
02369
02379 gdcmDictEntry *gdcmParser::NewVirtualDictEntry(guint16 group, guint16 element,
02380 std::string vr,
02381 std::string fourth,
02382 std::string name)
02383 {
02384 return gdcmGlobal::GetDicts()->NewVirtualDictEntry(group,element,vr,fourth,name);
02385 }
02386
02395 gdcmHeaderEntry *gdcmParser::NewHeaderEntryByNumber(guint16 Group, guint16 Elem)
02396 {
02397
02398 gdcmDictEntry *DictEntry = GetDictEntryByNumber(Group, Elem);
02399 if (!DictEntry)
02400 DictEntry = NewVirtualDictEntry(Group, Elem);
02401
02402 gdcmHeaderEntry *NewEntry = new gdcmHeaderEntry(DictEntry);
02403 if (!NewEntry)
02404 {
02405 dbg.Verbose(1, "gdcmParser::NewHeaderEntryByNumber",
02406 "failed to allocate gdcmHeaderEntry");
02407 return NULL;
02408 }
02409 return NewEntry;
02410 }
02411
02412
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02453 guint32 gdcmParser::GenerateFreeTagKeyInGroup(guint16 group)
02454 {
02455 for (guint32 elem = 0; elem < UINT32_MAX; elem++)
02456 {
02457 TagKey key = gdcmDictEntry::TranslateToKey(group, elem);
02458 if (tagHT.count(key) == 0)
02459 return elem;
02460 }
02461 return UINT32_MAX;
02462 }
02463
02464