+2003-05-12 Eric Boix <Eric.Boix@creatis.insa-lyon.fr> 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 <Eric.Boix@creatis.insa-lyon.fr> 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
SetPixelDataSizeFromHeader();
}
-
-/////////////////////////////////////////////////////////////////
/**
* \ingroup gdcmFile
* \brief calcule la longueur (in bytes) A ALLOUER pour recevoir les
*
* @return longueur a allouer
*/
-
void gdcmFile::SetPixelDataSizeFromHeader(void) {
int nb;
string str_nb;
/**
* \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
}
-/////////////////////////////////////////////////////////////////
/**
* \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);
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) {
// 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
-// $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 <stdio.h>
#include <cerrno>
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;
-// $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
int GetXSize(void);
int GetYSize(void);
int GetZSize(void);
+ int GetPixelSize(void);
string GetPixelType(void);
int Write(FILE *, FileType);
-// $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"
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();
-// $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 <stdio.h>
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();
}