1 /*=========================================================================
4 Module: $RCSfile: gdcmDocEntrySet.cxx,v $
6 Date: $Date: 2005/01/26 11:42:02 $
7 Version: $Revision: 1.49 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
18 #include "gdcmDocEntrySet.h"
20 #include "gdcmDebug.h"
21 #include "gdcmCommon.h"
22 #include "gdcmDictSet.h"
23 #include "gdcmGlobal.h"
24 #include "gdcmDocEntry.h"
25 #include "gdcmSeqEntry.h"
26 #include "gdcmValEntry.h"
27 #include "gdcmBinEntry.h"
32 //-----------------------------------------------------------------------------
35 * \brief Get the "std::string representable" value of the Dicom entry
36 * @param group Group number of the searched tag.
37 * @param elem Element number of the searched tag.
38 * @return Corresponding element value when it exists,
39 * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
41 std::string DocEntrySet::GetEntryValue(uint16_t group, uint16_t elem)
43 ContentEntry *entry = dynamic_cast<ContentEntry *>(GetDocEntry(group,elem));
45 return entry->GetValue();
50 * \brief Gets (from Header) a 'non string' element value
51 * @param group group number of the Entry
52 * @param elem element number of the Entry
53 * @return Pointer to the 'non string' area
55 void *DocEntrySet::GetEntryBinArea(uint16_t group, uint16_t elem)
57 BinEntry *entry = GetBinEntry(group,elem);
59 return entry->GetBinArea();
64 * \brief Searches within Header Entries (Dicom Elements) parsed with
65 * the public and private dictionaries
66 * for the value length of a given tag..
67 * @param group Group number of the searched tag.
68 * @param elem Element number of the searched tag.
69 * @return Corresponding element length; -2 if not found
71 int DocEntrySet::GetEntryLength(uint16_t group, uint16_t elem)
73 DocEntry *entry = GetDocEntry(group,elem);
75 return entry->GetLength();
80 * \brief Searches within Header Entries (Dicom Elements) parsed with
81 * the public [and private dictionaries]
82 * for the element value representation of a given tag..
83 * Obtaining the VR (Value Representation) might be needed by caller
84 * to convert the string typed content to caller's native type
85 * (think of C++ vs Python). The VR is actually of a higher level
86 * of semantics than just the native C++ type.
87 * @param group Group number of the searched tag.
88 * @param elem Element number of the searched tag.
89 * @return Corresponding element value representation when it exists,
90 * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
92 std::string DocEntrySet::GetEntryVR(uint16_t group, uint16_t elem)
94 DocEntry *entry = GetDocEntry(group,elem);
96 return entry->GetVR();
101 * \brief Same as \ref Document::GetDocEntry except it only
102 * returns a result when the corresponding entry is of type
104 * @param group Group number of the searched Dicom Element
105 * @param elem Element number of the searched Dicom Element
106 * @return When present, the corresponding ValEntry.
108 ValEntry *DocEntrySet::GetValEntry(uint16_t group, uint16_t elem)
110 DocEntry *currentEntry = GetDocEntry(group, elem);
114 return dynamic_cast<ValEntry*>(currentEntry);
118 * \brief Same as \ref Document::GetDocEntry except it only
119 * returns a result when the corresponding entry is of type
121 * @param group Group number of the searched Dicom Element
122 * @param elem Element number of the searched Dicom Element
123 * @return When present, the corresponding BinEntry.
125 BinEntry *DocEntrySet::GetBinEntry(uint16_t group, uint16_t elem)
127 DocEntry *currentEntry = GetDocEntry(group, elem);
130 gdcmVerboseMacro( "No corresponding BinEntry " << std::hex << group <<
135 return dynamic_cast<BinEntry*>(currentEntry);
139 * \brief Same as \ref Document::GetDocEntry except it only
140 * returns a result when the corresponding entry is of type
142 * @param group Group number of the searched Dicom Element
143 * @param elem Element number of the searched Dicom Element
144 * @return When present, the corresponding SeqEntry.
146 SeqEntry *DocEntrySet::GetSeqEntry(uint16_t group, uint16_t elem)
148 DocEntry *currentEntry = GetDocEntry(group, elem);
151 gdcmVerboseMacro( "No corresponding SeqEntry " << std::hex << group <<
156 return dynamic_cast<SeqEntry*>(currentEntry);
160 * \brief Accesses an existing DocEntry (i.e. a Dicom Element)
161 * through it's (group, element) and modifies it's content with
163 * @param content new value (string) to substitute with
164 * @param group group number of the Dicom Element to modify
165 * @param elem element number of the Dicom Element to modify
167 bool DocEntrySet::SetValEntry(std::string const& content,
168 uint16_t group, uint16_t elem)
170 ValEntry *entry = GetValEntry(group, elem);
173 gdcmVerboseMacro( "No corresponding ValEntry " << std::hex << group <<
174 "," << elem << " element (try promotion first).");
177 return SetValEntry(content,entry);
181 * \brief Accesses an existing DocEntry (i.e. a Dicom Element)
182 * through it's (group, element) and modifies it's content with
184 * @param content new value (void* -> uint8_t*) to substitute with
185 * @param lgth new value length
186 * @param group group number of the Dicom Element to modify
187 * @param elem element number of the Dicom Element to modify
189 bool DocEntrySet::SetBinEntry(uint8_t *content, int lgth,
190 uint16_t group, uint16_t elem)
192 BinEntry *entry = GetBinEntry(group, elem);
195 gdcmVerboseMacro( "No corresponding ValEntry " << std::hex << group <<
196 "," << elem << " element (try promotion first).");
200 return SetBinEntry(content,lgth,entry);
204 * \brief Accesses an existing DocEntry (i.e. a Dicom Element)
205 * and modifies it's content with the given value.
206 * @param content new value (string) to substitute with
207 * @param entry Entry to be modified
209 bool DocEntrySet::SetValEntry(std::string const &content, ValEntry *entry)
213 entry->SetValue(content);
220 * \brief Accesses an existing BinEntry (i.e. a Dicom Element)
221 * and modifies it's content with the given value.
222 * @param content new value (void* -> uint8_t*) to substitute with
223 * @param entry Entry to be modified
224 * @param lgth new value length
226 bool DocEntrySet::SetBinEntry(uint8_t *content, int lgth, BinEntry *entry)
230 entry->SetBinArea(content);
231 entry->SetLength(lgth);
232 entry->SetValue(GDCM_BINLOADED);
239 * \brief Modifies the value of a given Doc Entry (Dicom Element)
240 * when it exists. Create it with the given value when unexistant.
241 * @param value (string) Value to be set
242 * @param group Group number of the Entry
243 * @param elem Element number of the Entry
244 * @param vr V(alue) R(epresentation) of the Entry -if private Entry-
245 * \return pointer to the modified/created Header Entry (NULL when creation
248 ValEntry *DocEntrySet::InsertValEntry(std::string const &value,
249 uint16_t group, uint16_t elem,
252 ValEntry *valEntry = 0;
253 DocEntry *currentEntry = GetDocEntry( group, elem);
257 valEntry = dynamic_cast<ValEntry *>(currentEntry);
261 if( valEntry->GetVR()!=vr )
264 // if currentEntry doesn't correspond to the requested valEntry
267 if( !RemoveEntry(currentEntry) )
269 gdcmVerboseMacro( "Removal of previous DocEntry failed.");
276 // Create a new valEntry if necessary
279 valEntry = NewValEntry(group, elem, vr);
281 if ( !AddEntry(valEntry) )
283 gdcmVerboseMacro("AddEntry failed although this is a creation.");
290 // Set the binEntry value
291 SetValEntry(value, valEntry); // The std::string value
296 * \brief Modifies the value of a given Header Entry (Dicom Element)
297 * when it exists. Create it with the given value when unexistant.
298 * A copy of the binArea is made to be kept in the Document.
299 * @param binArea (binary) value to be set
300 * @param group Group number of the Entry
301 * @param elem Element number of the Entry
302 * @param vr V(alue) R(epresentation) of the Entry -if private Entry-
303 * \return pointer to the modified/created Header Entry (NULL when creation
306 BinEntry *DocEntrySet::InsertBinEntry(uint8_t *binArea,int lgth,
307 uint16_t group, uint16_t elem,
310 BinEntry *binEntry = 0;
311 DocEntry *currentEntry = GetDocEntry( group, elem);
313 // Verify the currentEntry
316 binEntry = dynamic_cast<BinEntry *>(currentEntry);
320 if( binEntry->GetVR()!=vr )
323 // if currentEntry doesn't correspond to the requested valEntry
326 if( !RemoveEntry(currentEntry) )
328 gdcmVerboseMacro( "Removal of previous DocEntry failed.");
335 // Create a new binEntry if necessary
338 binEntry = NewBinEntry(group, elem, vr);
340 if ( !AddEntry(binEntry) )
342 gdcmVerboseMacro( "AddEntry failed allthough this is a creation.");
349 // Set the binEntry value
351 if( lgth>0 && binArea )
353 tmpArea = new uint8_t[lgth];
354 memcpy(tmpArea,binArea,lgth);
360 if( !SetBinEntry(tmpArea,lgth,binEntry) )
372 * \brief Modifies the value of a given Header Entry (Dicom Element)
373 * when it exists. Creates it when unexistant.
374 * @param group Group number of the Entry
375 * @param elem Element number of the Entry
376 * \return pointer to the modified/created SeqEntry (NULL when creation
379 SeqEntry *DocEntrySet::InsertSeqEntry(uint16_t group, uint16_t elem)
381 SeqEntry *seqEntry = 0;
382 DocEntry *currentEntry = GetDocEntry( group, elem);
384 // Verify the currentEntry
387 seqEntry = dynamic_cast<SeqEntry *>(currentEntry);
391 if( seqEntry->GetVR()!="SQ" )
394 // if currentEntry doesn't correspond to the requested valEntry
397 if (!RemoveEntry(currentEntry))
399 gdcmVerboseMacro( "Removal of previous DocEntry failed.");
405 // Create a new seqEntry if necessary
408 seqEntry = NewSeqEntry(group, elem);
410 if( !AddEntry(seqEntry) )
412 gdcmVerboseMacro( "AddEntry failed allthough this is a creation.");
422 * \brief Checks if a given Dicom Element exists within the H table
423 * @param group Group number of the searched Dicom Element
424 * @param elem Element number of the searched Dicom Element
425 * @return true is found
427 bool DocEntrySet::CheckIfEntryExist(uint16_t group, uint16_t elem )
429 return GetDocEntry(group,elem)!=NULL;
433 * \brief Request a new virtual dict entry to the dict set
434 * @param group group number of the underlying DictEntry
435 * @param elem element number of the underlying DictEntry
436 * @param vr VR (Value Representation) of the underlying DictEntry
437 * @param vm VM (Value Multiplicity) of the underlying DictEntry
438 * @param name english name
440 DictEntry* DocEntrySet::NewVirtualDictEntry( uint16_t group,uint16_t elem,
443 TagName const & name )
445 return Global::GetDicts()->NewVirtualDictEntry(group,elem,vr,vm,name);
449 * \brief Build a new Val Entry from all the low level arguments.
450 * Check for existence of dictionary entry, and build
451 * a default one when absent.
452 * @param group group number of the new Entry
453 * @param elem element number of the new Entry
454 * @param vr VR of the new Entry
456 ValEntry *DocEntrySet::NewValEntry(uint16_t group,uint16_t elem,
459 DictEntry *dictEntry = GetDictEntry(group, elem, vr);
460 gdcmAssertMacro(dictEntry);
462 ValEntry *newEntry = new ValEntry(dictEntry);
465 gdcmVerboseMacro( "Failed to allocate ValEntry");
473 * \brief Build a new Bin Entry from all the low level arguments.
474 * Check for existence of dictionary entry, and build
475 * a default one when absent.
476 * @param group group number of the new Entry
477 * @param elem element number of the new Entry
478 * @param vr VR of the new Entry
480 BinEntry *DocEntrySet::NewBinEntry(uint16_t group,uint16_t elem,
483 DictEntry *dictEntry = GetDictEntry(group, elem, vr);
484 gdcmAssertMacro(dictEntry);
486 BinEntry *newEntry = new BinEntry(dictEntry);
489 gdcmVerboseMacro( "Failed to allocate BinEntry");
496 * \brief Build a new Seq Entry from all the low level arguments.
497 * Check for existence of dictionary entry, and build
498 * a default one when absent.
499 * @param group group number of the new Entry
500 * @param elem element number of the new Entry
502 SeqEntry* DocEntrySet::NewSeqEntry(uint16_t group,uint16_t elem)
504 DictEntry *dictEntry = GetDictEntry(group, elem, "SQ");
505 gdcmAssertMacro(dictEntry);
507 SeqEntry *newEntry = new SeqEntry( dictEntry );
510 gdcmVerboseMacro( "Failed to allocate SeqEntry");
516 //-----------------------------------------------------------------------------
519 * \brief Searches [both] the public [and the shadow dictionary (when they
520 * exist)] for the presence of the DictEntry with given
521 * group and element. The public dictionary has precedence on the
523 * @param group group number of the searched DictEntry
524 * @param elem element number of the searched DictEntry
525 * @return Corresponding DictEntry when it exists, NULL otherwise.
527 DictEntry *DocEntrySet::GetDictEntry(uint16_t group,uint16_t elem)
529 DictEntry *found = 0;
530 Dict *pubDict = Global::GetDicts()->GetDefaultPubDict();
533 gdcmVerboseMacro( "We SHOULD have a default dictionary");
537 found = pubDict->GetEntry(group, elem);
543 * \brief Searches [both] the public [and the shadow dictionary (when they
544 * exist)] for the presence of the DictEntry with given
545 * group and element, and create a new virtual DictEntry if necessary
546 * @param group group number of the searched DictEntry
547 * @param elem element number of the searched DictEntry
548 * @param vr Value Representation to use, if necessary
549 * @return Corresponding DictEntry when it exists, NULL otherwise.
551 DictEntry *DocEntrySet::GetDictEntry(uint16_t group, uint16_t elem,
554 DictEntry *dictEntry = GetDictEntry(group,elem);
555 DictEntry *goodEntry = dictEntry;
556 std::string goodVR = vr;
558 if (elem == 0x0000) goodVR="UL";
562 if ( goodVR != goodEntry->GetVR()
563 && goodVR != GDCM_UNKNOWN )
569 // Create a new virtual DictEntry if necessary
574 goodEntry = NewVirtualDictEntry(group, elem, goodVR, "FIXME",
575 dictEntry->GetName() );
579 goodEntry = NewVirtualDictEntry(group, elem, goodVR);
585 //-----------------------------------------------------------------------------
588 //-----------------------------------------------------------------------------
589 } // end namespace gdcm