2003-04-7 Eric Boix <Eric.Boix@creatis.insa-lyon.fr> with JPR
* Data/im_00001 renamed to gdcm-MR-PHILIPS-16-Multi-Seq.dcm
+ * src:
+ - gdcmHeader::GetPubElValSet removed.
+ - gdcmElValSet::WriteDcm, WriteAcr, WriteExplVR, revamped to
+ UpdateGroupLength, WriteElements, Write.
+ * Test/*.cxx changed to agree with above changes
2003-03-31 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
* src/gdcmHeader.h: LoadElements() is not a public method anymore
// On suppose que les champs DICOM du 2ieme fichier existent *effectivement*
- // FIXME : floowing lines commented out in order to make compilation work.
- //FIXME f1->ReplaceOrCreateByNumber(0x0028, 0x0008, f2->GetPubElValSet().GetElValueByNumber(0x0028, 0x0008));// nb Frames
- //FIXME f1->ReplaceOrCreateByNumber(0x0028, 0x0010, f2->GetPubElValSet().GetElValueByNumber(0x0028, 0x0010));// nbLig
- //FIXME f1->ReplaceOrCreateByNumber(0x0028, 0x0011, f2->GetPubElValSet().GetElValueByNumber(0x0028, 0x0011));// nbCol
+ f1->ReplaceOrCreateByNumber(0x0028, 0x0008,
+ f2->GetPubElValByNumber(0x0028, 0x0008));// nb Frames
+ f1->ReplaceOrCreateByNumber(0x0028, 0x0010,
+ f2->GetPubElValByNumber(0x0028, 0x0010));// nbLig
+ f1->ReplaceOrCreateByNumber(0x0028, 0x0011,
+ f2->GetPubElValByNumber(0x0028, 0x0011));// nbCol
// sans doute d'autres à mettre à jour...
sprintf(resultat, "%s.vol", deuxieme.c_str());
printf ("WriteDCM\n");
- f1->WriteDcm(resultat);
+ f1->WriteDcmImplVR(resultat);
}
Source = gdcmFile(SourceFileName);
Source.GetImageData()
TargetFileName = "junk"
- Target = Source.WriteDcm(TargetFileName)
+ Target = Source.WriteDcmImplVR(TargetFileName)
Sign = 'c7d6bedae1bef3851f35b29952fbbd4b'
ComputeSign = md5.new(open(TargetFileName).read()).hexdigest()
#print ComputeSign
typedef string TagKey;
typedef string TagName;
+enum FileType {
+ Unknown = 0,
+ ExplicitVR,
+ ImplicitVR,
+ ACR,
+ ACR_LIBIDO
+}; // CLEANME
+
+
#endif
}
}
-int gdcmElValSet::Write(FILE * _fp) {
-
- string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
- SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
- //FIXME 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.
- SetElValueLengthByNumber(18, 0x0002, 0x0010);
-
- UpdateGroupLength();
- WriteElements(TrueDicom, _fp);
-
- return(1);
-}
-
-
-int gdcmElValSet::WriteAcr(FILE * _fp) {
- UpdateGroupLength(true);
- // Si on fait de l'implicit VR little Endian
- // (pour moins se fairche sur processeur INTEL)
- // penser a forcer le TRANSFERT SYNTAX UID
- WriteElements(ACR, _fp);
-
- return(1);
-}
+int gdcmElValSet::Write(FILE * _fp, FileType type) {
+
+ if (type == ImplicitVR) {
+ string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
+ SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);
+ //FIXME 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.
+ SetElValueLengthByNumber(18, 0x0002, 0x0010);
+ }
+ if (type == ExplicitVR) {
+ string explicitVRTransfertSyntax = "1.2.840.10008.1.2.1";
+ SetElValueByNumber(explicitVRTransfertSyntax, 0x0002, 0x0010);
+ // See above comment
+ SetElValueLengthByNumber(20, 0x0002, 0x0010);
+ }
-int gdcmElValSet::WriteExplVR(FILE * _fp) {
+ if ( (type == ImplicitVR) || (type == ExplicitVR) )
+ UpdateGroupLength();
+ if ( type == ACR)
+ UpdateGroupLength(true);
- string explicitVRTransfertSyntax = "1.2.840.10008.1.2.1";
- SetElValueByNumber(explicitVRTransfertSyntax, 0x0002, 0x0010);
- // See comment in gdcmElValSet::Write
- SetElValueLengthByNumber(20, 0x0002, 0x0010);
-
- UpdateGroupLength();
- WriteElements(ExplicitVR, _fp);
+ WriteElements(type, _fp);
- return(1);
+ return(1);
}
-
-
-
-// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.7 2003/04/07 15:04:40 frog Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.8 2003/04/08 15:03:35 frog Exp $
#ifndef GDCMELVALSET_H
#define GDCMELVALSET_H
TagElValueHT tagHt; // Both accesses with a TagKey or with a
TagElValueNameHT NameHt; // the DictEntry.Name are required.
//FIXME This is redundant with gdcmHeader::FileType enum. That sux !
-enum FileType {
- TrueDicom,
- ExplicitVR,
- ACR};
public:
void Add(gdcmElValue*);
// TODO
//void ReplaceOrCreate(gdcmElValue*);
void Print(ostream &);
void PrintByName(ostream &);
- int Write(FILE *fp);
- int WriteAcr(FILE *fp);
- int WriteExplVR(FILE *fp);
+ int Write(FILE *fp, FileType type);
gdcmElValue* GetElementByNumber(guint16 group, guint16 element);
gdcmElValue* GetElementByName (string);
*/
size_t gdcmFile::GetImageDataSize(void) {
- int nbLignes, nbCol, nbFrames, nb;
- string str_nbFrames, str_nb;
- // Nombre de Lignes
- nbLignes=atoi(gdcmHeader::GetPubElValByNumber(0x0028,0x0010).c_str());
- // Nombre de Colonnes
- nbCol =atoi(gdcmHeader::GetPubElValByNumber(0x0028,0x0011).c_str());
-
- // Nombre de Frames
- str_nbFrames=gdcmHeader::GetPubElValByNumber(0x0028,0x0008);
-
- if (str_nbFrames == "gdcm::Unfound" ) {
- nbFrames = 1;
- } else {
- nbFrames = atoi(str_nbFrames.c_str() );
- }
-
- // Nombre de Bits Alloues pour le stockage d'un Pixel
- str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100);
+ int nb;
+ string str_nb;
+ str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100);
if (str_nb == "gdcm::Unfound" ) {
nb = 16;
} else {
nb = atoi(str_nb.c_str() );
+ if (nb == 12) nb =16;
}
- size_t lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
+ size_t lgrTotale = GetXSize() * GetYSize() * GetZSize() *(nb/8);
return (lgrTotale);
}
* @return TODO JPR
*/
-int gdcmFile::WriteDcm (string nomFichier) {
-
-// ATTENTION : fonction non terminée (commitée a titre de precaution)
-
- FILE * fp1;
- char* filePreamble;
- fp1 = fopen(nomFichier.c_str(),"wb");
- if (fp1 == NULL) {
- printf("Echec ouverture (ecriture) Fichier [%s] \n",nomFichier.c_str());
- return (0);
- }
-
- // Ecriture Dicom File Preamble
- filePreamble=(char*)calloc(128,1);
- fwrite(filePreamble,128,1,fp1);
- fwrite("DICM",4,1,fp1);
-
- // un accesseur de + est obligatoire ???
- // pourtant le gdcmElValSet contenu dans le gdcmHeader
- // ne devrait pas être visible par l'utilisateur final (?)
-
- GetPubElValSet().Write(fp1);
-
- fwrite(Pixels, lgrTotale, 1, fp1);
-
- fclose (fp1);
- return(1);
+int gdcmFile::WriteDcmImplVR (string nomFichier) {
+ return WriteBase(nomFichier, ImplicitVR);
}
-int gdcmFile::WriteDcm (const char* nomFichier) {
- WriteDcm (string (nomFichier));
+int gdcmFile::WriteDcmImplVR (const char* nomFichier) {
+ return WriteDcmImplVR (string (nomFichier));
}
-
/////////////////////////////////////////////////////////////////
/**
* \ingroup gdcmFile
*/
int gdcmFile::WriteDcmExplVR (string nomFichier) {
-
-// ATTENTION : fonction non terminée (commitée a titre de precaution)
-
- FILE * fp1;
- char* filePreamble;
- fp1 = fopen(nomFichier.c_str(),"wb");
- if (fp1 == NULL) {
- printf("Echec ouverture (ecriture) Fichier [%s] \n",nomFichier.c_str());
- return (0);
- }
-
- // Ecriture Dicom File Preamble
- filePreamble=(char*)calloc(128,1);
- fwrite(filePreamble,128,1,fp1);
- fwrite("DICM",4,1,fp1);
-
- // un accesseur de + est obligatoire ???
- // pourtant le gdcmElValSet contenu dans le gdcmHeader
- // ne devrait pas être visible par l'utilisateur final (?)
-
- GetPubElValSet().WriteExplVR(fp1);
-
- fwrite(Pixels, lgrTotale, 1, fp1);
-
- fclose (fp1);
- return(1);
+ return WriteBase(nomFichier, ExplicitVR);
}
/////////////////////////////////////////////////////////////////
*/
int gdcmFile::WriteAcr (string nomFichier) {
+ return WriteBase(nomFichier, ACR);
+}
-// ATTENTION : fonction non terminée (commitée a titre de precaution)
-
- FILE * fp1;
- fp1 = fopen(nomFichier.c_str(),"wb");
- if (fp1 == NULL) {
- printf("Echec ouverture (ecriture) Fichier [%s] \n",nomFichier.c_str());
- return (0);
- }
-
- // un accesseur de + est obligatoire ???
- // pourtant le gdcmElValSet contenu dans le gdcmHeader
- // ne devrait pas être visible par l'utilisateur final (?)
-
- GetPubElValSet().WriteAcr(fp1);
-
- fwrite(Pixels, lgrTotale, 1, fp1);
-
- fclose (fp1);
- return(1);
+int gdcmFile::WriteBase (string nomFichier, FileType type) {
+
+ FILE * fp1;
+ fp1 = fopen(nomFichier.c_str(),"wb");
+ if (fp1 == NULL) {
+ printf("Echec ouverture (ecriture) Fichier [%s] \n",nomFichier.c_str());
+ return (0);
+ }
+
+ if ( (type == ImplicitVR) || (type == ExplicitVR) ) {
+ char * filePreamble;
+ // Ecriture Dicom File Preamble
+ filePreamble=(char*)calloc(128,1);
+ fwrite(filePreamble,128,1,fp1);
+ fwrite("DICM",4,1,fp1);
+ }
+
+ gdcmHeader::Write(fp1, type);
+ fwrite(Pixels, lgrTotale, 1, fp1);
+ fclose (fp1);
+ return(1);
}
void* Data;
int Parsed; // weather allready parsed
string OrigFileName; // To avoid file overwrite
+protected:
+ int WriteBase(string FileName, FileType type);
public:
// je ne suis pas sur d'avoir compris *où* il serait légitime de ranger ca.
// on pourra tjs le deplacer, et mettre des accesseurs
// Ca sera à l'utilisateur d'appeler son Reader correctement
int WriteRawData (string nomFichier);
- int WriteDcm (string nomFichier);
- int WriteDcm (const char * nomFichier);
- int WriteDcmExplVR (string nomFichier);
+ int WriteDcmImplVR(string nomFichier);
+ int WriteDcmImplVR(const char * nomFichier);
+ int WriteDcmExplVR(string nomFichier);
int WriteAcr (string nomFichier);
};
entCur = deb + 128;
if(memcmp(entCur, "DICM", (size_t)4) == 0) {
- filetype = TrueDicom;
dbg.Verbose(1, "gdcmHeader::CheckSwap:", "looks like DICOM Version3");
- } else {
- filetype = Unknown;
- dbg.Verbose(1, "gdcmHeader::CheckSwap:", "not a DICOM Version3 file");
- }
-
- if(filetype == TrueDicom) {
// Next, determine the value representation (VR). Let's skip to the
// first element (0002, 0000) and check there if we find "UL"
// - or "OB" if the 1st one is (0002,0001) -,
// * the 4 bytes of the first tag (0002, 0000),or (0002, 0001)
// i.e. a total of 136 bytes.
entCur = deb + 136;
- ///// FIXME
- ///// Use gdcmHeader::dicom_vr to test all the possibilities
- ///// insteadn of just checking for UL, OB and UI !?
+ // FIXME
+ // Use gdcmHeader::dicom_vr to test all the possibilities
+ // instead of just checking for UL, OB and UI !?
if( (memcmp(entCur, "UL", (size_t)2) == 0) ||
(memcmp(entCur, "OB", (size_t)2) == 0) ||
(memcmp(entCur, "UI", (size_t)2) == 0) )
rewind(fp);
fseek (fp, 132L, SEEK_SET);
return;
- } // End of TrueDicom
+ } // End of DicomV3
// Alas, this is not a DicomV3 file and whatever happens there is no file
// preamble. We can reset the file position indicator to where the data
// is (i.e. the beginning of the file).
+ dbg.Verbose(1, "gdcmHeader::CheckSwap:", "not a DICOM Version3 file");
rewind(fp);
// Our next best chance would be to be considering a 'clean' ACR/NEMA file.
// It is time for despaired wild guesses. So, let's assume this file
// happens to be 'dirty' ACR/NEMA, i.e. the length of the group is
// not present. Then the only info we have is the net2host one.
+ filetype = Unknown;
if (! net2host )
sw = 0;
else
* @return True when the file is a dicom version 3.
*/
bool gdcmHeader::IsDicomV3(void) {
- if ( (filetype == TrueDicom)
- || (filetype == ExplicitVR)
+ if ( (filetype == ExplicitVR)
|| (filetype == ImplicitVR) )
return true;
return false;
* @return The suggested integer.
*/
guint32 gdcmHeader::SwapLong(guint32 a) {
- // FIXME: il pourrait y avoir un pb pour les entiers negatifs ...
switch (sw) {
case 0 :
break;
"Erroneous Group Length element length.");
}
- /*
- // on le traite tt de même (VR peut donner l'info)
- // faire qq chose + ruse (pas de test si pas de VR)
- if ( group % 2 != 0 )
- // We only have some semantics on documented elements, which are
- // the even ones.
- return false;
-
- */
-
- /*
- if ( (length != 4) && ( length != 2) )
- // Swapping only make sense on integers which are 2 or 4 bytes long.
-
- // En fait, pour les entiers de 'Value Multiplicity' supérieur a 1
- // la longueur n'est pas forcement 2 ou 4
- // ET il faudra swapper.
- return false;
- */
-
if ( (vr == "UL") || (vr == "US") || (vr == "SL") || (vr == "SS") )
return true;
-
- // est-ce encore utile?
- // mieux vaut modifier le source du Dicom Dictionnary
- // et remplacer pour ces 2 cas RET par US
-
- if ( (group == 0x0028) && (element == 0x0005) )
- // The "Image Dimensions" tag is retained from ACR/NEMA and contains
- // the number of dimensions of the contained object (1 for Signal,
- // 2 for Image, 3 for Volume, 4 for Sequence).
- return true;
-
- if ( (group == 0x0028) && (element == 0x0200) )
- // This tag is retained from ACR/NEMA
- return true;
-
return false;
}
// is found by indirection through the "Image Location").
// Inside the group pointed by "Image Location" the searched element
// is conventionally the element 0x0010 (when the norm is respected).
- // When the "Image Location" is absent we default to group 0x7fe0.
+ // When the "Image Location" is absent we default to group 0x7fe0.
guint16 grPixel;
guint16 numPixel;
string ImageLocation = GetPubElValByName("Image Location");
grPixel = (guint16) atoi( ImageLocation.c_str() );
}
if (grPixel != 0x7fe0)
- // FIXME is this still necessary ?
- // Now, this looks like an old dirty fix for Philips imager
+ // This is a kludge for old dirty Philips imager.
numPixel = 0x1010;
else
numPixel = 0x0010;
gdcmDictEntry * gdcmHeader::GetDictEntryByKey(guint16 group, guint16 element) {
gdcmDictEntry * found = (gdcmDictEntry*)0;
if (!RefPubDict && !RefShaDict) {
- dbg.Verbose(0, "FIXME in gdcmHeader::GetDictEntry",
+ dbg.Verbose(0, "gdcmHeader::GetDictEntry",
"we SHOULD have a default dictionary");
}
if (RefPubDict) {
gdcmDictEntry * gdcmHeader::GetDictEntryByName(string Name) {
gdcmDictEntry * found = (gdcmDictEntry*)0;
if (!RefPubDict && !RefShaDict) {
- dbg.Verbose(0, "FIXME in gdcmHeader::GetDictEntry",
+ dbg.Verbose(0, "gdcmHeader::GetDictEntry",
"we SHOULD have a default dictionary");
}
if (RefPubDict) {
void gdcmHeader::PrintPubDict(ostream & os) {
RefPubDict->Print(os);
}
+
+int gdcmHeader::Write(FILE * fp, FileType type) {
+ return PubElValSet.Write(fp, type);
+}
bool IsDicomV3(void);
protected:
- // FIXME: is this enum still necessary ??
- enum FileType {
- Unknown = 0,
- TrueDicom,
- ExplicitVR,
- ImplicitVR,
- ACR,
- ACR_LIBIDO}; // CLEANME
FileType filetype;
int write(ostream&);
int anonymize(ostream&); // FIXME : anonymize should be a friend ?
int SetPubElValLengthByNumber(guint32 lgr, guint16 group, guint16 element);
int ReplaceOrCreateByNumber(guint16 Group, guint16 Elem, string Value);
-
- gdcmElValSet GetPubElValSet() { return(PubElValSet); }
-
int GetXSize(void);
int GetYSize(void);
int GetZSize(void);
string GetPixelType(void);
+ int Write(FILE *, FileType);
};
/**
* \ingroup gdcmHeaderIdo
- * \brief Pour les fichiers non TrueDicom, si le recognition
- * code (0008,0010) s'avere etre "ACR_LIBIDO", alors
- * valide la reconnaissance du fichier en positionnant
+ * \brief Si le recognition code (0008,0010) s'avere etre "ACR_LIBIDO",
+ * alors valide la reconnaissance du fichier en positionnant
* filetype.
*/
void gdcmHeaderIdo::setAcrLibido(void) {
string RecCode;
- if ( (filetype != TrueDicom)
- && (filetype != ExplicitVR)
- && (filetype != ImplicitVR) ) {
- printf("_setAcrLibido expects a presumably ACR file\n");
- // Recognition Code --> n'existe plus en DICOM V3 ...
- RecCode = GetPubElValByNumber(0x0008, 0x0010);
- // FIXME NOW
- if (RecCode == "ACRNEMA_LIBIDO" ||
- RecCode == "CANRME_AILIBOD" )
- filetype = ACR_LIBIDO;
- else
- filetype = ACR;
- }
+ RecCode = GetPubElValByNumber(0x0008, 0x0010);
+ if (RecCode == "ACRNEMA_LIBIDO" ||
+ RecCode == "CANRME_AILIBOD" )
+ filetype = ACR_LIBIDO;
return;
}