- return ( IsJPEGBaseLineProcess1TransferSyntax()
- || IsJPEGExtendedProcess2_4TransferSyntax()
- || IsJPEGExtendedProcess3_5TransferSyntax()
- || IsJPEGSpectralSelectionProcess6_8TransferSyntax()
- || IsJPEGLossless()
- || IsJPEG2000() );
-}
-
-
-/**
- * \brief Determines if the Transfer Syntax corresponds to encapsulated
- * of encoded Pixel Data (as opposed to native).
- * @return True when encapsulated. False when native.
- */
-bool Document::IsEncapsulateTransferSyntax()
-{
- return ( IsJPEGTransferSyntax()
- || IsRLELossLessTransferSyntax() );
-}
-
-/**
- * \brief Predicate for dicom version 3 file.
- * @return True when the file is a dicom version 3.
- */
-bool Document::IsDicomV3()
-{
- // Checking if Transfert Syntax exists is enough
- // Anyway, it's to late check if the 'Preamble' was found ...
- // And ... would it be a rich idea to check ?
- // (some 'no Preamble' DICOM images exist !)
- return GetDocEntryByNumber(0x0002, 0x0010) != NULL;
-}
-
-/**
- * \brief returns the File Type
- * (ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown)
- * @return the FileType code
- */
-FileType Document::GetFileType()
-{
- return Filetype;
-}
-
-/**
- * \brief Tries to open the file \ref Document::Filename and
- * checks the preamble when existing.
- * @return The FILE pointer on success.
- */
-FILE* Document::OpenFile()
-{
- Fp = fopen(Filename.c_str(),"rb");
-
- if(!Fp)
- {
- dbg.Verbose( 0,
- "Document::OpenFile cannot open file: ",
- Filename.c_str());
- return 0;
- }
-
- uint16_t zero;
- fread(&zero, (size_t)2, (size_t)1, Fp);
-
- //ACR -- or DICOM with no Preamble --
- if( zero == 0x0008 || zero == 0x0800 || zero == 0x0002 || zero == 0x0200 )
- {
- return Fp;
- }
-
- //DICOM
- fseek(Fp, 126L, SEEK_CUR);
- char dicm[4];
- fread(dicm, (size_t)4, (size_t)1, Fp);
- if( memcmp(dicm, "DICM", 4) == 0 )
- {
- return Fp;
- }
-
- fclose(Fp);
- dbg.Verbose( 0,
- "Document::OpenFile not DICOM/ACR (missing preamble)",
- Filename.c_str());
-
- return 0;
-}
-
-/**
- * \brief closes the file
- * @return TRUE if the close was successfull
- */
-bool Document::CloseFile()
-{
- int closed = fclose(Fp);
- Fp = 0;
-
- return closed;
-}
-
-/**
- * \brief Writes in a file all the Header Entries (Dicom Elements)
- * @param fp file pointer on an already open file
- * @param filetype Type of the File to be written
- * (ACR-NEMA, ExplicitVR, ImplicitVR)
- * \return Always true.
- */
-void Document::Write(FILE* fp,FileType filetype)
-{
- /// \todo move the following lines (and a lot of others, to be written)
- /// to a future function CheckAndCorrectHeader
- /// (necessary if user wants to write a DICOM V3 file
- /// starting from an ACR-NEMA (V2) Header
-
- if (filetype == ImplicitVR)
- {
- std::string implicitVRTransfertSyntax = UI1_2_840_10008_1_2;
- ReplaceOrCreateByNumber(implicitVRTransfertSyntax,0x0002, 0x0010);
-
- /// \todo Refer to standards on page 21, chapter 6.2
- /// "Value representation": values with a VR of UI shall be
- /// padded with a single trailing null
- /// in the following case we have to padd manually with a 0
-
- SetEntryLengthByNumber(18, 0x0002, 0x0010);
- }
-
- if (filetype == ExplicitVR)
- {
- std::string explicitVRTransfertSyntax = UI1_2_840_10008_1_2_1;
- ReplaceOrCreateByNumber(explicitVRTransfertSyntax,0x0002, 0x0010);
-
- /// \todo Refer to standards on page 21, chapter 6.2
- /// "Value representation": values with a VR of UI shall be
- /// padded with a single trailing null
- /// Dans le cas suivant on doit pader manuellement avec un 0
-
- SetEntryLengthByNumber(20, 0x0002, 0x0010);
- }
-
-/**
- * \todo rewrite later, if really usefull
- * - 'Group Length' element is optional in DICOM
- * - but un-updated odd groups lengthes can causes pb
- * (xmedcon breaker)
- *
- * if ( (filetype == ImplicitVR) || (filetype == ExplicitVR) )
- * UpdateGroupLength(false,filetype);
- * if ( filetype == ACR)
- * UpdateGroupLength(true,ACR);
- */
-
- ElementSet::Write(fp, filetype); // This one is recursive
-
-}
-
-/**
- * \brief Modifies the value of a given Header Entry (Dicom Element)
- * when it exists. Create it with the given value when unexistant.
- * @param value (string) Value to be set
- * @param group Group number of the Entry
- * @param elem Element number of the Entry
- * @param VR V(alue) R(epresentation) of the Entry -if private Entry-
- * \return pointer to the modified/created Header Entry (NULL when creation
- * failed).
- */
-ValEntry* Document::ReplaceOrCreateByNumber(
- std::string const & value,
- uint16_t group,
- uint16_t elem,
- std::string const & VR )
-{
- ValEntry* valEntry = 0;
- DocEntry* currentEntry = GetDocEntryByNumber( group, elem);
-
- if (!currentEntry)
- {
- // check if (group,element) DictEntry exists
- // if it doesn't, create an entry in DictSet::VirtualEntry
- // and use it
-
- // Find out if the tag we received is in the dictionaries:
- Dict *pubDict = Global::GetDicts()->GetDefaultPubDict();
- DictEntry* dictEntry = pubDict->GetDictEntryByNumber(group, elem);
- if (!dictEntry)
- {
- currentEntry = NewDocEntryByNumber(group, elem,VR);
- }
- else
- {
- currentEntry = NewDocEntryByNumber(group, elem);
- }
-
- if (!currentEntry)
- {
- dbg.Verbose(0, "Document::ReplaceOrCreateByNumber: call to"
- " NewDocEntryByNumber failed.");
- return NULL;
- }
- valEntry = new ValEntry(currentEntry);
- if ( !AddEntry(valEntry))
- {
- dbg.Verbose(0, "Document::ReplaceOrCreateByNumber: AddEntry"
- " failed allthough this is a creation.");
- }
- }
- else
- {
- valEntry = dynamic_cast< ValEntry* >(currentEntry);
- if ( !valEntry ) // Euuuuh? It wasn't a ValEntry
- // then we change it to a ValEntry ?
- // Shouldn't it be considered as an error ?
- {
- // We need to promote the DocEntry to a ValEntry:
- valEntry = new ValEntry(currentEntry);
- if (!RemoveEntry(currentEntry))
- {
- dbg.Verbose(0, "Document::ReplaceOrCreateByNumber: removal"
- " of previous DocEntry failed.");
- return NULL;
- }
- if ( !AddEntry(valEntry))
- {
- dbg.Verbose(0, "Document::ReplaceOrCreateByNumber: adding"
- " promoted ValEntry failed.");
- return NULL;
- }
- }
- }
-
- SetEntryByNumber(value, group, elem);
-
- return valEntry;
-}
-
-/*
- * \brief Modifies the value of a given Header Entry (Dicom Element)
- * when it exists. Create it with the given value when unexistant.
- * @param binArea (binary) value to be set
- * @param Group Group number of the Entry
- * @param Elem Element number of the Entry
- * \return pointer to the modified/created Header Entry (NULL when creation
- * failed).
- */
-BinEntry* Document::ReplaceOrCreateByNumber(
- uint8_t* binArea,
- int lgth,
- uint16_t group,
- uint16_t elem,
- std::string const& VR )
-{
- BinEntry* binEntry = 0;
- DocEntry* currentEntry = GetDocEntryByNumber( group, elem);
- if (!currentEntry)
- {
-
- // check if (group,element) DictEntry exists
- // if it doesn't, create an entry in DictSet::VirtualEntry
- // and use it
-
- // Find out if the tag we received is in the dictionaries:
- Dict *pubDict = Global::GetDicts()->GetDefaultPubDict();
- DictEntry *dictEntry = pubDict->GetDictEntryByNumber(group, elem);
-
- if (!dictEntry)
- {
- currentEntry = NewDocEntryByNumber(group, elem, VR);
- }
- else
- {
- currentEntry = NewDocEntryByNumber(group, elem);
- }
- if (!currentEntry)
- {
- dbg.Verbose(0, "Document::ReplaceOrCreateByNumber: call to"
- " NewDocEntryByNumber failed.");
- return NULL;
- }
- binEntry = new BinEntry(currentEntry);
- if ( !AddEntry(binEntry))
- {
- dbg.Verbose(0, "Document::ReplaceOrCreateByNumber: AddEntry"
- " failed allthough this is a creation.");
- }
- }
- else
- {
- binEntry = dynamic_cast< BinEntry* >(currentEntry);
- if ( !binEntry ) // Euuuuh? It wasn't a BinEntry
- // then we change it to a BinEntry ?
- // Shouldn't it be considered as an error ?
- {
- // We need to promote the DocEntry to a BinEntry:
- binEntry = new BinEntry(currentEntry);
- if (!RemoveEntry(currentEntry))
- {
- dbg.Verbose(0, "Document::ReplaceOrCreateByNumber: removal"
- " of previous DocEntry failed.");
- return NULL;
- }
- if ( !AddEntry(binEntry))
- {
- dbg.Verbose(0, "Document::ReplaceOrCreateByNumber: adding"
- " promoted BinEntry failed.");
- return NULL;
- }
- }
- }
-
- SetEntryByNumber(binArea, lgth, group, elem);
-
- return binEntry;
-}
-
-
-/*
- * \brief Modifies the value of a given Header Entry (Dicom Element)
- * when it exists. Create it when unexistant.
- * @param Group Group number of the Entry
- * @param Elem Element number of the Entry
- * \return pointer to the modified/created SeqEntry (NULL when creation
- * failed).
- */
-SeqEntry* Document::ReplaceOrCreateByNumber(
- uint16_t group,
- uint16_t elem)
-{
- SeqEntry* b = 0;
- DocEntry* a = GetDocEntryByNumber( group, elem);
- if (!a)
- {
- a = NewSeqEntryByNumber(group, elem);
- if (!a)
- {
- return 0;
- }
-
- b = new SeqEntry(a, 1); // FIXME : 1 (Depth)
- AddEntry(b);
- }
- return b;
-}
-
-/**
- * \brief Set a new value if the invoked element exists
- * Seems to be useless !!!
- * @param value new element value
- * @param group group number of the Entry
- * @param elem element number of the Entry
- * \return boolean
- */
-bool Document::ReplaceIfExistByNumber(std::string const & value,
- uint16_t group, uint16_t elem )
-{
- SetEntryByNumber(value, group, elem);
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Protected
-
-/**
- * \brief Checks if a given Dicom Element exists within the H table
- * @param group Group number of the searched Dicom Element
- * @param element Element number of the searched Dicom Element
- * @return true is found
- */
-bool Document::CheckIfEntryExistByNumber(uint16_t group, uint16_t element )
-{
- const std::string &key = DictEntry::TranslateToKey(group, element );
- return TagHT.count(key);
-}
-
-/**
- * \brief Searches within Header Entries (Dicom Elements) parsed with
- * the public and private dictionaries
- * for the element value of a given tag.
- * \warning Don't use any longer : use GetPubEntryByName
- * @param tagName name of the searched element.
- * @return Corresponding element value when it exists,
- * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
- */
-std::string Document::GetEntryByName(TagName const& tagName)
-{
- DictEntry* dictEntry = RefPubDict->GetDictEntryByName(tagName);
- if( !dictEntry )
- {
- return GDCM_UNFOUND;
- }
-
- return GetEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement());
-}
-
-/**
- * \brief Searches within Header Entries (Dicom Elements) parsed with
- * the public and private dictionaries
- * for the element value representation of a given tag.
- *
- * Obtaining the VR (Value Representation) might be needed by caller
- * to convert the string typed content to caller's native type
- * (think of C++ vs Python). The VR is actually of a higher level
- * of semantics than just the native C++ type.
- * @param tagName name of the searched element.
- * @return Corresponding element value representation when it exists,
- * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise.
- */
-std::string Document::GetEntryVRByName(TagName const& tagName)
-{
- DictEntry *dictEntry = RefPubDict->GetDictEntryByName(tagName);
- if( dictEntry == NULL)
- {
- return GDCM_UNFOUND;
- }
-
- DocEntry* elem = GetDocEntryByNumber(dictEntry->GetGroup(),
- dictEntry->GetElement());
- return elem->GetVR();
-}