Module: $RCSfile: gdcmFileHelper.cxx,v $
Language: C++
- Date: $Date: 2005/10/25 12:42:01 $
- Version: $Revision: 1.73 $
+ Date: $Date: 2005/11/03 08:46:03 $
+ Version: $Revision: 1.78 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
#include "gdcmPixelWriteConvert.h"
#include "gdcmDocEntryArchive.h"
#include "gdcmDictSet.h"
+#include "gdcmOrientation.h"
#include <fstream>
*/
FileHelper::FileHelper( )
{
- FileInternal = new File( );
- SelfHeader = true;
+ FileInternal = File::New( );
Initialize();
}
*/
FileHelper::FileHelper(File *header)
{
- FileInternal = header;
- SelfHeader = false;
- Initialize();
- if ( FileInternal->IsReadable() )
- {
- PixelReadConverter->GrabInformationsFromFile( FileInternal );
- }
-}
+ gdcmAssertMacro(header);
-#ifndef GDCM_LEGACY_REMOVE
-/*
- * brief DEPRECATED : use SetFilename() + SetLoadMode() + Load() methods
- * Constructor dedicated to deal with the *pixels* area of a ACR/DICOMV3
- * file (gdcm::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
- * note the in-memory representation of all available tags found in
- * the DICOM header is post-poned to first header information access.
- * This avoid a double parsing of public part of the header when
- * one sets an a posteriori shadow dictionary (efficiency can be
- * seen as a side effect).
- * param filename file to be opened for parsing
- * deprecated use SetFilename() + Load() methods
- */
-FileHelper::FileHelper(std::string const &filename )
-{
- FileInternal = new File( );
- FileInternal->SetFileName( filename );
- FileInternal->Load();
- SelfHeader = true;
+ FileInternal = header;
+ FileInternal->Register();
Initialize();
if ( FileInternal->IsReadable() )
{
PixelReadConverter->GrabInformationsFromFile( FileInternal );
}
}
-#endif
/**
* \brief canonical destructor
delete Archive;
}
- if ( SelfHeader )
- {
- delete FileInternal;
- }
- FileInternal = 0;
+ FileInternal->Unregister();
}
//-----------------------------------------------------------------------------
--> 'Referenced SOP Class UID' (0x0008, 0x1150)
whose value is the original 'SOP Class UID'
- ---> 'Referenced SOP Instance UID' (0x0008, 0x1155)
+ --> 'Referenced SOP Instance UID' (0x0008, 0x1155)
whose value is the original 'SOP Class UID'
--> Bits Stored, Bits Allocated, Hight Bit Position are checked for consistency
--> Pixel Spacing (0x0028,0x0030) is defaulted to "1.0\1.0"
--> Samples Per Pixel (0x0028,0x0002) is defaulted to 1 (grayscale)
+--> Imager Pixel Spacing (0x0018,0x1164) : defaulted to 1.0\1.0
--> Instance Creation Date, Instance Creation Time, Study Date, Study Time
are force to current Date and Time
--> Conversion Type (0x0008,0x0064)
- is forced to 'SYN'
-
+ is forced to 'SYN' (Synthetic Image)
+
+--> Patient Orientation : (0x0020,0x0020), if not present, is deduced from
+ Image Orientation (Patient) : (0020|0037)
+
--> Study ID, Series Number, Instance Number, Patient Orientation (Type 2)
are created, with empty value if there are missing.
// Always modify the value
// Push the entries to the archive.
CopyMandatoryEntry(0x0002,0x0000,"0");
-
+
DataEntry *e_0002_0001 = CopyDataEntry(0x0002,0x0001, "OB");
e_0002_0001->SetBinArea((uint8_t*)Util::GetFileMetaInformationVersion(),
false);
Archive->Push(e_0002_0001);
e_0002_0001->Delete();
- // Potentialy post-processed image --> [Secondary Capture Image Storage]
- // 'Media Storage SOP Class UID'
+ // FIXME : we should allow user to tell he *wants* to keep the original
+ // 'Media Storage SOP Class UID'
+ // Potentialy this is a post-processed image
+ // 'Media Storage SOP Class UID' --> [Secondary Capture Image Storage]
+ //
CopyMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7");
// 'Media Storage SOP Instance UID'
<< " for consistency purpose");
}
+ // Imager Pixel Spacing : defaulted to 1.0\1.0
+ // --> This one is the *legal* one !
+ // FIXME : we should write it only when we are *sure* the image comes from
+ // an imager (see also 0008,0x0064)
+ CheckMandatoryEntry(0x0018,0x1164,"1.0\\1.0");
// Pixel Spacing : defaulted to 1.0\1.0
CheckMandatoryEntry(0x0028,0x0030,"1.0\\1.0");
// Samples Per Pixel (type 1) : default to grayscale
CheckMandatoryEntry(0x0028,0x0002,"1");
-
// --- Check UID-related Entries ---
// Create 'Source Image Sequence' SeqEntry
SeqEntry *sis = SeqEntry::New (
Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x2112) );
- SQItem *sqi = new SQItem(1);
+ SQItem *sqi = SQItem::New(1);
// (we assume 'SOP Instance UID' exists too)
// create 'Referenced SOP Class UID'
DataEntry *e_0008_1150 = DataEntry::New(
Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x1150) );
e_0008_1150->SetString( e_0008_0016->GetString());
sqi->AddEntry(e_0008_1150);
+ e_0008_1150->Delete();
// create 'Referenced SOP Instance UID'
DataEntry *e_0008_0018 = FileInternal->GetDataEntry(0x0008, 0x0018);
Global::GetDicts()->GetDefaultPubDict()->GetEntry(0x0008, 0x1155) );
e_0008_1155->SetString( e_0008_0018->GetString());
sqi->AddEntry(e_0008_1155);
+ e_0008_1155->Delete();
+
+ sis->AddSQItem(sqi,1);
+ sqi->Delete();
- sis->AddSQItem(sqi,1);
// temporarily replaces any previous 'Source Image Sequence'
Archive->Push(sis);
sis->Delete();
CopyMandatoryEntry(0x0008,0x0030,time);
// Accession Number
- CopyMandatoryEntry(0x0008,0x0050,"");
+ //CopyMandatoryEntry(0x0008,0x0050,"");
+ CheckMandatoryEntry(0x0008,0x0050,"");
- // Conversion Type ... FIXME (type 1)
+ // Conversion Type.
+ // Other possible values are :
// See PS 3.3, Page 408
+
+ // DV = Digitized Video
+ // DI = Digital Interface
+ // DF = Digitized Film
+ // WSD = Workstation
+ // SD = Scanned Document
+ // SI = Scanned Image
+ // DRW = Drawing
+ // SYN = Synthetic Image
+
+ // 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)
CopyMandatoryEntry(0x0008,0x0064,"SYN");
// ----- Add Mandatory Entries if missing ---
// The user is allowed to create his own Study,
// keeping the same 'Study Instance UID' for various images
// The user may add images to a 'Manufacturer Study',
- // adding new series to an already existing Study
+ // adding new Series to an already existing Study
CheckMandatoryEntry(0x0020,0x000d,Util::CreateUniqueUID());
// 'Serie Instance UID'
// The user is allowed to create his own Series,
// keeping the same 'Serie Instance UID' for various images
// 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 prevent him for doing that
CheckMandatoryEntry(0x0020,0x000e,Util::CreateUniqueUID());
// Study ID
// Instance Number
CheckMandatoryEntry(0x0020,0x0013,"");
-
- // Patient Orientation FIXME 1\0\0\0\1\0 or empty ?
- CheckMandatoryEntry(0x0020,0x0020,"");
+
+ // Patient Orientation
+ // Can be computed from (0020|0037) : Image Orientation (Patient)
+ gdcm::Orientation o;
+ std::string ori = o.GetOrientation ( FileInternal );
+ if (ori != "\\" )
+ CheckMandatoryEntry(0x0020,0x0020,ori);
+ else
+ CheckMandatoryEntry(0x0020,0x0020,"");
// Modality : if missing we set it to 'OTher'
CheckMandatoryEntry(0x0008,0x0060,"OT");