// DL Delimiters
//
+ // Other usefull abreviations :
+ //Radiographic view associated with Patient Position (0018,5100).
+ // Defined Terms:
+ //
+ // AP = Anterior/Posterior
+ // PA = Posterior/Anterior
+ // LL = Left Lateral
+ // RL = Right Lateral
+ // RLD = Right Lateral Decubitus
+ // LLD = Left Lateral Decubitus
+ // RLO = Right Lateral Oblique
+ // LLO = Left Lateral Oblique
+
//-----------------------------------------------------------------------------
// Refer to gdcmParser::CheckSwap()
const unsigned int gdcmParser::HEADER_LENGTH_TO_READ = 256;
* \ingroup gdcmParser
* \brief Determines if the Transfer Syntax was already encountered
* and if it corresponds to a ImplicitVRLittleEndian one.
- *
* @return True when ImplicitVRLittleEndian found. False in all other cases.
*/
bool gdcmParser::IsImplicitVRLittleEndianTransferSyntax(void) {
* \ingroup gdcmParser
* \brief Determines if the Transfer Syntax was already encountered
* and if it corresponds to a ExplicitVRLittleEndian one.
- *
* @return True when ExplicitVRLittleEndian found. False in all other cases.
*/
bool gdcmParser::IsExplicitVRLittleEndianTransferSyntax(void) {
* \ingroup gdcmParser
* \brief Determines if the Transfer Syntax was already encountered
* and if it corresponds to a DeflatedExplicitVRLittleEndian one.
- *
* @return True when DeflatedExplicitVRLittleEndian found. False in all other cases.
*/
bool gdcmParser::IsDeflatedExplicitVRLittleEndianTransferSyntax(void) {
* \ingroup gdcmParser
* \brief Determines if the Transfer Syntax was already encountered
* and if it corresponds to a Explicit VR Big Endian one.
- *
* @return True when big endian found. False in all other cases.
*/
bool gdcmParser::IsExplicitVRBigEndianTransferSyntax(void) {
* \ingroup gdcmParser
* \brief returns the File Type
* (ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown)
- * @return
+ * @return the FileType code
*/
FileType gdcmParser::GetFileType(void) {
return(filetype);
UpdateGroupLength(true,ACR);
*/
- WriteEntries(type, fp);
+ WriteEntries(fp,type);
return(true);
}
* @param Value passed as a std::string
* @param Group
* @param Elem
- * \return boolean
+ * \return false only if new element creation fails
*/
bool gdcmParser::ReplaceOrCreateByNumber(std::string Value,
guint16 Group,
* \brief Modifies the value of a given Header Entry (Dicom Element)
* if it exists; Creates it with the given value if it doesn't
* @param Value passed as a char*
- * @param Group
- * @param Elem
+ * @param Group group of the Entry
+ * @param Elem element of the Entry
* \return boolean
*
*/
* \ingroup gdcmParser
* \brief Set a new value if the invoked element exists
* Seems to be useless !!!
- * @param Value
- * @param Group
- * @param Elem
+ * @param Value new element value
+ * @param Group group of the Entry
+ * @param Elem element of the Entry
* \return boolean
*/
bool gdcmParser::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem )
//-----------------------------------------------------------------------------
// Protected
+
/**
* \ingroup gdcmParser
* \brief Checks if a given Dicom Element exists
- * \ within the H table
+ * within the H table
* @param group Group number of the searched Dicom Element
* @param element Element number of the searched Dicom Element
* @return number of occurences
if ( ! tagHT.count(key))
return false;
int l = content.length();
- if(l%2) // Odd length are padded with a space (020H).
+ if(l%2) // Non even length are padded with a space (020H).
{
l++;
content = content + '\0';
* through it's (group, element) and modifies it's length with
* the given value.
* \warning Use with extreme caution.
- * @param length new length to substitute with
- * @param group group of the entry to modify
- * @param element element of the Entry to modify
+ * @param l new length to substitute with
+ * @param group group of the Entry to modify
+ * @param element element of the Entry to modify
* @return 1 on success, 0 otherwise.
*/
-
-bool gdcmParser::SetEntryLengthByNumber(guint32 length,
+bool gdcmParser::SetEntryLengthByNumber(guint32 l,
guint16 group,
guint16 element)
{
TagKey key = gdcmDictEntry::TranslateToKey(group, element);
if ( ! tagHT.count(key))
return false;
- if (length%2) length++; // length must be even
- ( ((tagHT.equal_range(key)).first)->second )->SetLength(length);
+ if (l%2) l++; // length must be even
+ ( ((tagHT.equal_range(key)).first)->second )->SetLength(l);
return true ;
}
/**
* \ingroup gdcmParser
* \brief Gets (from Header) the offset of a 'non string' element value
- * \ (LoadElementValues has already be executed)
- * @param Group
- * @param Elem
+ * (LoadElementValues has already be executed)
+ * @param Group group of the Entry
+ * @param Elem element of the Entry
* @return File Offset of the Element Value
*/
size_t gdcmParser::GetEntryOffsetByNumber(guint16 Group, guint16 Elem)
/**
* \ingroup gdcmParser
* \brief Gets (from Header) a 'non string' element value
- * \ (LoadElementValues has already be executed)
- * @param Group
- * @param Elem
+ * (LoadElementValues has already be executed)
+ * @param Group group of the Entry
+ * @param Elem element of the Entry
* @return Pointer to the 'non string' area
*/
void * gdcmParser::GetEntryVoidAreaByNumber(guint16 Group, guint16 Elem)
* \ingroup gdcmParser
* \brief Loads (from disk) the element content
* when a string is not suitable
- * @param Group
- * @param Elem
+ * @param Group group of the Entry
+ * @param Elem element of the Entry
*/
void *gdcmParser::LoadEntryVoidArea(guint16 Group, guint16 Elem)
{
/**
* \ingroup gdcmParser
- * \brief Update the entries with the shadow dictionary. Only odd entries are
- * analized
+ * \brief Update the entries with the shadow dictionary.
+ * Only non even entries are analyzed
*/
void gdcmParser::UpdateShaEntries(void) {
gdcmDictEntry *entry;
/**
* \ingroup gdcmParser
* \brief retrieves a Dicom Element (the first one) using (group, element)
- * \ warning (group, element) IS NOT an identifier inside the Dicom Header
+ * \warning (group, element) IS NOT an identifier inside the Dicom Header
* if you think it's NOT UNIQUE, check the count number
* and use iterators to retrieve ALL the Dicoms Elements within
* a given couple (group, element)
/**
* \ingroup gdcmParser
* \brief writes on disc according to the requested format
- * \ (ACR-NEMA, ExplicitVR, ImplicitVR) the image
- * \ warning does NOT add the missing elements in the header :
- * \ it's up to the user doing it !
- * \ (function CheckHeaderCoherence to be written)
- * \ warning DON'T try, right now, to write a DICOM image
- * \ from an ACR Header (meta elements will be missing!)
+ * (ACR-NEMA, ExplicitVR, ImplicitVR) the image
+ * \warning does NOT add the missing elements in the header :
+ * it's up to the user doing it !
+ * (function CheckHeaderCoherence to be written)
+ * \warning DON'T try, right now, to write a DICOM image
+ * from an ACR Header (meta elements will be missing!)
* @param type type of the File to be written
* (ACR-NEMA, ExplicitVR, ImplicitVR)
* @param _fp already open file pointer
*/
-void gdcmParser::WriteEntries(FileType type, FILE * _fp)
+void gdcmParser::WriteEntries(FILE *_fp,FileType type)
{
guint16 gr, el;
guint32 lgr;
+ std::string value;
const char * val;
std::string vr;
guint32 val_uint32;
// TODO : find a trick (in STL?) to do it, at low cost !
void *ptr;
-
+
// TODO (?) tester les echecs en ecriture (apres chaque fwrite)
int compte =0;
tag2 != listEntries.end();
++tag2)
{
- gr = (*tag2)->GetGroup();
- el = (*tag2)->GetElement();
- lgr = (*tag2)->GetReadLength();
- val = (*tag2)->GetValue().c_str();
- vr = (*tag2)->GetVR();
+ // === Deal with the length
+ // --------------------
+ if(((*tag2)->GetLength())%2==1)
+ {
+ (*tag2)->SetValue((*tag2)->GetValue()+"\0");
+ (*tag2)->SetLength((*tag2)->GetLength()+1);
+ }
+
+ gr = (*tag2)->GetGroup();
+ el = (*tag2)->GetElement();
+ lgr = (*tag2)->GetReadLength();
+ val = (*tag2)->GetValue().c_str();
+ vr = (*tag2)->GetVR();
voidArea = (*tag2)->GetVoidArea();
if ( type == ACR )
fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp); //group
fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp); //element
- // === Deal with the length
- // --------------------
-
// if ( (type == ExplicitVR) && (gr <= 0x0002) ) // ?!? < 2
if ( (type == ExplicitVR) || (type == DICOMDIR) )
{
// EXPLICIT VR
guint16 z=0, shortLgr;
- if (vr == "Unknown") { // Unknown was 'written'
+ if (vr == "unkn")
+ { // Unknown was 'written'
shortLgr=lgr;
fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,_fp);
fwrite ( &z, (size_t)2 ,(size_t)1 ,_fp);
- } else {
- if (gr != 0xfffe) { // NO value for 'delimiters'
- if (vr == "Unknown") // Unknown was 'written'
- fwrite(&z,(size_t)2 ,(size_t)1 ,_fp);
- else
- fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,_fp);
+ }
+ else
+ {
+ if (gr != 0xfffe)
+ { // NO value for 'delimiters'
+ if (vr == "unkn") // Unknown was 'written'
+ fwrite(&z,(size_t)2 ,(size_t)1 ,_fp);
+ else
+ fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,_fp);
}
-
- if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") || gr == 0xfffe) // JPR
+
+ if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") || gr == 0xfffe)
{
if (gr != 0xfffe)
- fwrite ( &z, (size_t)2 ,(size_t)1 ,_fp);
- fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);
+ fwrite ( &z, (size_t)2 ,(size_t)1 ,_fp);
+ fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);
}
else
{
shortLgr=lgr;
fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,_fp);
}
- }
+ }
}
else // IMPLICIT VR
{
if (vr == "SQ") continue; // no "value" to write for the SEQuences
if (gr == 0xfffe)continue;
- if (voidArea != NULL) { // there is a 'non string' LUT, overlay, etc
+ if (voidArea != NULL)
+ { // there is a 'non string' LUT, overlay, etc
fwrite ( voidArea,(size_t)lgr ,(size_t)1 ,_fp); // Elem value
- continue;
+ continue;
}
if (vr == "US" || vr == "SS")
if ((gr == GrPixel) && (el == NumPixel) ) {
compte++;
- if (compte == countGrPixel) // we passed *all* the GrPixel,NumPixel
+ if (compte == countGrPixel) // we passed *all* the GrPixel,NumPixel
break;
}
fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); // Elem value
* \brief add a new Dicom Element pointer to
* the H Table and to the chained List
* \warning push_bash in listEntries ONLY during ParseHeader
- * \TODO something to allow further Elements addition,
- * \ when position to be taken care of
+ * \todo something to allow further Elements addition,
+ * (at their right place in the chained list)
+ * when position to be taken care of
* @param newHeaderEntry
*/
void gdcmParser::AddHeaderEntry(gdcmHeaderEntry *newHeaderEntry) {
* \ingroup gdcmParser
* \brief
* @param Entry Header Entry whose length of the value shall be loaded.
-
* @return
*/
void gdcmParser::FindHeaderEntryLength (gdcmHeaderEntry *Entry) {
guint16 length16;
if( (element == NumPixel) && (group == GrPixel) )
{
- dbg.SetDebug(-1);
+ dbg.SetDebug(GDCM_DEBUG);
dbg.Verbose(2, "gdcmParser::FindLength: ",
"we reached (GrPixel,NumPixel)");
}
return;
char VR[3];
- int lgrLue;
long PositionOnEntry = ftell(fp);
// Warning: we believe this is explicit VR (Value Representation) because
// is in explicit VR and try to fix things if it happens not to be
// the case.
- lgrLue=fread (&VR, (size_t)2,(size_t)1, fp);
+ int lgrLue=fread (&VR, (size_t)2,(size_t)1, fp); // lgrLue not used
VR[2]=0;
if(!CheckHeaderEntryVR(Entry,VR))
{
* \brief Check the correspondance between the VR of the header entry
* and the taken VR. If they are different, the header entry is
* updated with the new VR.
- * @param Entry
- * @param VR
+ * @param Entry Header Entry to check
+ * @param vr Dicom Value Representation
* @return false if the VR is incorrect of if the VR isn't referenced
* otherwise, it returns true
*/
sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n",
Entry->GetGroup(),Entry->GetElement());
dbg.Verbose(1, "gdcmParser::FindVR: ",msg);
-
+ if (Entry->GetGroup()%2 && Entry->GetElement() == 0x0000) { // Group length is UL !
+ gdcmDictEntry* NewEntry = NewVirtualDictEntry(
+ Entry->GetGroup(),Entry->GetElement(),
+ "UL","FIXME","Group Length");
+ Entry->SetDictEntry(NewEntry);
+ }
return(false);
}
if ( Entry->IsVRUnknown() )
{
// When not a dictionary entry, we can safely overwrite the VR.
- Entry->SetVR(vr);
+ if (Entry->GetElement() == 0x0000) { // Group length is UL !
+ Entry->SetVR("UL");
+ } else {
+ Entry->SetVR(vr);
+ }
}
else if ( Entry->GetVR() != vr )
{
s << NewInt32;
}
}
-
#ifdef GDCM_NO_ANSI_STRING_STREAM
s << std::ends; // to avoid oddities on Solaris
#endif //GDCM_NO_ANSI_STRING_STREAM
guint16 el =Entry->GetElement();
if (FoundLength%2) {
- std::cout << "Warning : Tag with uneven length " << FoundLength
- << "in x(" << std::hex << gr << "," << el <<")" << std::endl;
+ std::ostringstream s;
+ s << "Warning : Tag with uneven length " << FoundLength
+ << " in x(" << std::hex << gr << "," << el <<")" << std::dec;
+ dbg.Verbose(0,s.str().c_str());
}
// Sorry for the patch!
/**
* \ingroup gdcmParser
* \brief
- *
+ * \warning NOT end user intended method !
* @return
*/
guint32 gdcmParser::FindHeaderEntryLengthOB(void) {
/**
* \ingroup gdcmParser
* \brief Reads a supposed to be 16 Bits integer
- * \ (swaps it depending on processor endianity)
- *
+ * (swaps it depending on processor endianity)
* @return read value
*/
guint16 gdcmParser::ReadInt16(void) {
/**
* \ingroup gdcmParser
* \brief Reads a supposed to be 32 Bits integer
- * \ (swaps it depending on processor endianity)
- *
+ * (swaps it depending on processor endianity)
* @return read value
*/
guint32 gdcmParser::ReadInt32(void) {
/**
* \ingroup gdcmParser
* \brief
- *
+ * \warning NOT end user intended method !
* @return
*/
void gdcmParser::SkipBytes(guint32 NBytes) {
/**
* \ingroup gdcmParser
- * \brief
+ * \brief during parsing, Header Elements too long are not loaded in memory
* @param NewSize
*/
void gdcmParser::SetMaxSizeLoadEntry(long NewSize)
/**
* \ingroup gdcmParser
- * \brief
- * \warning TODO : not yet usable
+ * \brief Header Elements too long will not be printed
+ * \warning
+ * \todo : not yet usable
* (see MAX_SIZE_PRINT_ELEMENT_VALUE
* in gdcmHeaderEntry gdcmLoadEntry)
*
gdcmHeaderEntry *gdcmParser::ReadNextHeaderEntry(void) {
guint16 g,n;
gdcmHeaderEntry *NewEntry;
-
g = ReadInt16();
n = ReadInt16();
{
gdcmDictEntry *NewTag = GetDictEntryByName(Name);
if (!NewTag)
- NewTag = NewVirtualDictEntry(0xffff, 0xffff, "LO", "Unknown", Name);
+ NewTag = NewVirtualDictEntry(0xffff, 0xffff, "LO", "unkn", Name);
gdcmHeaderEntry* NewEntry = new gdcmHeaderEntry(NewTag);
if (!NewEntry)
* \ingroup gdcmParser
* \brief Request a new virtual dict entry to the dict set
* @param group group of the underlying DictEntry
- * @param elem element of the underlying DictEntry
+ * @param element element of the underlying DictEntry
* @param vr VR of the underlying DictEntry
* @param fourth owner group
* @param name english name