- case 0x0007 :
- case 0x0008 :
- SwapCode = 1234;
- Filetype = ACR;
- return true;
- case 0x0100 :
- case 0x0200 :
- case 0x0300 :
- case 0x0400 :
- case 0x0500 :
- case 0x0600 :
- case 0x0700 :
- case 0x0800 :
- SwapCode = 4321;
- Filetype = ACR;
- return true;
- default :
- gdcmVerboseMacro( "ACR/NEMA unfound swap info (Really hopeless !)");
- Filetype = Unknown;
- return false;
- }
- }
-}
-
-
-
-/**
- * \brief Change the Byte Swap code.
- */
-void Document::SwitchByteSwapCode()
-{
- gdcmVerboseMacro( "Switching Byte Swap code.");
- if ( SwapCode == 1234 )
- {
- SwapCode = 4321;
- }
- else if ( SwapCode == 4321 )
- {
- SwapCode = 1234;
- }
- else if ( SwapCode == 3412 )
- {
- SwapCode = 2143;
- }
- else if ( SwapCode == 2143 )
- {
- SwapCode = 3412;
- }
-}
-
-/**
- * \brief during parsing, Header Elements too long are not loaded in memory
- * @param newSize
- */
-void Document::SetMaxSizeLoadEntry(long newSize)
-{
- if ( newSize < 0 )
- {
- return;
- }
- if ((uint32_t)newSize >= (uint32_t)0xffffffff )
- {
- MaxSizeLoadEntry = 0xffffffff;
- return;
- }
- MaxSizeLoadEntry = newSize;
-}
-
-
-/**
- * \brief Header Elements too long will not be printed
- * \todo See comments of \ref Document::MAX_SIZE_PRINT_ELEMENT_VALUE
- * @param newSize
- */
-void Document::SetMaxSizePrintEntry(long newSize)
-{
- //DOH !! This is exactly SetMaxSizeLoadEntry FIXME FIXME
- if ( newSize < 0 )
- {
- return;
- }
- if ((uint32_t)newSize >= (uint32_t)0xffffffff )
- {
- MaxSizePrintEntry = 0xffffffff;
- return;
- }
- MaxSizePrintEntry = newSize;
-}
-
-
-
-/**
- * \brief Handle broken private tag from Philips NTSCAN
- * where the endianess is being switch to BigEndian for no
- * apparent reason
- * @return no return
- */
-void Document::HandleBrokenEndian(uint16_t &group, uint16_t &elem)
-{
- // Endian reversion. Some files contain groups of tags with reversed endianess.
- static int reversedEndian = 0;
- // try to fix endian switching in the middle of headers
- if ((group == 0xfeff) && (elem == 0x00e0))
- {
- // start endian swap mark for group found
- reversedEndian++;
- SwitchByteSwapCode();
- // fix the tag
- group = 0xfffe;
- elem = 0xe000;
- }
- else if (group == 0xfffe && elem == 0xe00d && reversedEndian)
- {
- // end of reversed endian group
- reversedEndian--;
- SwitchByteSwapCode();
- }
-}
-
-/**
- * \brief Accesses the info from 0002,0010 : Transfer Syntax and TS
- * else 1.
- * @return The full Transfer Syntax Name (as opposed to Transfer Syntax UID)
- */
-std::string Document::GetTransferSyntaxName()
-{
- // use the TS (TS : Transfer Syntax)
- std::string transferSyntax = GetEntry(0x0002,0x0010);
-
- if ( transferSyntax == GDCM_NOTLOADED )
- {
- gdcmErrorMacro( "Transfer Syntax not loaded. " << std::endl
- << "Better you increase MAX_SIZE_LOAD_ELEMENT_VALUE" );
- return "Uncompressed ACR-NEMA";
- }
- if ( transferSyntax == GDCM_UNFOUND )
- {
- gdcmVerboseMacro( "Unfound Transfer Syntax (0002,0010)");
- return "Uncompressed ACR-NEMA";
- }
-
- // we do it only when we need it
- const TSKey &tsName = Global::GetTS()->GetValue( transferSyntax );
-
- // Global::GetTS() is a global static you shall never try to delete it!
- return tsName;
-}
-
-/**
- * \brief Group 0002 is always coded Little Endian
- * whatever Transfer Syntax is
- * @return no return
- */
-void Document::HandleOutOfGroup0002(uint16_t group)
-{
- // Endian reversion. Some files contain groups of tags with reversed endianess.
- if ( !Group0002Parsed && group != 0x0002)
- {
- Group0002Parsed = true;
- // we just came out of group 0002
- // if Transfer syntax is Big Endian we have to change CheckSwap
-
- std::string ts = GetTransferSyntaxName();
- if ( !Global::GetTS()->IsTransferSyntax(ts) )
- {
- gdcmVerboseMacro("True DICOM File, with NO Tansfer Syntax: " << ts );
- return;
- }
-
- // FIXME Strangely, this works with
- //'Implicit VR Transfer Syntax (GE Private)
- if ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian )
- {
- gdcmVerboseMacro("Tansfer Syntax = Explicit VR - Big Endian");
- SwitchByteSwapCode();
- }
- }
-}
-
-/**
- * \brief Read the next tag but WITHOUT loading it's value
- * (read the 'Group Number', the 'Element Number',
- * gets the Dict Entry
- * gets the VR, gets the length, gets the offset value)
- * @return On succes the newly created DocEntry, NULL on failure.
- */
-DocEntry *Document::ReadNextDocEntry()
-{
- uint16_t group;
- uint16_t elem;
-
- try
- {
- group = ReadInt16();
- elem = ReadInt16();
- }
- catch ( FormatError e )
- {
- // We reached the EOF (or an error occured) therefore
- // header parsing has to be considered as finished.
- //std::cout << e;
- return 0;
- }
-
- // Sometimes file contains groups of tags with reversed endianess.
- HandleBrokenEndian(group, elem);
-
-// In 'true DICOM' files Group 0002 is allways little endian
- if ( HasDCMPreamble )
- HandleOutOfGroup0002(group);
-
- std::string vr = FindDocEntryVR();
- std::string realVR = vr;
-
- if( vr == GDCM_UNKNOWN)
- {
- DictEntry *dictEntry = GetDictEntry(group,elem);
- if( dictEntry )
- realVR = dictEntry->GetVR();
- }
-
- DocEntry *newEntry;
- if( Global::GetVR()->IsVROfSequence(realVR) )
- newEntry = NewSeqEntry(group, elem);
- else if( Global::GetVR()->IsVROfStringRepresentable(realVR) )
- newEntry = NewValEntry(group, elem,vr);
- else
- newEntry = NewBinEntry(group, elem,vr);
-
- if( vr == GDCM_UNKNOWN )
- {
- if( Filetype == ExplicitVR )
- {
- // We thought this was explicit VR, but we end up with an
- // implicit VR tag. Let's backtrack.
- std::string msg;
- msg = Util::Format("Falsely explicit vr file (%04x,%04x)\n",
- newEntry->GetGroup(), newEntry->GetElement());
- gdcmVerboseMacro( msg.c_str() );
- }
- newEntry->SetImplicitVR();
- }
-
- try
- {
- FindDocEntryLength(newEntry);
- }
- catch ( FormatError e )
- {
- // Call it quits
- //std::cout << e;
- delete newEntry;
- return 0;