X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmHeader.cxx;h=8096eb16503fd2d30f4162095497756d87be819b;hb=9a8932b74aab77d55d7b478b1996611c7d588daa;hp=9d7f6a115672e8ae28a2315c33709727dadc2f8c;hpb=4f48626ba6d2dc26d40f07b780b0fdb5fcc04911;p=gdcm.git diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index 9d7f6a11..8096eb16 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -1,16 +1,13 @@ // gdcmHeader.cxx //----------------------------------------------------------------------------- -#include -#include -#include // for isalpha -#include - #include "gdcmHeader.h" #include "gdcmGlobal.h" #include "gdcmUtil.h" #include "gdcmDebug.h" #include "gdcmTS.h" +#include + //----------------------------------------------------------------------------- // Constructor / Destructor /** @@ -28,6 +25,12 @@ gdcmHeader::gdcmHeader(const char *InFilename, bool ignore_shadow): gdcmParser(InFilename,exception_on_error,enable_sequences,ignore_shadow) { + + typedef struct { + guint32 totalSQlength; + guint32 alreadyParsedlength; + } pileElem; + // for some ACR-NEMA images GrPixel, NumPixel is *not* 7fe0,0010 // We may encounter the 'RETired' (0x0028, 0x0200) tag @@ -40,23 +43,134 @@ gdcmHeader::gdcmHeader(const char *InFilename, // This IS the right place for the code - std::string ImageLocation = GetEntryByNumber(0x0028, 0x0200); - if ( ImageLocation == GDCM_UNFOUND ) { // Image Location - GrPixel = 0x7fe0; // default value - } else { - GrPixel = (guint16) atoi( ImageLocation.c_str() ); - } - if (GrPixel == 0xe07f) // sometimes Image Location value doesn't follow - GrPixel = 0x7fe0; // the supposed processor endianity. - // see gdcmData/cr172241.dcm - if (GrPixel != 0x7fe0) - // This is a kludge for old dirty Philips imager. - NumPixel = 0x1010; - else - NumPixel = 0x0010; + std::string ImageLocation = GetEntryByNumber(0x0028, 0x0200); + if ( ImageLocation == GDCM_UNFOUND ) { // Image Location + GrPixel = 0x7fe0; // default value + } else { + GrPixel = (guint16) atoi( ImageLocation.c_str() ); + } + if (GrPixel == 0xe07f) // sometimes Image Location value doesn't follow + GrPixel = 0x7fe0; // the supposed processor endianity. + // see gdcmData/cr172241.dcm + if (GrPixel != 0x7fe0) + // This is a kludge for old dirty Philips imager. + NumPixel = 0x1010; + else + NumPixel = 0x0010; + + TagKey key = gdcmDictEntry::TranslateToKey(GrPixel, NumPixel); + countGrPixel = GetEntry().count(key); + + // we set the SQ Depth of each Header Entry + + int top =-1; + int countSQ = 0; + pileElem pile[100]; // Hope embedded sequence depth is no that long ! + + int currentParsedlength = 0; + int totalElementlength; + std::ostringstream tab; + tab << " "; + + // GDCM_DEBUG + // Sorry; Dealing with e-film breaker images + // will (certainly) cause a lot of troubles ... + // I prefer keeping my 'trace' on . + + for (ListTag::iterator i = listEntries.begin(); + i != listEntries.end(); + ++i) { + (*i)->SetSQDepthLevel(countSQ); + if ( (*i)->GetVR() == "SQ" && (*i)->GetReadLength() != 0) { // SQ found + countSQ++; + top ++; + if ( top >= 20) { +#ifdef GDCM_DEBUG + std::cout << "Kaie ! Kaie! SQ Stack Overflow" << std::endl; +#endif //GDCM_DEBUG + return; + } +#ifdef GDCM_DEBUG + std::cout << "\n >>>>> empile niveau " << top + << "; Lgr SeQ: " << (*i)->GetReadLength() + << "\n" <GetReadLength(); + pile[top].alreadyParsedlength = 0; + currentParsedlength = 0; + + } else { // non SQ found + if (countSQ != 0) { // we are 'inside a SeQuence' + if ( (*i)->GetGroup()==0xfffe && (*i)->GetElement()==0xe0dd) { + // we just found 'end of SeQuence' + +#ifdef GDCM_DEBUG + std::cout << "fffe,e0dd : depile" << std::endl; +#endif //GDCM_DEBUG + + currentParsedlength += 8; // gr:2 elem:2 vr:2 lgt:2 + countSQ --; + top --; + pile[top].alreadyParsedlength += currentParsedlength; + } else { + // we are on a 'standard' elem + // or a Zero-length SeQuence + + totalElementlength = (*i)->GetFullLength(); + currentParsedlength += totalElementlength; + pile[top].alreadyParsedlength += totalElementlength; + + if (pile[top].totalSQlength == 0xffffffff) { +#ifdef GDCM_DEBUG + std::cout << "totalSeQlength == 0xffffffff" << std::endl; +#endif //GDCM_DEBUG + } else { +#ifdef GDCM_DEBUG + std::cout << "alrdyPseLgt:" + << pile[top].alreadyParsedlength << " totSeQlgt: " + << pile[top].totalSQlength << " curPseLgt: " + << currentParsedlength + << std::endl; +#endif //GDCM_DEBUG + while (pile[top].alreadyParsedlength==pile[top].totalSQlength) { +#ifdef GDCM_DEBUG + std::cout << " \n<<<<<< On depile niveau " << top + << " \n" << std::endl; +#endif //GDCM_DEBUG + (*i)->SetSQDepthLevel(countSQ); + currentParsedlength = pile[top].alreadyParsedlength; + countSQ --; + top --; + if (top >=0) { + pile[top].alreadyParsedlength += currentParsedlength +12; + // 12 : length of 'SQ embedded' SQ element + currentParsedlength += 8; // gr:2 elem:2 vr:2 lgt:2 - TagKey key = gdcmDictEntry::TranslateToKey(GrPixel, NumPixel); - countGrPixel = GetEntry().count(key); +#ifdef GDCM_DEBUG + std::cout << pile[top].alreadyParsedlength << " " + << pile[top].totalSQlength << " " + << currentParsedlength + << std::endl; +#endif //GDCM_DEBUG + } + if (top == -1) { + currentParsedlength = 0; + break; + } + } + } + } + } // end : 'inside a SeQuence' + } +#ifdef GDCM_DEBUG + for (int k=0; k<(*i)->GetSQDepthLevel();k++) { + std::cout << tab; + } + (*i)->SetPrintLevel(2); + (*i)->Print(); +#endif //GDCM_DEBUG + } // end for } /** @@ -79,6 +193,57 @@ gdcmHeader::~gdcmHeader (void) { // Print // see gdcmParser.cxx + +/** + * \ingroup gdcmHeader + * \brief Prints the Header Entries (Dicom Elements) + * from the chained list + * and skips the elements belonging to a SeQuence + * @return + */ +void gdcmHeader::PrintEntryNoSQ(std::ostream & os) { + + int depth; + for (ListTag::iterator i = listEntries.begin(); + i != listEntries.end(); + ++i) + { + depth= (*i)->GetSQDepthLevel(); + if ( depth != 0 /*|| (*i)->GetVR() =="SQ" */){ + continue; + } + (*i)->SetPrintLevel(printLevel); + (*i)->Print(os); + } +} + +/** + * \ingroup gdcmHeader + * \brief Prints the Header Entries (Dicom Elements) + * from the chained list + * and indents the elements belonging to any SeQuence + * \warning : will be removed + * @return + */ +void gdcmHeader::PrintEntryNiceSQ(std::ostream & os) { + std::ostringstream tab; + tab << " "; + + int depth; + for (ListTag::iterator i = listEntries.begin(); + i != listEntries.end(); + ++i) { + depth= (*i)->GetSQDepthLevel(); + if (depth != 0) { + for (int k=0;kSetPrintLevel(printLevel); + (*i)->Print(os); + + } // end for +} + //----------------------------------------------------------------------------- // Public @@ -443,7 +608,10 @@ size_t gdcmHeader::GetPixelOffset(void) { // pb : sometimes , (0x0088,0x0200) exists, but doesn't contain *anything* // see gdcmData/MxTwinLossLess.dcm ... - //std::string icone = GetEntryByNumber(0x0088,0x0200); //icone image sequence + /** + * \todo Clean me + *std::string icone = GetEntryByNumber(0x0088,0x0200); //icone image sequence + */ IterHT it = GetHeaderEntrySameNumber(GrPixel,NumPixel); TagKey key = gdcmDictEntry::TranslateToKey(GrPixel,NumPixel); @@ -456,9 +624,11 @@ size_t gdcmHeader::GetPixelOffset(void) { if (PixelElement) { return PixelElement->GetOffset(); } else { -/* std::cout << "Big trouble : Pixel Element (" +#ifdef GDCM_DEBUG + std::cout << "Big trouble : Pixel Element (" << std::hex << GrPixel<<","<< NumPixel<< ") NOT found" - << std::endl; */ + << std::endl; +#endif //GDCM_DEBUG return 0; } } @@ -485,9 +655,11 @@ size_t gdcmHeader::GetPixelAreaLength(void) { if (PixelElement) { return PixelElement->GetLength(); } else { -/* std::cout << "Big trouble : Pixel Element (" +#ifdef GDCM_DEBUG + std::cout << "Big trouble : Pixel Element (" << std::hex << GrPixel<<","<< NumPixel<< ") NOT found" - << std::endl;*/ + << std::endl; +#endif //GDCM_DEBUG return 0; } } @@ -521,7 +693,9 @@ bool gdcmHeader::HasLUT(void) { return false; // Blue Palette Color Lookup Table Data if ( !GetHeaderEntryByNumber(0x0028,0x1203) ) - return false; + return false; + // FIXME : (0x0028,0x3006) : LUT Data (CTX dependent) + // NOT taken into account, but we don't know how to use it ... return true; } @@ -628,7 +802,7 @@ unsigned char * gdcmHeader::GetLUTRGBA(void) { } // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT - unsigned char *LUTRGBA = (unsigned char *)calloc(1024,1); // 256 * 4 (R, G, B, Alpha) + unsigned char *LUTRGBA = new unsigned char[1024]; // 256 * 4 (R, G, B, Alpha) if (!LUTRGBA) { return NULL; } @@ -716,7 +890,7 @@ void gdcmHeader::SetImageDataSize(size_t ImageDataSize) { char car[20]; // Assumes HeaderEntry (GrPixel, NumPixel) is unique ... - // TODO deal with multiplicity (see gdcmData/icone.dcm) + //\todo deal with multiplicity (see gdcmData/icone.dcm) sprintf(car,"%d",ImageDataSize); gdcmHeaderEntry *a = GetHeaderEntryByNumber(GrPixel, NumPixel);