X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vtk%2FvtkGdcmWriter.cxx;h=333be8f232ba5e4be1a472528bd1319ae05c8cf3;hb=5ae9aa5467bc943c2545ed669aa616e2c93f5a24;hp=c9843e32136c2b746bf9962a956b76dfc36fbfc9;hpb=1c35ba5e5bc72b0861b92698dd4ea29f0bab5f73;p=gdcm.git diff --git a/vtk/vtkGdcmWriter.cxx b/vtk/vtkGdcmWriter.cxx index c9843e32..333be8f2 100644 --- a/vtk/vtkGdcmWriter.cxx +++ b/vtk/vtkGdcmWriter.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: vtkGdcmWriter.cxx,v $ Language: C++ - Date: $Date: 2004/12/09 17:08:36 $ - Version: $Revision: 1.6 $ + Date: $Date: 2005/10/25 14:52:37 $ + Version: $Revision: 1.26 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -16,9 +16,10 @@ =========================================================================*/ -#include "gdcmHeader.h" #include "gdcmFile.h" +#include "gdcmFileHelper.h" #include "gdcmDebug.h" +#include "gdcmUtil.h" #include "vtkGdcmWriter.h" #include @@ -26,8 +27,12 @@ #include #include -vtkCxxRevisionMacro(vtkGdcmWriter, "$Revision: 1.6 $"); -vtkStandardNewMacro(vtkGdcmWriter); +#ifndef vtkFloatingPointType +#define vtkFloatingPointType float +#endif + +vtkCxxRevisionMacro(vtkGdcmWriter, "$Revision: 1.26 $") +vtkStandardNewMacro(vtkGdcmWriter) //----------------------------------------------------------------------------- // Constructor / Destructor @@ -35,6 +40,7 @@ vtkGdcmWriter::vtkGdcmWriter() { this->LookupTable = NULL; this->FileDimensionality = 3; + this->WriteType = VTK_GDCM_WRITE_TYPE_EXPLICIT_VR; } vtkGdcmWriter::~vtkGdcmWriter() @@ -43,20 +49,38 @@ vtkGdcmWriter::~vtkGdcmWriter() //----------------------------------------------------------------------------- // Print -void vtkGdcmWriter::PrintSelf(ostream& os, vtkIndent indent) +void vtkGdcmWriter::PrintSelf(ostream &os, vtkIndent indent) { - this->Superclass::PrintSelf(os,indent); + this->Superclass::PrintSelf(os, indent); + + os << indent << "Write type : " << this->GetWriteTypeAsString(); } //----------------------------------------------------------------------------- // Public +const char *vtkGdcmWriter::GetWriteTypeAsString() +{ + switch(WriteType) + { + case VTK_GDCM_WRITE_TYPE_EXPLICIT_VR : + return "Explicit VR"; + case VTK_GDCM_WRITE_TYPE_IMPLICIT_VR : + return "Implicit VR"; + case VTK_GDCM_WRITE_TYPE_ACR : + return "ACR"; + case VTK_GDCM_WRITE_TYPE_ACR_LIBIDO : + return "ACR Libido"; + default : + return "Unknow type"; + } +} //----------------------------------------------------------------------------- // Protected /** * Copy the image and reverse the Y axis */ -// The output datas must be deleted by the user of the method !!! +// The output data must be deleted by the user of the method !!! size_t ReverseData(vtkImageData *image,unsigned char **data) { int inc[3]; @@ -70,31 +94,38 @@ size_t ReverseData(vtkImageData *image,unsigned char **data) size_t planeSize = dim[1] * lineSize; size_t size = dim[2] * planeSize; - *data = new unsigned char[size]; - - image->GetIncrements(inc); - unsigned char *src = (unsigned char *)image->GetScalarPointerForExtent(extent); - unsigned char *dst = *data + planeSize - lineSize; - for (int plane = extent[4]; plane <= extent[5]; plane++) + if( size>0 ) { - for (int line = extent[2]; line <= extent[3]; line++) + *data = new unsigned char[size]; + + image->GetIncrements(inc); + unsigned char *src = (unsigned char *)image->GetScalarPointerForExtent(extent); + unsigned char *dst = *data + planeSize - lineSize; + for (int plane = extent[4]; plane <= extent[5]; plane++) { - // Copy one line at proper destination: - memcpy((void*)dst, (void*)src, lineSize); + for (int line = extent[2]; line <= extent[3]; line++) + { + // Copy one line at proper destination: + memcpy((void*)dst, (void*)src, lineSize); - src += inc[1]*image->GetScalarSize(); - dst -= lineSize; + src += inc[1] * image->GetScalarSize(); + dst -= lineSize; + } + dst += 2 * planeSize; } - dst += 2 * planeSize; + } + else + { + *data = NULL; } return size; } /** - * Set the datas informations in the file + * Set the data informations in the file */ -void SetImageInformation(gdcm::File *file,vtkImageData *image) +void SetImageInformation(gdcm::FileHelper *file, vtkImageData *image) { std::ostringstream str; @@ -106,36 +137,37 @@ void SetImageInformation(gdcm::File *file,vtkImageData *image) str.str(""); str << dim[0]; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0011); + file->InsertEntryString(str.str(),0x0028,0x0011); // Columns str.str(""); str << dim[1]; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0010); + file->InsertEntryString(str.str(),0x0028,0x0010); // Rows if(dim[2]>1) { str.str(""); str << dim[2]; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0012); + //file->Insert(str.str(),0x0028,0x0012); // Planes + file->InsertEntryString(str.str(),0x0028,0x0008); // Number of Frames } // Pixel type str.str(""); str << image->GetScalarSize()*8; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0100); - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0101); + file->InsertEntryString(str.str(),0x0028,0x0100); // Bits Allocated + file->InsertEntryString(str.str(),0x0028,0x0101); // Bits Stored str.str(""); str << image->GetScalarSize()*8-1; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0102); + file->InsertEntryString(str.str(),0x0028,0x0102); // High Bit // Pixel Repr // FIXME : what do we do when the ScalarType is // VTK_UNSIGNED_INT or VTK_UNSIGNED_LONG str.str(""); - if( image->GetScalarType() == VTK_UNSIGNED_CHAR || + if( image->GetScalarType() == VTK_UNSIGNED_CHAR || image->GetScalarType() == VTK_UNSIGNED_SHORT || - image->GetScalarType() == VTK_UNSIGNED_INT || + image->GetScalarType() == VTK_UNSIGNED_INT || image->GetScalarType() == VTK_UNSIGNED_LONG ) { str << "0"; // Unsigned @@ -144,68 +176,80 @@ void SetImageInformation(gdcm::File *file,vtkImageData *image) { str << "1"; // Signed } - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0103); + file->InsertEntryString(str.str(),0x0028,0x0103); // Pixel Representation // Samples per pixel str.str(""); str << image->GetNumberOfScalarComponents(); - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0002); + file->InsertEntryString(str.str(),0x0028,0x0002); // Samples per Pixel + + /// \todo : Spacing Between Slices is meaningfull ONLY for CT an MR modality + /// We should perform some checkings before forcing the Entry creation // Spacing - double *sp = image->GetSpacing(); + vtkFloatingPointType *sp = image->GetSpacing(); str.str(""); - str << sp[0] << "\\" << sp[1]; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0030); + // We are about to enter floating point value. + // By default ostringstream are smart and don't do fixed point + // thus forcing to fixed point value + str.setf( std::ios::fixed ); + str << sp[1] << "\\" << sp[0]; + file->InsertEntryString(str.str(),0x0028,0x0030); // Pixel Spacing str.str(""); str << sp[2]; - file->ReplaceOrCreateByNumber(str.str(),0x0018,0x0088); + file->InsertEntryString(str.str(),0x0018,0x0088); // Spacing Between Slices // Origin - double *org = image->GetOrigin(); + vtkFloatingPointType *org = image->GetOrigin(); + + /// \todo : Image Position Patient is meaningfull ONLY for CT an MR modality + /// We should perform some checkings before forcing the Entry creation str.str(""); str << org[0] << "\\" << org[1] << "\\" << org[2]; - file->ReplaceOrCreateByNumber(str.str(),0x0020,0x0032); + file->InsertEntryString(str.str(),0x0020,0x0032); // Image Position Patient + str.unsetf( std::ios::fixed ); //done with floating point values // Window / Level - double *rng=image->GetScalarRange(); + vtkFloatingPointType *rng = image->GetScalarRange(); str.str(""); str << rng[1]-rng[0]; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x1051); + file->InsertEntryString(str.str(),0x0028,0x1051); // Window Width str.str(""); str << (rng[1]+rng[0])/2.0; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x1050); + file->InsertEntryString(str.str(),0x0028,0x1050); // Window Center // Pixels unsigned char *data; size_t size = ReverseData(image,&data); - file->SetImageData(data,size); + file->SetUserData(data,size); } /** * Write of the files * The call to this method is recursive if there is some files to write */ -void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *image, ofstream *file) +void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *image, + ofstream *file) { if(file) { - vtkErrorMacro( << "File musn't be opened"); + vtkErrorMacro( << "File must not be open"); return; } if( image->GetScalarType() == VTK_FLOAT || image->GetScalarType() == VTK_DOUBLE ) { - vtkErrorMacro(<< "Bad input type. Scalar type musn't be of type " + vtkErrorMacro(<< "Bad input type. Scalar type must not be of type " << "VTK_FLOAT or VTKDOUBLE (found:" << image->GetScalarTypeAsString()); return; } - RecursiveWrite(axis,image,image,file); + RecursiveWrite(axis,image, image, file); //WriteDcmFile(this->FileName,image); } @@ -217,7 +261,7 @@ void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *cache, // if the file is already open then just write to it if( file ) { - vtkErrorMacro( << "File musn't be opened"); + vtkErrorMacro( << "File musn't be open"); return; } @@ -227,7 +271,7 @@ void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *cache, // determine the name if (this->FileName) { - sprintf(this->InternalFileName,"%s",this->FileName); + sprintf(this->InternalFileName, "%s", this->FileName); } else { @@ -240,6 +284,8 @@ void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *cache, { sprintf(this->InternalFileName, this->FilePattern,this->FileNumber); } +// Remove this code in case user is using VTK 4.2... +#if !(VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION == 2) if (this->FileNumber < this->MinimumFileNumber) { this->MinimumFileNumber = this->FileNumber; @@ -248,6 +294,7 @@ void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *cache, { this->MaximumFileNumber = this->FileNumber; } +#endif } // Write the file @@ -256,7 +303,7 @@ void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *cache, return; } - // if the current region is too high a dimension forthe file + // if the current region is too high a dimension for the file // the we will split the current axis cache->GetAxisUpdateExtent(axis, min, max); @@ -282,23 +329,45 @@ void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *cache, cache->SetAxisUpdateExtent(axis, min, max); } -void vtkGdcmWriter::WriteDcmFile(char *fileName,vtkImageData *image) +void vtkGdcmWriter::WriteDcmFile(char *fileName, vtkImageData *image) { // From here, the write of the file begins - gdcm::File *dcmFile = new gdcm::File(); + gdcm::FileHelper *dcmFile = gdcm::FileHelper::New(); // Set the image informations - SetImageInformation(dcmFile,image); + SetImageInformation(dcmFile, image); // Write the image + switch(this->WriteType) + { + case VTK_GDCM_WRITE_TYPE_EXPLICIT_VR : + dcmFile->SetWriteTypeToDcmExplVR(); + break; + case VTK_GDCM_WRITE_TYPE_IMPLICIT_VR : + dcmFile->SetWriteTypeToDcmImplVR(); + break; + case VTK_GDCM_WRITE_TYPE_ACR : + dcmFile->SetWriteTypeToAcr(); + break; + case VTK_GDCM_WRITE_TYPE_ACR_LIBIDO : + dcmFile->SetWriteTypeToAcrLibido(); + break; + default : + dcmFile->SetWriteTypeToDcmExplVR(); + } + if(!dcmFile->Write(fileName)) { - vtkErrorMacro( << "File " << this->FileName << "couldn't be written by " + vtkErrorMacro( << "File " << this->FileName << "cannot be written by " << " the gdcm library"); - std::cerr << "not written \n"; } - delete dcmFile; + // Clean up + if( dcmFile->GetUserData() && dcmFile->GetUserDataSize()>0 ) + { + delete[] dcmFile->GetUserData(); + } + dcmFile->Delete(); } //-----------------------------------------------------------------------------