X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vtk%2FvtkGdcmWriter.cxx;h=4d0168780397b00aba09bb2ca9e0d774ef05adb8;hb=refs%2Ftags%2FVersion1.0.bp;hp=e4ba6795cbf9b980e326e1844f9b664a04febb30;hpb=446ab2af0e3045cd559b086ced08a8cc5a61d2e2;p=gdcm.git diff --git a/vtk/vtkGdcmWriter.cxx b/vtk/vtkGdcmWriter.cxx index e4ba6795..4d016878 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 11:31:52 $ - Version: $Revision: 1.5 $ + Date: $Date: 2005/01/28 10:07:35 $ + Version: $Revision: 1.16 $ 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,7 +27,7 @@ #include #include -vtkCxxRevisionMacro(vtkGdcmWriter, "$Revision: 1.5 $"); +vtkCxxRevisionMacro(vtkGdcmWriter, "$Revision: 1.16 $"); vtkStandardNewMacro(vtkGdcmWriter); //----------------------------------------------------------------------------- @@ -34,6 +35,13 @@ vtkStandardNewMacro(vtkGdcmWriter); vtkGdcmWriter::vtkGdcmWriter() { this->LookupTable = NULL; + this->FileDimensionality = 3; + this->WriteType = VTK_GDCM_WRITE_TYPE_EXPLICIT_VR; + + UIDPrefix = ""; + StudyInstanceUID = ""; + SeriesInstanceUID = ""; + FrameOfReferenceInstanceUID = ""; } vtkGdcmWriter::~vtkGdcmWriter() @@ -45,10 +53,53 @@ vtkGdcmWriter::~vtkGdcmWriter() void vtkGdcmWriter::PrintSelf(ostream& os, vtkIndent 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"; + } +} + +void vtkGdcmWriter::SetUIDPrefix(const char *prefix) +{ + UIDPrefix = prefix; +} + +const char *vtkGdcmWriter::GetUIDPrefix() +{ + return UIDPrefix.c_str(); +} + +void vtkGdcmWriter::NewStudyInstanceUID() +{ + StudyInstanceUID = ""; +} + +void vtkGdcmWriter::NewSeriesInstanceUID() +{ + SeriesInstanceUID = ""; +} + +void vtkGdcmWriter::NewFrameOfReferenceInstanceUID() +{ + FrameOfReferenceInstanceUID = ""; +} //----------------------------------------------------------------------------- // Protected @@ -56,29 +107,42 @@ void vtkGdcmWriter::PrintSelf(ostream& os, vtkIndent indent) * Copy the image and reverse the Y axis */ // The output datas must be deleted by the user of the method !!! -size_t ReverseData(vtkImageData *img,unsigned char **data) +size_t ReverseData(vtkImageData *image,unsigned char **data) { - int *dim = img->GetDimensions(); - size_t lineSize = dim[0] * img->GetScalarSize() - * img->GetNumberOfScalarComponents(); + int inc[3]; + int *extent = image->GetUpdateExtent(); + int dim[3] = {extent[1]-extent[0]+1, + extent[3]-extent[2]+1, + extent[5]-extent[4]+1}; + + size_t lineSize = dim[0] * image->GetScalarSize() + * image->GetNumberOfScalarComponents(); size_t planeSize = dim[1] * lineSize; size_t size = dim[2] * planeSize; - *data = new unsigned char[size]; - - unsigned char *src = (unsigned char *)img->GetScalarPointer(); - unsigned char *dst = *data + planeSize - lineSize; - for (int plane = 0; plane < dim[2]; plane++) + if( size>0 ) { - for (int line = 0; line < dim[1]; line++) - { - // Copy one line at proper destination: - memcpy((void*)dst, (void*)src, lineSize); + *data = new unsigned char[size]; - src += lineSize; - dst -= lineSize; + 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++) + { + 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; + } + dst += 2 * planeSize; } - dst += 2 * planeSize; + } + else + { + *data = NULL; } return size; @@ -87,37 +151,41 @@ size_t ReverseData(vtkImageData *img,unsigned char **data) /** * Set the datas informations in the file */ -void SetImageInformation(gdcm::File *file,vtkImageData *image) +void SetImageInformation(gdcm::FileHelper *file,vtkImageData *image) { std::ostringstream str; // Image size - int *dim = image->GetDimensions(); + int *extent = image->GetUpdateExtent(); + int dim[3] = {extent[1]-extent[0]+1, + extent[3]-extent[2]+1, + extent[5]-extent[4]+1}; str.str(""); str << dim[0]; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0011); + file->InsertValEntry(str.str(),0x0028,0x0011); // Columns str.str(""); str << dim[1]; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0010); + file->InsertValEntry(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->InsertValEntry(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->InsertValEntry(str.str(),0x0028,0x0100); // Bits Allocated + file->InsertValEntry(str.str(),0x0028,0x0101); // Bits Stored str.str(""); str << image->GetScalarSize()*8-1; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0102); + file->InsertValEntry(str.str(),0x0028,0x0102); // High Bit // Pixel Repr // FIXME : what do we do when the ScalarType is @@ -134,44 +202,44 @@ void SetImageInformation(gdcm::File *file,vtkImageData *image) { str << "1"; // Signed } - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0103); + file->InsertValEntry(str.str(),0x0028,0x0103); // Pixel Representation // Samples per pixel str.str(""); str << image->GetNumberOfScalarComponents(); - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0002); + file->InsertValEntry(str.str(),0x0028,0x0002); // Samples per Pixel // Spacing double *sp = image->GetSpacing(); str.str(""); str << sp[0] << "\\" << sp[1]; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0030); + file->InsertValEntry(str.str(),0x0028,0x0030); // Pixel Spacing str.str(""); str << sp[2]; - file->ReplaceOrCreateByNumber(str.str(),0x0018,0x0088); + file->InsertValEntry(str.str(),0x0018,0x0088); // Spacing Between Slices // Origin double *org = image->GetOrigin(); str.str(""); str << org[0] << "\\" << org[1] << "\\" << org[2]; - file->ReplaceOrCreateByNumber(str.str(),0x0020,0x0032); + file->InsertValEntry(str.str(),0x0020,0x0032); // Image Position Patient // Window / Level double *rng=image->GetScalarRange(); str.str(""); str << rng[1]-rng[0]; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x1051); + file->InsertValEntry(str.str(),0x0028,0x1051); // Window Width str.str(""); str << (rng[1]+rng[0])/2.0; - file->ReplaceOrCreateByNumber(str.str(),0x0028,0x1050); + file->InsertValEntry(str.str(),0x0028,0x1050); // Window Center // Pixels unsigned char *data; size_t size = ReverseData(image,&data); - file->SetImageData(data,size); + file->SetUserData(data,size); } /** @@ -180,7 +248,6 @@ void SetImageInformation(gdcm::File *file,vtkImageData *image) */ void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *image, ofstream *file) { - (void)axis; // To avoid warning if(file) { vtkErrorMacro( << "File musn't be opened"); @@ -196,34 +263,136 @@ void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *image, ofstream *file return; } - WriteDcmFile(this->FileName,image); + RecursiveWrite(axis,image,image,file); + //WriteDcmFile(this->FileName,image); } -void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *image, - vtkImageData *cache, ofstream *file) +void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *cache, + vtkImageData *image, ofstream *file) { - (void)axis; // To avoid warning - (void)image; // To avoid warning - (void)cache; // To avoid warning - (void)file; // To avoid warning + int idx, min, max; + + // if the file is already open then just write to it + if( file ) + { + vtkErrorMacro( << "File musn't be opened"); + return; + } + + // if we need to open another slice, do it + if( (axis + 1) == this->FileDimensionality ) + { + // determine the name + if (this->FileName) + { + sprintf(this->InternalFileName,"%s",this->FileName); + } + else + { + if (this->FilePrefix) + { + sprintf(this->InternalFileName, this->FilePattern, + this->FilePrefix, this->FileNumber); + } + else + { + sprintf(this->InternalFileName, this->FilePattern,this->FileNumber); + } + if (this->FileNumber < this->MinimumFileNumber) + { + this->MinimumFileNumber = this->FileNumber; + } + else if (this->FileNumber > this->MaximumFileNumber) + { + this->MaximumFileNumber = this->FileNumber; + } + } + + // Write the file + WriteDcmFile(this->InternalFileName,image); + ++this->FileNumber; + return; + } + + // if the current region is too high a dimension forthe file + // the we will split the current axis + cache->GetAxisUpdateExtent(axis, min, max); + + // if it is the y axis then flip by default + if (axis == 1 && !this->FileLowerLeft) + { + for(idx = max; idx >= min; idx--) + { + cache->SetAxisUpdateExtent(axis, idx, idx); + this->RecursiveWrite(axis - 1, cache, image, file); + } + } + else + { + for(idx = min; idx <= max; idx++) + { + cache->SetAxisUpdateExtent(axis, idx, idx); + this->RecursiveWrite(axis - 1, cache, image, file); + } + } + + // restore original extent + cache->SetAxisUpdateExtent(axis, min, max); } void vtkGdcmWriter::WriteDcmFile(char *fileName,vtkImageData *image) { // From here, the write of the file begins - gdcm::File *dcmFile = new gdcm::File(); + gdcm::FileHelper *dcmFile = new gdcm::FileHelper(); + + // Set the image UID + if( StudyInstanceUID.empty() ) + StudyInstanceUID = gdcm::Util::CreateUniqueUID( UIDPrefix ); + if( SeriesInstanceUID.empty() ) + SeriesInstanceUID = gdcm::Util::CreateUniqueUID( UIDPrefix ); + if( FrameOfReferenceInstanceUID.empty() ) + FrameOfReferenceInstanceUID = gdcm::Util::CreateUniqueUID( UIDPrefix ); + std::string uid = gdcm::Util::CreateUniqueUID( UIDPrefix ); + + dcmFile->InsertValEntry(uid,0x0008,0x0018); //[SOP Instance UID] + dcmFile->InsertValEntry(uid,0x0002,0x0003); //[Media Stored SOP Instance UID] + dcmFile->InsertValEntry(StudyInstanceUID,0x0020,0x000d); //[Study Instance UID] + dcmFile->InsertValEntry(SeriesInstanceUID,0x0020,0x000e); //[Series Instance UID] + dcmFile->InsertValEntry(FrameOfReferenceInstanceUID,0x0020, 0x0052); //[Frame of Reference UID] // Set the image informations 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 " << " the gdcm library"); - std::cerr << "not written \n"; } + // Clean up + if( dcmFile->GetUserData() && dcmFile->GetUserDataSize()>0 ) + { + delete[] dcmFile->GetUserData(); + } delete dcmFile; }