-/**
- * \ingroup gdcmHeader
- * \brief
- *
- * @return
- */
-gdcmElValue* gdcmHeader::GetElValueByNumber(guint16 Group, guint16 Elem) {
-
- gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
- if (!elValue) {
- dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
- "failed to Locate gdcmElValue");
- return (gdcmElValue*)0;
- }
- return elValue;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Checks if a given ElValue (group,number)
- * \ exists in the Public ElValSet
- * @param Group
- * @param Elem
- * @return integer acts as a boolean
- */
-bool gdcmHeader::CheckIfExistByNumber(guint16 Group, guint16 Elem ) {
- return (PubElValSet.CheckIfExistByNumber(Group, Elem));
-}
-
-/**
- * \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::GetPubElValOffsetByNumber(guint16 Group, guint16 Elem) {
- gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
- if (!elValue) {
- dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
- "failed to Locate gdcmElValue");
- return (size_t)0;
- }
- return elValue->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::GetPubElValVoidAreaByNumber(guint16 Group, guint16 Elem) {
- gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
- if (!elValue) {
- dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
- "failed to Locate gdcmElValue");
- return (NULL);
- }
- return elValue->GetVoidArea();
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Loads (from disk) the element content
- * when a string is not suitable
- */
-void * gdcmHeader::LoadElementVoidArea(guint16 Group, guint16 Elem) {
- gdcmElValue * Element= PubElValSet.GetElementByNumber(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;
- }
- /* int res = */ PubElValSet.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;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief TODO
- * @param Value
- * @param Group
- * @param Elem
- * \return integer acts as a boolean
- */
-bool gdcmHeader::ReplaceOrCreateByNumber(std::string Value,
- guint16 Group, guint16 Elem ) {
- // TODO : FIXME JPRx
- // curieux, non ?
- // on (je) cree une Elvalue ne contenant pas de valeur
- // on l'ajoute au ElValSet
- // on affecte une valeur a cette ElValue a l'interieur du ElValSet
- // --> devrait pouvoir etre fait + simplement ???
- if (CheckIfExistByNumber(Group, Elem) == 0) {
- gdcmElValue* a =NewElValueByNumber(Group, Elem);
- if (a == NULL)
- return false;
- PubElValSet.Add(a);
- }
- PubElValSet.SetElValueByNumber(Value, Group, Elem);
- return(true);
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Modify (or Creates if not found) an element
- * @param Value new value
- * @param Group
- * @param Elem
- * \return integer acts as a boolean
- *
- */
-bool gdcmHeader::ReplaceOrCreateByNumber(char* Value, guint16 Group, guint16 Elem ) {
-
- gdcmElValue* nvElValue=NewElValueByNumber(Group, Elem);
- // TODO : check if fails
- PubElValSet.Add(nvElValue);
- std::string v = Value;
- PubElValSet.SetElValueByNumber(v, Group, Elem);
- return(true);
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Set a new value if the invoked element exists
- * Seems to be useless !!!
- * @param Value
- * @param Group
- * @param Elem
- * \return integer acts as a boolean
- */
-bool gdcmHeader::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem ) {
-
- //gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
- std::string v = Value;
- PubElValSet.SetElValueByNumber(v, Group, Elem);
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Private
-/**
- * \ingroup gdcmHeader
- * \brief Loads the element values of all the elements present in the
- * public tag based hash table.
- */
-void gdcmHeader::LoadElements(void) {
- rewind(fp);
-
- // We don't use any longer the HashTable, since a lot a stuff is missing
- // when SeQuences were encountered
- //
- //TagElValueHT ht = PubElValSet.GetTagHt();
- //for (TagElValueHT::iterator tag = ht.begin(); tag != ht.end(); ++tag) {
- // LoadElementValue(tag->second);
- //}
-
- for (ListTag::iterator i = GetPubListElem().begin();
- i != GetPubListElem().end();
- ++i){
- LoadElementValue(*i);
- }
-
- rewind(fp);
-
- // Load 'non string' values
- std::string PhotometricInterpretation = GetPubElValByNumber(0x0028,0x0004);
- if( PhotometricInterpretation == "PALETTE COLOR " ){
- LoadElementVoidArea(0x0028,0x1200); // gray LUT
- LoadElementVoidArea(0x0028,0x1201); // R LUT
- LoadElementVoidArea(0x0028,0x1202); // G LUT
- LoadElementVoidArea(0x0028,0x1203); // B LUT
-
- LoadElementVoidArea(0x0028,0x1221); // Segmented Red Palette Color LUT Data
- LoadElementVoidArea(0x0028,0x1222); // Segmented Green Palette Color LUT Data
- LoadElementVoidArea(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 = GetPubElValByNumber(0x0008, 0x0010);
- if (RecCode == "ACRNEMA_LIBIDO_1.1" ||
- RecCode == "CANRME_AILIBOD1_1." ) {
- filetype = ACR_LIBIDO;
- std::string rows = GetPubElValByNumber(0x0028, 0x0010);
- std::string columns = GetPubElValByNumber(0x0028, 0x0011);
- SetPubElValByNumber(columns, 0x0028, 0x0010);
- SetPubElValByNumber(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::LoadElementValue(gdcmElValue * 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 ( IsAnInteger(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::LoadElementValueSafe(gdcmElValue * ElVal) {
- long PositionOnEntry = ftell(fp);
- LoadElementValue(ElVal);
- fseek(fp, PositionOnEntry, SEEK_SET);
-}