Module: $RCSfile: gdcmFileHelper.cxx,v $
Language: C++
- Date: $Date: 2007/08/28 14:05:33 $
- Version: $Revision: 1.124 $
+ Date: $Date: 2007/10/25 07:52:59 $
+ Version: $Revision: 1.136 $
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>
}
/**
- * \brief Access to the underlying \ref PixelReadConverter RGBA LUT
+ * \brief Access to the underlying PixelReadConverter RGBA LUT
*/
uint8_t* FileHelper::GetLutRGBA()
{
}
/**
- * \brief Access to the underlying \ref PixelReadConverter RGBA LUT Item Number
+ * \brief Access to the underlying PixelReadConverter RGBA LUT Item Number
*/
int FileHelper::GetLutItemNumber()
{
}
/**
- * \brief Access to the underlying \ref PixelReadConverter RGBA LUT Item Size
+ * \brief Access to the underlying PixelReadConverter RGBA LUT Item Size
*/
int FileHelper::GetLutItemSize()
{
{
CheckMandatoryElements(); //called once, here !
- bool flag = false;
- DocEntry *e;
switch(WriteType)
{
case ImplicitVR:
break;
case JPEG2000:
- /// \TODO Maybe we should consider doing the compression here !
+ /// \todo Maybe we should consider doing the compression here !
// PixelWriteConverter->SetCompressJPEG2000UserData(inData, expectedSize, FileInternal);
SetWriteFileTypeToJPEG2000();
int numberBitsAllocated = FileInternal->GetBitsAllocated();
if ( numberBitsAllocated == 0 || numberBitsAllocated == 12 )
{
- gdcmWarningMacro( "numberBitsAllocated changed from "
- << numberBitsAllocated << " to 16 "
+ gdcmWarningMacro( "numberBitsAllocated changed from "
+ << numberBitsAllocated << " to 16 "
<< " for consistency purpose" );
numberBitsAllocated = 16;
}
size_t decSize = FileInternal->GetXSize()
- * FileInternal->GetYSize()
+ * FileInternal->GetYSize()
* FileInternal->GetZSize()
* FileInternal->GetTSize()
* FileInternal->GetSamplesPerPixel()
if ( FileInternal->HasLUT() )
rgbSize = decSize * 3;
+ size_t userDataSize = PixelWriteConverter->GetUserDataSize();
switch(WriteMode)
{
case WMODE_RAW :
- if ( decSize!=PixelWriteConverter->GetUserDataSize() )
+ if ( abs((long)(decSize-userDataSize))>1) // ignore padding zero
{
gdcmWarningMacro( "Data size (Raw) is incorrect. Should be "
<< decSize << " / Found :"
- << PixelWriteConverter->GetUserDataSize() );
+ << userDataSize );
return false;
}
break;
case WMODE_RGB :
- if ( rgbSize!=PixelWriteConverter->GetUserDataSize() )
+ if ( abs((long)(rgbSize-userDataSize))>1) // ignore padding zero
{
gdcmWarningMacro( "Data size (RGB) is incorrect. Should be "
- << decSize << " / Found "
- << PixelWriteConverter->GetUserDataSize() );
+ << rgbSize << " / Found "
+ << userDataSize );
return false;
}
break;
-4) user modified/added some tags *without processing* the pixels (anonymization...)
UNMODIFIED_PIXELS_IMAGE
-Probabely some more to be added.
+ --> Set it with FileHelper::SetContentType(int);
gdcm::FileHelper::CheckMandatoryElements() deals automatically with these cases.
--> 'Referenced SOP Instance UID' (0x0008, 0x1155)
whose value is the original 'SOP Class UID'
-3) TODO : find a trick to allow user to pass to the writter the list of the Dicom images
+3) TO DO : find a trick to allow user to pass to the writter the list of the Dicom images
or the Series, (or the Study ?) he used to created his image
(MIP, MPR, cartography image, ...)
These info should be stored (?)
// --------------------- 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");
+ }
+ }
}
}
PixelReadConverter = new PixelReadConvert;
PixelWriteConverter = new PixelWriteConvert;
Archive = new DocEntryArchive( FileInternal );
+
+ KeepOverlays = false;
}
/**
/* Probabely something to be added to use Rescale Slope/Intercept
-Have a look ,at ITK code !
+Have a look at ITK code !
// Internal function to rescale pixel according to Rescale Slope/Intercept
template<class TBuffer, class TSource>