Module: $RCSfile: gdcmFileHelper.cxx,v $
Language: C++
- Date: $Date: 2007/10/08 15:20:17 $
- Version: $Revision: 1.132 $
+ Date: $Date: 2008/09/15 15:49:22 $
+ Version: $Revision: 1.138 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
#include "gdcmDocEntryArchive.h"
#include "gdcmDictSet.h"
#include "gdcmOrientation.h"
-
+
+
+
+#include <algorithm> // for transform?
+
#if defined(__BORLANDC__)
- #include <mem.h> // for memset
+ #include <mem.h> // for memset
+ #include <ctype.h> //for toupper
+ #include <math.h>
#endif
#include <fstream>
These lines will be moved to the document-to-be 'User's Guide'
-// To read an image, user needs a gdcm::File
-gdcm::File *f = new gdcm::File(fileName);
+// To read an image, user needs a GDCM_NAME_SPACE::File
+GDCM_NAME_SPACE::File *f = new GDCM_NAME_SPACE::File(fileName);
// or (advanced) :
// user may also decide he doesn't want to load some parts of the header
-gdcm::File *f = new gdcm::File();
+GDCM_NAME_SPACE::File *f = new GDCM_NAME_SPACE::File();
f->SetFileName(fileName);
f->SetLoadMode(LD_NOSEQ); // or
f->SetLoadMode(LD_NOSHADOW); // or
// user can now check some values
std::string v = f->GetEntryValue(groupNb,ElementNb);
-// to get the pixels, user needs a gdcm::FileHelper
-gdcm::FileHelper *fh = new gdcm::FileHelper(f);
+// to get the pixels, user needs a GDCM_NAME_SPACE::FileHelper
+GDCM_NAME_SPACE::FileHelper *fh = new GDCM_NAME_SPACE::FileHelper(f);
// user may ask not to convert Palette (if any) to RGB
uint8_t *pixels = fh->GetImageDataRaw();
// He can now use the pixels, create a new image, ...
uint8_t *userPixels = ...
-//To re-write the image, user re-uses the gdcm::FileHelper
-gdcm::File *fh = new gdcm::FileHelper();
+//To re-write the image, user re-uses the GDCM_NAME_SPACE::FileHelper
+GDCM_NAME_SPACE::File *fh = new GDCM_NAME_SPACE::FileHelper();
fh->SetTypeToRaw(); // Even if it was possible to convert Palette to RGB
// (WriteMode is set)
ElementSet::WriteContent(fp, writetype);
writes recursively all DataElements
RestoreWrite();
- (moves back to the gdcm::File all the archived elements)
+ (moves back to the GDCM_NAME_SPACE::File all the archived elements)
*/
// Constructor / Destructor
/**
* \brief Constructor dedicated to deal with the *pixels* area of a ACR/DICOMV3
- * file (gdcm::File only deals with the ... header)
+ * file (GDCM_NAME_SPACE::File only deals with the ... header)
* Opens (in read only and when possible) an existing file and checks
* for DICOM compliance. Returns NULL on failure.
* It will be up to the user to load the pixels into memory
/**
* \brief canonical destructor
- * \note If the header (gdcm::File) was created by the FileHelper constructor,
+ * \note If the header (GDCM_NAME_SPACE::File) was created by the FileHelper constructor,
* it is destroyed by the FileHelper
*/
FileHelper::~FileHelper()
// Public
/**
- * \brief Sets the LoadMode of the internal gdcm::File as a boolean string.
+ * \brief Sets the LoadMode of the internal GDCM_NAME_SPACE::File as a boolean string.
* NO_SEQ, NO_SHADOW, NO_SHADOWSEQ ... (nothing more, right now)
* WARNING : before using NO_SHADOW, be sure *all* your files
* contain accurate values in the 0x0000 element (if any)
GetFile()->SetLoadMode( loadMode );
}
/**
- * \brief Sets the LoadMode of the internal gdcm::File
+ * \brief Sets the LoadMode of the internal GDCM_NAME_SPACE::File
* @param fileName name of the file to be open
*/
void FileHelper::SetFileName(std::string const &fileName)
if ( abs((long)(decSize-userDataSize))>1) // ignore padding zero
{
gdcmWarningMacro( "Data size (Raw) is incorrect. Should be "
- << decSize << " / Found :"
+ << decSize << "("
+ << FileInternal->GetXSize() << " * "
+ << FileInternal->GetYSize() << " * "
+ << FileInternal->GetZSize() << " * "
+ << FileInternal->GetTSize() << " * "
+ << FileInternal->GetSamplesPerPixel() << " * "
+ << numberBitsAllocated / 8
+ << ") / Found :"
<< userDataSize );
return false;
}
-Probabely some more to be added.
--> Set it with FileHelper::SetContentType(int);
-gdcm::FileHelper::CheckMandatoryElements() deals automatically with these cases.
+GDCM_NAME_SPACE::FileHelper::CheckMandatoryElements() deals automatically with these cases.
1)2)3)4)
0008 0012 Instance Creation Date
Bellow follows the full description (hope so !) of the consistency checks performed
-by gdcm::FileHelper::CheckMandatoryElements()
+by GDCM_NAME_SPACE::FileHelper::CheckMandatoryElements()
-->'Media Storage SOP Class UID' (0x0002,0x0002)
// --------------------- For DataSet ---------------------
+ // check whether 0018|0015 [CS] [Body Part Examined] value is UPPER CASE
+ // (avoid dciodvfy to complain!)
+ DataEntry *e_0018_0015 = FileInternal->GetDataEntry(0x0018, 0x0015);
+ if ( e_0018_0015)
+ {
+ std::string bodyPartExamined = e_0018_0015->GetString();
+ std::transform(bodyPartExamined.begin(), bodyPartExamined.end(), bodyPartExamined.begin(),
+ (int(*)(int)) toupper);
+ CopyMandatoryEntry(0x0018,0x0015,bodyPartExamined,"CS");
+ }
+
if ( ContentType != USER_OWN_IMAGE) // when it's not a user made image
{
// If 'SOP Class UID' and 'SOP Instance UID' exist ('true DICOM' image)
// we create the 'Source Image Sequence' SeqEntry
// to hold informations about the Source Image
-
+
+ // 'SOP Instance UID'
DataEntry *e_0008_0016 = FileInternal->GetDataEntry(0x0008, 0x0016);
+ //
DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
if ( e_0008_0016 && e_0008_0018)
{
- // Create 'Source Image Sequence' SeqEntry
- SeqEntry *sis = SeqEntry::New (0x0008, 0x2112);
- SQItem *sqi = SQItem::New(1);
+ // Create 'Source Image Sequence' SeqEntry
+ SeqEntry *sis = SeqEntry::New (0x0008, 0x2112);
+ SQItem *sqi = SQItem::New(1);
- // create 'Referenced SOP Class UID' from 'SOP Class UID'
+ // create 'Referenced SOP Class UID' from 'SOP Class UID'
- DataEntry *e_0008_1150 = DataEntry::New(0x0008, 0x1150, "UI");
- e_0008_1150->SetString( e_0008_0016->GetString());
- sqi->AddEntry(e_0008_1150);
- e_0008_1150->Delete();
+ DataEntry *e_0008_1150 = DataEntry::New(0x0008, 0x1150, "UI");
+ e_0008_1150->SetString( e_0008_0016->GetString());
+ sqi->AddEntry(e_0008_1150);
+ e_0008_1150->Delete();
- // create 'Referenced SOP Instance UID' from 'SOP Instance UID'
- DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
+ // create 'Referenced SOP Instance UID' from 'SOP Instance UID'
+ // DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
- DataEntry *e_0008_1155 = DataEntry::New(0x0008, 0x1155, "UI");
- e_0008_1155->SetString( e_0008_0018->GetString());
- sqi->AddEntry(e_0008_1155);
- e_0008_1155->Delete();
+ DataEntry *e_0008_1155 = DataEntry::New(0x0008, 0x1155, "UI");
+ e_0008_1155->SetString( e_0008_0018->GetString());
+ sqi->AddEntry(e_0008_1155);
+ e_0008_1155->Delete();
- sis->AddSQItem(sqi,1);
- sqi->Delete();
-
- // temporarily replaces any previous 'Source Image Sequence'
- Archive->Push(sis);
- sis->Delete();
- // FIXME : is 'Image Type' *really* depending on the presence of 'SOP Class UID'?
- if ( ContentType == FILTERED_IMAGE)
- // the user *knows* he just modified the pixels
- // the image is no longer an 'Original' one
- CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY","CS");
+ sis->AddSQItem(sqi,1);
+ sqi->Delete();
+
+ // temporarily replaces any previous 'Source Image Sequence'
+ Archive->Push(sis);
+ sis->Delete();
+ // FIXME : is 'Image Type' *really* depending on the presence of 'SOP Class UID'?
+
+ if ( ContentType == FILTERED_IMAGE) // the user *knows* he just modified the pixels
+ {
+ DataEntry *e_0008_0008 = FileInternal->GetDataEntry(0x0008, 0x0008);
+ if ( e_0008_0008)
+ {
+ std::string imageType = e_0008_0008->GetString();
+ std::string::size_type p = imageType.find("ORIGINAL");
+ if (p == 0) // image is ORIGINAL one
+ {
+ // the image is no longer an 'Original' one
+ CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY","CS");
+ }
+ // if Image Type was not ORIGINAL\..., we keep it.
+ }
+ else // 0008_0008 was missing, wee add it.
+ {
+ CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY","CS");
+ }
+ }
}
}