-/**
- * \ingroup gdcmHeader
- * \brief
- *
- * @return
- */
-gdcmHeaderEntry *gdcmHeader::GetHeaderEntryByNumber(guint16 Group, guint16 Elem) {
- gdcmHeaderEntry *HeaderEntry = PubEntrySet.GetHeaderEntryByNumber(Group, Elem);
- if (!HeaderEntry) {
- dbg.Verbose(1, "gdcmHeader::GetHeaderEntryByNumber",
- "failed to Locate gdcmHeaderEntry");
- return NULL;
- }
- return HeaderEntry;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Searches within the public dictionary for a Dicom Element of
- * a given tag.
- * @param tagName name of the searched Dicom Element.
- * @return Corresponding Dicom Element when it exists, and NULL
- * otherwise.
- */
- gdcmHeaderEntry *gdcmHeader::GetHeaderEntryByName(std::string tagName) {
- gdcmDictEntry *dictEntry = RefPubDict->GetTagByName(tagName);
- if( dictEntry == NULL)
- return NULL;
-
- return(GetHeaderEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement()));
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Checks if a given HeaderEntry (group,number)
- * \ exists in the Public HeaderEntrySet
- * @param Group
- * @param Elem
- * @return integer acts as a boolean
- */
-bool gdcmHeader::CheckIfExistByNumber(guint16 Group, guint16 Elem ) {
- return (PubEntrySet.CheckIfExistByNumber(Group, Elem)>0);
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Gets (from Header) the offset of a 'non string' element value
- * \ (LoadElementValue has already be executed)
- * @param Group
- * @param Elem
- * @return File Offset of the Element Value
- */
-size_t gdcmHeader::GetPubEntryOffsetByNumber(guint16 Group, guint16 Elem) {
- gdcmHeaderEntry* Entry = GetHeaderEntryByNumber(Group, Elem);
- if (!Entry) {
- dbg.Verbose(1, "gdcmHeader::GetHeaderEntryByNumber",
- "failed to Locate gdcmHeaderEntry");
- return (size_t)0;
- }
- return Entry->GetOffset();
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Gets (from Header) a 'non string' element value
- * \ (LoadElementValue has already be executed)
- * @param Group
- * @param Elem
- * @return Pointer to the 'non string' area
- */
-void * gdcmHeader::GetPubEntryVoidAreaByNumber(guint16 Group, guint16 Elem) {
- gdcmHeaderEntry* Entry = GetHeaderEntryByNumber(Group, Elem);
- if (!Entry) {
- dbg.Verbose(1, "gdcmHeader::GetHeaderEntryByNumber",
- "failed to Locate gdcmHeaderEntry");
- return (NULL);
- }
- return Entry->GetVoidArea();
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Loads (from disk) the element content
- * when a string is not suitable
- */
-void * gdcmHeader::LoadEntryVoidArea(guint16 Group, guint16 Elem) {
- gdcmHeaderEntry * Element= GetHeaderEntryByNumber(Group, Elem);
- if ( !Element )
- return NULL;
- size_t o =(size_t)Element->GetOffset();
- fseek(fp, o, SEEK_SET);
- int l=Element->GetLength();
- void * a = malloc(l);
- if(!a) {
- return NULL;
- }
-
- PubEntrySet.SetVoidAreaByNumber(a, Group, Elem);
- // TODO check the result
- size_t l2 = fread(a, 1, l ,fp);
- if(l != l2) {
- free(a);
- return NULL;
- }
- return a;
-}
-
-//-----------------------------------------------------------------------------
-// Private
-/**
- * \ingroup gdcmHeader
- * \brief Loads the element values of all the elements present in the
- * public tag based hash table.
- */
-void gdcmHeader::LoadHeaderEntries(void) {
- rewind(fp);
-
- // We don't use any longer the HashTable, since a lot a stuff is missing
- // when SeQuences were encountered
- //
- //TagHeaderEntryHT ht = PubHeaderEntrySet.GetTagHT();
- //for (TagHeaderEntryHT::iterator tag = ht.begin(); tag != ht.end(); ++tag) {
- // LoadElementValue(tag->second);
- //}
-
- for (ListTag::iterator i = GetPubListEntry().begin();
- i != GetPubListEntry().end();
- ++i){
- LoadHeaderEntry(*i);
- }
-
- rewind(fp);
-
- // Load 'non string' values
- std::string PhotometricInterpretation = GetPubEntryByNumber(0x0028,0x0004);
- if( PhotometricInterpretation == "PALETTE COLOR " ){
- LoadEntryVoidArea(0x0028,0x1200); // gray LUT
- LoadEntryVoidArea(0x0028,0x1201); // R LUT
- LoadEntryVoidArea(0x0028,0x1202); // G LUT
- LoadEntryVoidArea(0x0028,0x1203); // B LUT
-
- LoadEntryVoidArea(0x0028,0x1221); // Segmented Red Palette Color LUT Data
- LoadEntryVoidArea(0x0028,0x1222); // Segmented Green Palette Color LUT Data
- LoadEntryVoidArea(0x0028,0x1223); // Segmented Blue Palette Color LUT Data
- }
-
- // --------------------------------------------------------------
- // Special Patch to allow gdcm to read ACR-LibIDO formated images
- //
- // if recognition code tells us we deal with a LibIDO image
- // we switch lineNumber and columnNumber
- //
- std::string RecCode;
- RecCode = GetPubEntryByNumber(0x0008, 0x0010);
- if (RecCode == "ACRNEMA_LIBIDO_1.1" ||
- RecCode == "CANRME_AILIBOD1_1." ) {
- filetype = ACR_LIBIDO;
- std::string rows = GetPubEntryByNumber(0x0028, 0x0010);
- std::string columns = GetPubEntryByNumber(0x0028, 0x0011);
- SetPubEntryByNumber(columns, 0x0028, 0x0010);
- SetPubEntryByNumber(rows , 0x0028, 0x0011);
- }
- // ----------------- End of Special Patch ----------------
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Loads the element content if it's length is not bigger
- * than the value specified with
- * gdcmHeader::SetMaxSizeLoadElementValue()
- * @param ElVal string value of the Dicom Element
- */
-void gdcmHeader::LoadHeaderEntry(gdcmHeaderEntry * ElVal) {
- size_t item_read;
- guint16 group = ElVal->GetGroup();
- std::string vr= ElVal->GetVR();
- guint32 length = ElVal->GetLength();
- bool SkipLoad = false;
-
- fseek(fp, (long)ElVal->GetOffset(), SEEK_SET);
-
- // the test was commented out to 'go inside' the SeQuences
- // we don't any longer skip them !
-
- // if( vr == "SQ" )
- // SkipLoad = true;
-
- // A SeQuence "contains" a set of Elements.
- // (fffe e000) tells us an Element is beginning
- // (fffe e00d) tells us an Element just ended
- // (fffe e0dd) tells us the current SeQuence just ended
- if( group == 0xfffe )
- SkipLoad = true;
-
- if ( SkipLoad ) {
- ElVal->SetLength(0);
- ElVal->SetValue("gdcm::Skipped");
- return;
- }
-
- // When the length is zero things are easy:
- if ( length == 0 ) {
- ElVal->SetValue("");
- return;
- }
-
- // The elements whose length is bigger than the specified upper bound
- // are not loaded. Instead we leave a short notice of the offset of
- // the element content and it's length.
- if (length > MaxSizeLoadElementValue) {
- std::ostringstream s;
- s << "gdcm::NotLoaded.";
- s << " Address:" << (long)ElVal->GetOffset();
- s << " Length:" << ElVal->GetLength();
- s << " x(" << std::hex << ElVal->GetLength() << ")";
- ElVal->SetValue(s.str());
- return;
- }
-
- // When an integer is expected, read and convert the following two or
- // four bytes properly i.e. as an integer as opposed to a string.
-
- // Actually, elements with Value Multiplicity > 1
- // contain a set of integers (not a single one)
- // Any compacter code suggested (?)
- if ( IsHeaderEntryAnInteger(ElVal) ) {
- guint32 NewInt;
- std::ostringstream s;
- int nbInt;
- if (vr == "US" || vr == "SS") {
- nbInt = length / 2;
- NewInt = ReadInt16();
- s << NewInt;
- if (nbInt > 1) {
- for (int i=1; i < nbInt; i++) {
- s << '\\';
- NewInt = ReadInt16();
- s << NewInt;
- }
- }
-
- } else if (vr == "UL" || vr == "SL") {
- nbInt = length / 4;
- NewInt = ReadInt32();
- s << NewInt;
- if (nbInt > 1) {
- for (int i=1; i < nbInt; i++) {
- s << '\\';
- NewInt = ReadInt32();
- s << NewInt;
- }
- }
- }
-#ifdef GDCM_NO_ANSI_STRING_STREAM
- s << std::ends; // to avoid oddities on Solaris
-#endif //GDCM_NO_ANSI_STRING_STREAM
- ElVal->SetValue(s.str());
- return;
- }
-
- // We need an additional byte for storing \0 that is not on disk
- char* NewValue = (char*)malloc(length+1);
- if( !NewValue) {
- dbg.Verbose(1, "LoadElementValue: Failed to allocate NewValue");
- return;
- }
- NewValue[length]= 0;
-
- item_read = fread(NewValue, (size_t)length, (size_t)1, fp);
- if ( item_read != 1 ) {
- free(NewValue);
- dbg.Verbose(1, "gdcmHeader::LoadElementValue","unread element value");
- ElVal->SetValue("gdcm::UnRead");
- return;
- }
- ElVal->SetValue(NewValue);
- free(NewValue);
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Loads the element while preserving the current
- * underlying file position indicator as opposed to
- * to LoadElementValue that modifies it.
- * @param ElVal Element whose value shall be loaded.
- * @return
- */
-void gdcmHeader::LoadHeaderEntrySafe(gdcmHeaderEntry * ElVal) {
- long PositionOnEntry = ftell(fp);
- LoadHeaderEntry(ElVal);
- fseek(fp, PositionOnEntry, SEEK_SET);
-}