Module: $RCSfile: gdcmFileHelper.cxx,v $
Language: C++
- Date: $Date: 2006/02/21 15:55:41 $
- Version: $Revision: 1.95 $
+ Date: $Date: 2006/03/01 09:45:04 $
+ Version: $Revision: 1.96 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
To be moved to User's guide / WIKI ?
We have to deal with 4 *very* different cases :
--1) user created ex nihilo his own image and wants to write it as a Dicom image.
+-1) user created ex nihilo his own image and wants to write it as a Dicom image.
+ USER_OWN_IMAGE
-2) user modified the pixels of an existing image.
+ FILTERED_IMAGE
-3) user created a new image, using existing images (eg MIP, MPR, cartography image)
--4) user anonymized an image without processing the pixels.
-
+ CREATED_IMAGE
+-4) user modified/added some tags *without processing* the pixels (anonymization..
+ UNMODIFIED_PIXELS_IMAGE
+
gdcm::FileHelper::CheckMandatoryElements() deals automatically with these cases.
1)2)3)4)
keeping the same 'Serie Instance UID' / 'Study Instance UID' for various images
Warning :
The user shouldn't add any image to a 'Manufacturer Serie'
- but there is no way no to allowed him to do that
+ but there is no way no to allow him to do that
None of the 'shadow elements' are droped out.
1)
-'Modality' (0x0008,0x0060) is defaulted to "OT" (other) if missing.
'Conversion Type (0x0008,0x0064) is forced to 'SYN' (Synthetic Image).
-'Study Date', 'Study Time' are defaulted to current Date and Time.
-1)2)3)
+1)3)
'Media Storage SOP Class UID' (0x0002,0x0002)
'SOP Class UID' (0x0008,0x0016) are set to
[Secondary Capture Image Storage]
0008 1115 SQ 1 Referenced Series Sequence
0008 1140 SQ 1 Referenced Image Sequence
-4) When user *knows* he didn't modified the pixels, he may ask the writer to keep some
-informations unchanged :
+4) When user *knows* he didn't modified the pixels, we keep some informations unchanged :
'Media Storage SOP Class UID' (0x0002,0x0002)
'SOP Class UID' (0x0008,0x0016)
'Image Type' (0x0008,0x0008)
'Conversion Type' (0x0008,0x0064)
-He has to use gdcm::FileHelper::SetKeepMediaStorageSOPClassUID(true)
-(probabely name has to be changed)
Bellow follows the full description (hope so !) of the consistency checks performed
-->'Media Storage SOP Class UID' (0x0002,0x0002)
--->'SOP Class UID' (0x0008,0x0016) are set to
+-->'SOP Class UID' (0x0008,0x0016) are defaulted to
[Secondary Capture Image Storage]
- (Potentialy, the image was modified by user, and post-processed;
- it's no longer a 'native' image)
- Except if user told he wants to keep MediaStorageSOPClassUID,
- when *he* knows he didn't modify the image (e.g. : he just anonymized the file)
-
--> 'Image Type' (0x0008,0x0008)
is forced to "DERIVED\PRIMARY"
(The written image is no longer an 'ORIGINAL' one)
- Except if user told he wants to keep MediaStorageSOPClassUID,
- when *he* knows he didn't modify the image (e.g. : he just anonymized the file)
+ Except if user knows he didn't modify the image (e.g. : he just anonymized the file)
--> Conversion Type (0x0008,0x0064)
- is forced to 'SYN' (Synthetic Image)
- Except if user told he wants to keep MediaStorageSOPClassUID,
- when *he* knows he didn't modify the image (e.g. : he just anonymized the file)
+ is defaulted to 'SYN' (Synthetic Image)
+ when *he* knows he created his own image ex nihilo
--> 'Modality' (0x0008,0x0060)
is defaulted to "OT" (other) if missing.
--> Patient ID, Patient's Birth Date, Patient's Sex, (Type 2)
--> Referring Physician's Name (Type 2)
- are created, with empty value if there are missing.
+ are created, with empty value if there are missing.
-------------------------------------------------------------------------------------*/
{
std::string sop = Util::CreateUniqueUID();
+ // --------------------- For Meta Elements ---------------------
// just to remember : 'official' 0002 group
if ( WriteType != ACR && WriteType != ACR_LIBIDO )
{
Archive->Push(e_0002_0001);
e_0002_0001->Delete();
- if ( KeepMediaStorageSOPClassUID)
- // It up to the use to *know* whether he modified the pixels or not.
- // he is allowed to keep the original 'Media Storage SOP Class UID'
- CheckMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7");
+ if ( ContentType == FILTERED_IMAGE || ContentType == UNMODIFIED_PIXELS_IMAGE)
+ {
+ // we keep the original 'Media Storage SOP Class UID', we default it if missing
+ CheckMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7");
+ }
else
- // Potentialy this is a post-processed image
+ {
+ // It's *not* an image comming straight from a source. We force
// 'Media Storage SOP Class UID' --> [Secondary Capture Image Storage]
- CopyMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7");
-
+ CopyMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7");
+ }
+
// 'Media Storage SOP Instance UID'
CopyMandatoryEntry(0x0002,0x0003,sop);
CopyMandatoryEntry(0x0002,0x0013,version);
}
+ // --------------------- For DataSet ---------------------
+
+ if ( ContentType == FILTERED_IMAGE || ContentType == UNMODIFIED_PIXELS_IMAGE)
+ {
+ // we keep the original 'Media Storage SOP Class UID', we default it if missing (it should be present !)
+ CheckMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7");
+ }
+ else
+ {
+ // It's *not* an image comming straight from a source. We force
+ // 'Media Storage SOP Class UID' --> [Secondary Capture Image Storage]
+ CopyMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7");
+ }
+
// Push out 'LibIDO-special' entries, if any
Archive->Push(0x0028,0x0015);
Archive->Push(0x0028,0x0016);
// 'Imager Pixel Spacing' : defaulted to 'Pixel Spacing'
// --> This one is the *legal* one !
- // FIXME : we should write it only when we are *sure* the image comes from
+ if ( ContentType != USER_OWN_IMAGE)
+ // we write it only when we are *sure* the image comes from
// an imager (see also 0008,0x0064)
- CheckMandatoryEntry(0x0018,0x1164,pixelSpacing);
+ CheckMandatoryEntry(0x0018,0x1164,pixelSpacing);
// Samples Per Pixel (type 1) : default to grayscale
CheckMandatoryEntry(0x0028,0x0002,"1");
// --- Check UID-related Entries ---
- // If 'SOP Class UID' exists ('true DICOM' image)
+
+ if ( ContentType != USER_OWN_IMAGE) // when it's not a user made image
+ {
+ // If 'SOP Class UID' exists ('true DICOM' image)
// we create the 'Source Image Sequence' SeqEntry
// to hold informations about the Source Image
-
- DataEntry *e_0008_0016 = FileInternal->GetDataEntry(0x0008, 0x0016);
- if ( e_0008_0016 )
- {
+
+ DataEntry *e_0008_0016 = FileInternal->GetDataEntry(0x0008, 0x0016);
+ if ( e_0008_0016 )
+ {
// Create 'Source Image Sequence' SeqEntry
SeqEntry *sis = SeqEntry::New (
Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x2112) );
Archive->Push(sis);
sis->Delete();
- // FIXME : is 'Image Type' *really* depending on the presence of'SOP Class UID'?
- if ( KeepMediaStorageSOPClassUID)
- // It up to the use to *know* whether he modified the pixels or not.
- // he is allowed to keep the original 'Media Storage SOP Class UID'
- // and 'Image Type' as well
- CheckMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY");
- else
- // Potentialy this is a post-processed image
- // (The written image is no longer an 'ORIGINAL' one)
- CopyMandatoryEntry(0x0008,0x0008,"DERIVED\\PRIMARY");
-
- }
+ // 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");
+ }
+ }
// At the end, not to overwrite the original ones,
// needed by 'Referenced SOP Instance UID', 'Referenced SOP Class UID'
// 'SOP Instance UID'
CopyMandatoryEntry(0x0008,0x0018,sop);
-
- // the gdcm written image is a [Secondary Capture Image Storage]
- // except if user told us he dind't modify the pixels, and, therefore
- // he want to keep the 'Media Storage SOP Class UID'
-
- // 'Media Storage SOP Class UID' : [Secondary Capture Image Storage]
- if ( KeepMediaStorageSOPClassUID)
- {
- // It up to the use to *know* whether he modified the pixels or not.
- // he is allowed to keep the original 'Media Storage SOP Class UID'
- CheckMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7");
- }
- else
- {
- // Potentialy this is a post-processed image
- // 'Media Storage SOP Class UID' --> [Secondary Capture Image Storage]
- CopyMandatoryEntry(0x0008,0x0016,"1.2.840.10008.5.1.4.1.1.7");
-
- // FIXME : Must we Force Value, or Default value ?
- // Is it Type 1 for any Modality ?
- // --> Answer seems to be NO :-(
- // FIXME : we should write it only when we are *sure* the image
- // *does not* come from an imager (see also 0018,0x1164)
+ if ( ContentType == USER_OWN_IMAGE)
+ {
// Conversion Type.
// Other possible values are :
// See PS 3.3, Page 408
// SI = Scanned Image
// DRW = Drawing
// SYN = Synthetic Image
-
- CheckMandatoryEntry(0x0008,0x0064,"SYN");
- }
+
+ CheckMandatoryEntry(0x0008,0x0064,"SYN"); // Why not?
+ }
+/*
+ if ( ContentType == CREATED_IMAGE)
+ {
+ /// \todo : find a trick to pass the Media Storage SOP Instance UID of the images used to create the current image
+
+ }
+*/
// ---- The user will never have to take any action on the following ----
// Deal with element 0x0000 (group length) of each group.
// First stage : get all the different Groups
+
/*
GroupHT grHT;
DocEntry *d = FileInternal->GetFirstEntry();
void FileHelper::Initialize()
{
UserFunction = 0;
- KeepMediaStorageSOPClassUID = false;
-
+ ContentType = USER_OWN_IMAGE;
+
WriteMode = WMODE_RAW;
WriteType = ExplicitVR;
Program: gdcm
Module: $RCSfile: gdcmFileHelper.h,v $
Language: C++
- Date: $Date: 2006/02/16 20:06:14 $
- Version: $Revision: 1.38 $
+ Date: $Date: 2006/03/01 09:45:04 $
+ Version: $Revision: 1.39 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
WMODE_RAW,
WMODE_RGB
};
-
-public:
+
/// \brief Constructs a FileHelper with a RefCounter
static FileHelper *New() {return new FileHelper();}
/// \brief Constructs a FileHelper with a RefCounter from a fileHelper
bool WriteDcmExplVR(std::string const &fileName);
bool WriteAcr (std::string const &fileName);
bool Write (std::string const &fileName);
- /// \brief if user knows he didn't modify the pixels (e.g. he just anonymized
- /// the file), he is allowed to ask to keep the original
- /// 'Media Storage SOP Class UID' and 'Image Type'
- void SetKeepMediaStorageSOPClassUID (bool v)
- { KeepMediaStorageSOPClassUID = v; }
- // no GetKeepMediaStorageSOPClassUID() method, on purpose!
-
+
+/// \brief We have to deal with 4 *very* different cases :
+/// -1) user created ex nihilo his own image and wants to write it as a Dicom image.
+/// USER_OWN_IMAGE
+/// -2) user modified the pixels of an existing image.
+/// FILTERED_IMAGE
+/// -3) user created a new image, using existing images (eg MIP, MPR, cartography image)
+/// CREATED_IMAGE
+/// -4) user anonymized an image without processing the pixels.
+/// ANONYMIZED_IMAGE
+
+ void SetContentType (ImageContentType c) { ContentType = c; }
+ // no GetContentType() method, on purpose!
+
void CallStartMethod();
void CallProgressMethod();
void CallEndMethod();
/// See vtkgdcmSerieViewer for an example
VOID_FUNCTION_PUINT8_PFILE_POINTER UserFunction;
- /// \brief if user knows he didn't modify the pixels (e.g. he just
- /// anonymized the file), he is allowed to ask to keep the original
- /// 'Media Storage SOP Class UID' and 'Image Type'
- bool KeepMediaStorageSOPClassUID;
+ /// \brief only user knows what he did before asking the image to be written
+ /// - he created ex nihilo his own image
+ /// - he just applied a mathematical process on the pixels
+ /// - he created a new image, using existing images (eg MIP, MPR,cartography)
+ /// - he anonymized and image (*no* modif on the pixels)
+ ImageContentType ContentType;
+
};
} // end namespace gdcm