From: frog Date: Mon, 12 May 2003 14:32:42 +0000 (+0000) Subject: * src/gdcmHeader>[h/cxx] added gdcmHeader::GetPixelSize() X-Git-Tag: Version0.3~48 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=6cf458fe8d13f8b577a62802650afc6f67c720a0;p=gdcm.git * src/gdcmHeader>[h/cxx] added gdcmHeader::GetPixelSize() * vtk/vtkGdcmReader.cxx now properly inports the image in the vtk data structure (an image Flip was required). * vtk/testvtkGdcmReader.cxx refers to gdcmData subdir instead of Data. * cosmetic changes in documentation. --- diff --git a/ChangeLog b/ChangeLog index daa8a82a..31c758d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,17 @@ +2003-05-12 Eric Boix with JPR + * src/gdcmHeader>[h/cxx] added gdcmHeader::GetPixelSize() + * vtk/vtkGdcmReader.cxx now properly inports the image in the + vtk data structure (an image Flip was required). + * vtk/testvtkGdcmReader.cxx refers to gdcmData subdir instead of Data. + * cosmetic changes in documentation. + 2003-05-7 Eric Boix with JPR * src/gdcmHeader.cxx: the constructor no longer exits when an unexisting file is given as argument. * The subdirectory Data (containing all the images used for the test suite) is not part of this repository anymore. A new module containing those images is now available at - :pserver:frog@cvs.creatis.insa-lyon.fr:2402/cvs/public + :pserver:xxx@cvs.creatis.insa-lyon.fr:2402/cvs/public with the name gdcmData. All the python scripts (including the package initialisation file gdcmPython/__init__.py) were adapated to take this change into diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index 0284a5c2..ae734628 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -34,8 +34,6 @@ gdcmFile::gdcmFile(const char * filename) SetPixelDataSizeFromHeader(); } - -///////////////////////////////////////////////////////////////// /** * \ingroup gdcmFile * \brief calcule la longueur (in bytes) A ALLOUER pour recevoir les @@ -46,7 +44,6 @@ gdcmFile::gdcmFile(const char * filename) * * @return longueur a allouer */ - void gdcmFile::SetPixelDataSizeFromHeader(void) { int nb; string str_nb; @@ -63,13 +60,14 @@ void gdcmFile::SetPixelDataSizeFromHeader(void) { /** * \ingroup gdcmFile - * \brief Accessor + * \brief Returns the size (in bytes) of required memory to hold + * the pixel data represented in this file. + * @return The size of pixel data in bytes. */ size_t gdcmFile::GetImageDataSize(void) { return (lgrTotale); } - /** * \ingroup gdcmFile * \brief Read pixel data from disk (optionaly decompressing) into the @@ -135,12 +133,11 @@ bool gdcmFile::ReadPixelData(void* destination) { } -///////////////////////////////////////////////////////////////// /** * \ingroup gdcmFile * \brief Allocates necessary memory, copies the pixel data - * (image[s]/volume[s]) to newly allocated zone and return a - * pointer to it: + * (image[s]/volume[s]) to newly allocated zone. + * @return Pointer to newly allocated pixel data. */ void * gdcmFile::GetImageData (void) { PixelData = (void *) malloc(lgrTotale); @@ -148,16 +145,17 @@ void * gdcmFile::GetImageData (void) { return(PixelData); } -///////////////////////////////////////////////////////////////// /** - * \ingroup gdcmFile - * \brief amene en mémoire dans une zone précisee par l'utilisateur - * les Pixels d'une image - * - * @param destination - * @param MaxSize - * - * @return The number of bytes actually copied. + * \ingroup gdcmFile + * \brief Copies at most MaxSize bytes of pixel data to caller's + * memory space. + * @param destination Address (in caller's memory space) at which the + * pixel data should be copied + * @param MaxSize Maximum number of bytes to be copied. When MaxSize + * is not sufficient to hold the pixel data the copy is not + * executed (i.e. no partial copy). + * @return On success, the number of bytes actually copied. Zero on + * failure e.g. MaxSize is lower than necessary. */ size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) { diff --git a/src/gdcmFile.h b/src/gdcmFile.h index b8158760..89d038ee 100644 --- a/src/gdcmFile.h +++ b/src/gdcmFile.h @@ -35,17 +35,9 @@ public: // from the constructor's one (no overwriting allowed). // TODO Swig int SetFileName(string filename); - void SetPixelDataSizeFromHeader(void); - // Returns size (in bytes) of required memory to contain data - // represented in this file. + void SetPixelDataSizeFromHeader(void); size_t GetImageDataSize(); - - // Allocates necessary memory, copies the data (image[s]/volume[s]) to - // newly allocated zone and return a pointer to it: - void * GetImageData(); - - // Copies (at most MaxSize bytes) of data to caller's memory space. - // Returns an error code on failure (if MaxSize is not big enough) + void * GetImageData(); size_t GetImageDataIntoVector(void* destination, size_t MaxSize ); // Allocates ExpectedSize bytes of memory at this->Data and copies the diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index 4ec3a790..002aed72 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -1,4 +1,4 @@ -// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.64 2003/05/07 12:49:10 frog Exp $ +// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.65 2003/05/12 14:32:43 frog Exp $ #include #include @@ -1440,18 +1440,36 @@ int gdcmHeader::GetZSize(void) { return 1; } +/** + * \ingroup gdcmHeader + * \brief Return the size (in bytes) of a single pixel of data. + * @return The size in bytes of a single pixel of data. + * + */ +int gdcmHeader::GetPixelSize(void) { + string PixelType = GetPixelType(); + if (PixelType == "8U" || PixelType == "8S") + return 1; + if (PixelType == "16U" || PixelType == "16S") + return 2; + if (PixelType == "32U" || PixelType == "32S") + return 4; + dbg.Verbose(0, "gdcmHeader::GetPixelSize: Unknown pixel type"); + return 0; +} + /** * \ingroup gdcmHeader * \brief Build the Pixel Type of the image. * Possible values are: - * - U8 unsigned 8 bit, - * - S8 signed 8 bit, - * - U16 unsigned 16 bit, - * - S16 signed 16 bit, - * - U32 unsigned 32 bit, - * - S32 signed 32 bit, + * - 8U unsigned 8 bit, + * - 8S signed 8 bit, + * - 16U unsigned 16 bit, + * - 16S signed 16 bit, + * - 32U unsigned 32 bit, + * - 32S signed 32 bit, * \warning 12 bit images appear as 16 bit. - * @return + * @return */ string gdcmHeader::GetPixelType(void) { string BitsAlloc; diff --git a/src/gdcmHeader.h b/src/gdcmHeader.h index 3ccf8cf4..ae885cf8 100644 --- a/src/gdcmHeader.h +++ b/src/gdcmHeader.h @@ -1,4 +1,4 @@ -// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.h,v 1.22 2003/05/06 15:52:13 jpr Exp $ +// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.h,v 1.23 2003/05/12 14:32:43 frog Exp $ #ifndef GDCMHEADER_H #define GDCMHEADER_H @@ -165,6 +165,7 @@ public: int GetXSize(void); int GetYSize(void); int GetZSize(void); + int GetPixelSize(void); string GetPixelType(void); int Write(FILE *, FileType); diff --git a/vtk/testvtkGdcmReader.cxx b/vtk/testvtkGdcmReader.cxx index 47a9ae88..6fc520b1 100644 --- a/vtk/testvtkGdcmReader.cxx +++ b/vtk/testvtkGdcmReader.cxx @@ -1,4 +1,4 @@ -// $Header: /cvs/public/gdcm/vtk/Attic/testvtkGdcmReader.cxx,v 1.1 2003/05/05 14:13:59 frog Exp $ +// $Header: /cvs/public/gdcm/vtk/Attic/testvtkGdcmReader.cxx,v 1.2 2003/05/12 14:32:43 frog Exp $ #include "vtkRenderer.h" #include "vtkRenderWindow.h" @@ -33,18 +33,18 @@ int main( int argc, char *argv[] ) reader->DebugOn(); // Alloc Used High // 8 8 7 U : OK - // reader->SetFileName("../Data/CT-MONO2-8-abdo.dcm"); + // reader->SetFileName("../gdcmData/CT-MONO2-8-abdo.dcm"); // 16 12 11 U : OK but saturated - // reader->SetFileName("../Data/CT-MONO2-12-lomb-an2.acr2"); + // reader->SetFileName("../gdcmData/CT-MONO2-12-lomb-an2.acr2"); // 16 12 11 U OK - //OKreader->SetFileName("../Data/MR-MONO2-12-an2.acr2"); + //OKreader->SetFileName("../gdcmData/MR-MONO2-12-an2.acr2"); // 16 10 9 U OK - //reader->SetFileName("../Data/CR-MONO1-10-chest.dcm"); + //reader->SetFileName("../gdcmData/CR-MONO1-10-chest.dcm"); //reader->Update(); // 16 16 15 S: OK saturation ? - // reader->SetFileName("../Data/CT-MONO2-16-ort.dcm"); + // reader->SetFileName("../gdcmData/CT-MONO2-16-ort.dcm"); // 16 16 15 S: - reader->SetFileName("../Data/CT-MONO2-16-ankle.dcm"); + reader->SetFileName("../gdcmData/CT-MONO2-16-ankle.dcm"); reader->UpdateWholeExtent(); vtkImageData *ima = reader->GetOutput(); taille=ima->GetDimensions(); diff --git a/vtk/vtkGdcmReader.cxx b/vtk/vtkGdcmReader.cxx index eaba22fe..6f438ec7 100644 --- a/vtk/vtkGdcmReader.cxx +++ b/vtk/vtkGdcmReader.cxx @@ -1,4 +1,4 @@ -// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.1 2003/05/05 14:13:59 frog Exp $ +// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.2 2003/05/12 14:32:43 frog Exp $ #include "vtkGdcmReader.h" #include "vtkByteSwap.h" #include @@ -159,27 +159,39 @@ void vtkGdcmReader::ExecuteData(vtkDataObject *output) data->SetExtent(this->DataExtent); data->GetPointData()->GetScalars()->SetName("ImageFile"); - int size = - (this->DataExtent[1] - this->DataExtent[0]+1) * - (this->DataExtent[3] - this->DataExtent[2]+1) * - (this->DataExtent[5] - this->DataExtent[4]+1) * - 2; + // First check the coherence between the DataExtent and the + // size of the pixel data as annouced by gdcm (looks a bit paranoid). gdcmFile GdcmFile(this->InternalFileName); - size = GdcmFile.GetImageDataSize(); - unsigned char *mem = new unsigned char [size]; + int NumColumns = this->DataExtent[1] - this->DataExtent[0] + 1; + int NumLines = this->DataExtent[3] - this->DataExtent[2] + 1; + int NumPlanes = this->DataExtent[5] - this->DataExtent[4] + 1; + int size = NumColumns * NumLines * NumPlanes * GdcmFile.GetPixelSize(); if ( size != GdcmFile.GetImageDataSize() ) { vtkDebugMacro("Inconsistency with GetImageDataSize"); vtkDebugMacro("Number of scalar components" << this->NumberOfScalarComponents); } - GdcmFile.GetImageDataIntoVector((void*)mem, size); + // Allocate pixel data space itself. + unsigned char *mem = new unsigned char [size]; + + // If the data structure of vtk for image/volume representation + // were straigthforwards the following would suffice: + // GdcmFile.GetImageDataIntoVector((void*)mem, size); + // But vtk chose to invert the lines of an image, that is the last + // line comes first (for some axis related reasons?). Hence we need + // to load the image line by line, starting from the end: + int LineSize = NumColumns * GdcmFile.GetPixelSize(); + unsigned char * Source = (unsigned char*)GdcmFile.GetImageData(); + unsigned char * Destination = mem + size - LineSize; + for (int i = 0; i < NumLines; i++) + { + memcpy((void*)Destination, (void*)Source, LineSize); + Source += LineSize; + Destination -= LineSize; + } + data->GetPointData()->GetScalars()->SetVoidArray(mem, size, 0); - //vtkImageFlip * Flip = vtkImageFlip::New(); - //Flip->SetInput(data); - //Flip->Update(); - //data = Flip->GetOutput(); - //Flip->SetInput(NULL); this->Modified(); }