1 /*=========================================================================
4 Module: $RCSfile: gdcmDocEntrySet.cxx,v $
6 Date: $Date: 2005/01/25 15:44:23 $
7 Version: $Revision: 1.45 $
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 ValEntry *entry = GetValEntry(group,elem);
45 return entry->GetValue();
50 * \brief Gets (from Header) a 'non string' element value
51 * (LoadElementValues has already be executed)
52 * @param group group number of the Entry
53 * @param elem element number of the Entry
54 * @return Pointer to the 'non string' area
56 void *DocEntrySet::GetEntryBinArea(uint16_t group, uint16_t elem)
58 BinEntry *entry = GetBinEntry(group,elem);
60 return entry->GetBinArea();
65 * \brief Searches within Header Entries (Dicom Elements) parsed with
66 * the public and private dictionaries
67 * for the value length of a given tag..
68 * @param group Group number of the searched tag.
69 * @param elem Element number of the searched tag.
70 * @return Corresponding element length; -2 if not found
72 int DocEntrySet::GetEntryLength(uint16_t group, uint16_t elem)
74 DocEntry *entry = GetDocEntry(group,elem);
76 return entry->GetLength();
81 * \brief Searches within Header Entries (Dicom Elements) parsed with
82 * the public and private dictionaries
83 * for the element value representation of a given tag..
84 * Obtaining the VR (Value Representation) might be needed by caller
85 * to convert the string typed content to caller's native type
86 * (think of C++ vs Python). The VR is actually of a higher level
87 * of semantics than just the native C++ type.
88 * @param group Group number of the searched tag.
89 * @param elem Element number of the searched tag.
90 * @return Corresponding element value representation when it exists,
91 * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
93 std::string DocEntrySet::GetEntryVR(uint16_t group, uint16_t elem)
95 DocEntry *entry = GetDocEntry(group,elem);
97 return entry->GetVR();
102 * \brief Same as \ref Document::GetDocEntry except it only
103 * returns a result when the corresponding entry is of type
105 * @param group Group number of the searched Dicom Element
106 * @param elem Element number of the searched Dicom Element
107 * @return When present, the corresponding ValEntry.
109 ValEntry *DocEntrySet::GetValEntry(uint16_t group, uint16_t elem)
111 DocEntry *currentEntry = GetDocEntry(group, elem);
115 return dynamic_cast<ValEntry*>(currentEntry);
119 * \brief Same as \ref Document::GetDocEntry except it only
120 * returns a result when the corresponding entry is of type
122 * @param group Group number of the searched Dicom Element
123 * @param elem Element number of the searched Dicom Element
124 * @return When present, the corresponding BinEntry.
126 BinEntry *DocEntrySet::GetBinEntry(uint16_t group, uint16_t elem)
128 DocEntry *currentEntry = GetDocEntry(group, elem);
132 return dynamic_cast<BinEntry*>(currentEntry);
136 * \brief Same as \ref Document::GetDocEntry except it only
137 * returns a result when the corresponding entry is of type
139 * @param group Group number of the searched Dicom Element
140 * @param elem Element number of the searched Dicom Element
141 * @return When present, the corresponding SeqEntry.
143 SeqEntry *DocEntrySet::GetSeqEntry(uint16_t group, uint16_t elem)
145 DocEntry *currentEntry = GetDocEntry(group, elem);
149 return dynamic_cast<SeqEntry*>(currentEntry);
153 * \brief Accesses an existing DocEntry (i.e. a Dicom Element)
154 * through it's (group, element) and modifies it's content with
156 * @param content new value (string) to substitute with
157 * @param group group number of the Dicom Element to modify
158 * @param elem element number of the Dicom Element to modify
160 bool DocEntrySet::SetValEntry(std::string const& content,
161 uint16_t group, uint16_t elem)
163 ValEntry *entry = GetValEntry(group, elem);
166 gdcmVerboseMacro( "No corresponding ValEntry (try promotion first).");
169 return SetValEntry(content,entry);
173 * \brief Accesses an existing DocEntry (i.e. a Dicom Element)
174 * through it's (group, element) and modifies it's content with
176 * @param content new value (void* -> uint8_t*) to substitute with
177 * @param lgth new value length
178 * @param group group number of the Dicom Element to modify
179 * @param elem element number of the Dicom Element to modify
181 bool DocEntrySet::SetBinEntry(uint8_t*content, int lgth,
182 uint16_t group, uint16_t elem)
184 BinEntry *entry = GetBinEntry(group, elem);
187 gdcmVerboseMacro( "No corresponding ValEntry (try promotion first).");
191 return SetBinEntry(content,lgth,entry);
195 * \brief Accesses an existing DocEntry (i.e. a Dicom Element)
196 * and modifies it's content with the given value.
197 * @param content new value (string) to substitute with
198 * @param entry Entry to be modified
200 bool DocEntrySet::SetValEntry(std::string const &content, ValEntry *entry)
204 entry->SetValue(content);
211 * \brief Accesses an existing BinEntry (i.e. a Dicom Element)
212 * and modifies it's content with the given value.
213 * @param content new value (void* -> uint8_t*) to substitute with
214 * @param entry Entry to be modified
215 * @param lgth new value length
217 bool DocEntrySet::SetBinEntry(uint8_t *content, int lgth, BinEntry *entry)
221 entry->SetBinArea(content);
222 entry->SetLength(lgth);
223 entry->SetValue(GDCM_BINLOADED);
230 * \brief Modifies the value of a given Doc Entry (Dicom Element)
231 * when it exists. Create it with the given value when unexistant.
232 * @param value (string) Value to be set
233 * @param group Group number of the Entry
234 * @param elem Element number of the Entry
235 * @param vr V(alue) R(epresentation) of the Entry -if private Entry-
236 * \return pointer to the modified/created Header Entry (NULL when creation
239 ValEntry *DocEntrySet::InsertValEntry(std::string const &value,
240 uint16_t group, uint16_t elem,
243 ValEntry *valEntry = 0;
244 DocEntry *currentEntry = GetDocEntry( group, elem);
248 valEntry = dynamic_cast<ValEntry *>(currentEntry);
252 if( valEntry->GetVR()!=vr )
255 // if currentEntry doesn't correspond to the requested valEntry
258 if( !RemoveEntry(currentEntry) )
260 gdcmVerboseMacro( "Removal of previous DocEntry failed.");
267 // Create a new valEntry if necessary
270 valEntry = NewValEntry(group, elem, vr);
272 if ( !AddEntry(valEntry) )
274 gdcmVerboseMacro("AddEntry failed although this is a creation.");
281 // Set the binEntry value
282 SetValEntry(value, valEntry); // The std::string value
287 * \brief Modifies the value of a given Header Entry (Dicom Element)
288 * when it exists. Create it with the given value when unexistant.
289 * A copy of the binArea is made to be kept in the Document.
290 * @param binArea (binary) value to be set
291 * @param group Group number of the Entry
292 * @param elem Element number of the Entry
293 * @param vr V(alue) R(epresentation) of the Entry -if private Entry-
294 * \return pointer to the modified/created Header Entry (NULL when creation
297 BinEntry *DocEntrySet::InsertBinEntry(uint8_t *binArea,int lgth,
298 uint16_t group, uint16_t elem,
301 BinEntry *binEntry = 0;
302 DocEntry *currentEntry = GetDocEntry( group, elem);
304 // Verify the currentEntry
307 binEntry = dynamic_cast<BinEntry *>(currentEntry);
311 if( binEntry->GetVR()!=vr )
314 // if currentEntry doesn't correspond to the requested valEntry
317 if( !RemoveEntry(currentEntry) )
319 gdcmVerboseMacro( "Removal of previous DocEntry failed.");
326 // Create a new binEntry if necessary
329 binEntry = NewBinEntry(group, elem, vr);
331 if ( !AddEntry(binEntry) )
333 gdcmVerboseMacro( "AddEntry failed allthough this is a creation.");
340 // Set the binEntry value
342 if( lgth>0 && binArea )
344 tmpArea = new uint8_t[lgth];
345 memcpy(tmpArea,binArea,lgth);
351 if( !SetBinEntry(tmpArea,lgth,binEntry) )
363 * \brief Modifies the value of a given Header Entry (Dicom Element)
364 * when it exists. Creates it when unexistant.
365 * @param group Group number of the Entry
366 * @param elem Element number of the Entry
367 * \return pointer to the modified/created SeqEntry (NULL when creation
370 SeqEntry *DocEntrySet::InsertSeqEntry(uint16_t group, uint16_t elem)
372 SeqEntry *seqEntry = 0;
373 DocEntry *currentEntry = GetDocEntry( group, elem);
375 // Verify the currentEntry
378 seqEntry = dynamic_cast<SeqEntry *>(currentEntry);
382 if( seqEntry->GetVR()!="SQ" )
385 // if currentEntry doesn't correspond to the requested valEntry
388 if (!RemoveEntry(currentEntry))
390 gdcmVerboseMacro( "Removal of previous DocEntry failed.");
396 // Create a new seqEntry if necessary
399 seqEntry = NewSeqEntry(group, elem);
401 if( !AddEntry(seqEntry) )
403 gdcmVerboseMacro( "AddEntry failed allthough this is a creation.");
413 * \brief Checks if a given Dicom Element exists within the H table
414 * @param group Group number of the searched Dicom Element
415 * @param elem Element number of the searched Dicom Element
416 * @return true is found
418 bool DocEntrySet::CheckIfEntryExist(uint16_t group, uint16_t elem )
420 return GetDocEntry(group,elem)!=NULL;
424 * \brief Request a new virtual dict entry to the dict set
425 * @param group group number of the underlying DictEntry
426 * @param elem element number of the underlying DictEntry
427 * @param vr VR (Value Representation) of the underlying DictEntry
428 * @param vm VM (Value Multiplicity) of the underlying DictEntry
429 * @param name english name
431 DictEntry* DocEntrySet::NewVirtualDictEntry( uint16_t group,uint16_t elem,
434 TagName const & name )
436 return Global::GetDicts()->NewVirtualDictEntry(group,elem,vr,vm,name);
439 //-----------------------------------------------------------------------------
442 * \brief Build a new Val Entry from all the low level arguments.
443 * Check for existence of dictionary entry, and build
444 * a default one when absent.
445 * @param group group number of the new Entry
446 * @param elem element number of the new Entry
447 * @param vr VR of the new Entry
449 ValEntry *DocEntrySet::NewValEntry(uint16_t group,uint16_t elem,
452 DictEntry *dictEntry = GetDictEntry(group, elem, vr);
453 gdcmAssertMacro(dictEntry);
455 ValEntry *newEntry = new ValEntry(dictEntry);
458 gdcmVerboseMacro( "Failed to allocate ValEntry");
466 * \brief Build a new Bin Entry from all the low level arguments.
467 * Check for existence of dictionary entry, and build
468 * a default one when absent.
469 * @param group group number of the new Entry
470 * @param elem element number of the new Entry
471 * @param vr VR of the new Entry
473 BinEntry *DocEntrySet::NewBinEntry(uint16_t group,uint16_t elem,
476 DictEntry *dictEntry = GetDictEntry(group, elem, vr);
477 gdcmAssertMacro(dictEntry);
479 BinEntry *newEntry = new BinEntry(dictEntry);
482 gdcmVerboseMacro( "Failed to allocate BinEntry");
489 * \brief Build a new Seq Entry from all the low level arguments.
490 * Check for existence of dictionary entry, and build
491 * a default one when absent.
492 * @param group group number of the new Entry
493 * @param elem element number of the new Entry
495 SeqEntry* DocEntrySet::NewSeqEntry(uint16_t group,uint16_t elem)
497 DictEntry *dictEntry = GetDictEntry(group, elem, "SQ");
498 gdcmAssertMacro(dictEntry);
500 SeqEntry *newEntry = new SeqEntry( dictEntry );
503 gdcmVerboseMacro( "Failed to allocate SeqEntry");
510 * \brief Searches [both] the public [and the shadow dictionary (when they
511 * exist)] for the presence of the DictEntry with given
512 * group and element. The public dictionary has precedence on the
514 * @param group group number of the searched DictEntry
515 * @param elem element number of the searched DictEntry
516 * @return Corresponding DictEntry when it exists, NULL otherwise.
518 DictEntry *DocEntrySet::GetDictEntry(uint16_t group,uint16_t elem)
520 DictEntry *found = 0;
521 Dict *pubDict = Global::GetDicts()->GetDefaultPubDict();
524 gdcmVerboseMacro( "We SHOULD have a default dictionary");
528 found = pubDict->GetEntry(group, elem);
535 * \brief Searches both the public and the shadow dictionary (when they
536 * exist) for the presence of the DictEntry with given
537 * group and element, and create a new virtual DictEntry if necessary
538 * @param group group number of the searched DictEntry
539 * @param elem element number of the searched DictEntry
540 * @param vr Value Representation to use, if necessary
541 * @return Corresponding DictEntry when it exists, NULL otherwise.
543 DictEntry *DocEntrySet::GetDictEntry(uint16_t group, uint16_t elem,
546 DictEntry *dictEntry = GetDictEntry(group,elem);
547 DictEntry *goodEntry = dictEntry;
548 std::string goodVR = vr;
550 if (elem == 0x0000) goodVR="UL";
554 if ( goodVR != goodEntry->GetVR()
555 && goodVR != GDCM_UNKNOWN )
561 // Create a new virtual DictEntry if necessary
566 goodEntry = NewVirtualDictEntry(group, elem, goodVR, "FIXME",
567 dictEntry->GetName() );
571 goodEntry = NewVirtualDictEntry(group, elem, goodVR);
577 //-----------------------------------------------------------------------------
580 //-----------------------------------------------------------------------------
581 } // end namespace gdcm