From: frog Date: Mon, 5 May 2003 14:13:58 +0000 (+0000) Subject: * vtk subdir added. Contains vtkGdcmReader.[cxx|h] a vtk class X-Git-Tag: Version0.3~54 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=90a2b8eeadb9d5afb2bc165b080f8a4622f5deb4;p=gdcm.git * vtk subdir added. Contains vtkGdcmReader.[cxx|h] a vtk class inherinting from vtkImageReader and testvtkGdcmReader.cxx a small demo of the usage of this class. Compilation of this vtk part is only done when using the --enable-vtk at configure (or autogen.sh) stage. --- diff --git a/ChangeLog b/ChangeLog index c7ea5813..9deeb367 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2003-05-5 Eric Boix with JPR + * vtk subdir added. Contains vtkGdcmReader.[cxx|h] a vtk class + inherinting from vtkImageReader and testvtkGdcmReader.cxx a small + demo of the usage of this class. + Compilation of this vtk part is only done when using the --enable-vtk + at configure (or autogen.sh) stage. + 2003-04-16 Eric Boix with JPR * More memmory link related corrections and documentation fixes. Notes on valgrind: diff --git a/Doc/DoxyInstallation.txt b/Doc/DoxyInstallation.txt index 5e90abe8..3ba3baca 100644 --- a/Doc/DoxyInstallation.txt +++ b/Doc/DoxyInstallation.txt @@ -34,12 +34,12 @@ * -# ./autogen.sh --prefix=/where/ever/you/want * to configure the script to force installation in a specified * place. - * -# ./autogen.sh --configure-python to generate the + * -# ./autogen.sh --enable-python to generate the * python wrappers. * . * - make (or make 'CFLAGS=-g...) * - make instal - * - As usual, you can optionnaly: + * - As usual, you can optionnally: * -# make clean * -# make 'CFLAGS=' if you are in hurry and want to omit * "-g -O2" default flags diff --git a/INSTALL b/INSTALL index 2df82685..ecae1fa7 100644 --- a/INSTALL +++ b/INSTALL @@ -3,7 +3,7 @@ ./autogen.sh ./configure (optional if just after autogen.sh) make -make install +make instal You can use the --prefix option of the configure script to force installation in some place (default is /usr/local/DCMlib): diff --git a/Makefile.am b/Makefile.am index ea35b220..aa38126c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = src gdcmPython Test Dicts Doc +SUBDIRS = src gdcmPython Test Dicts Doc vtk EXTRA_DIST = \ diff --git a/configure.in b/configure.in index df3c7c79..cac0e468 100644 --- a/configure.in +++ b/configure.in @@ -54,7 +54,7 @@ AM_CONDITIONAL(ENABLE_DOXYGEN, test x$enable_doxygen = xyes) dnl Checks for Python AC_ARG_ENABLE(python, - [ --enable-python Enable Python language support (default=no).],, + [ --enable-python Enable Python language support (default=no).],, [enable_python="no"]) dnl AC_MSG_RESULT($enable_python) build_python=no @@ -68,6 +68,12 @@ if test "yes" = "$enable_python"; then fi AM_CONDITIONAL(BUILD_PYTHON, test x$build_python = xyes) +dnl Checks for vtk +AC_ARG_ENABLE(vtk, + [ --enable-vtk Enable vtk extensions support (default=no).],, + [enable_vtk="no"]) +AM_CONDITIONAL(BUILD_VTK, test x$enable_vtk = xyes) + dnl produce Makefile.in files AC_OUTPUT([ Makefile @@ -76,4 +82,5 @@ src/Makefile gdcmPython/Makefile Test/Makefile Dicts/Makefile +vtk/Makefile Doc/Makefile]) diff --git a/src/gdcmDict.h b/src/gdcmDict.h index 5e56f335..77d837c9 100644 --- a/src/gdcmDict.h +++ b/src/gdcmDict.h @@ -1,8 +1,4 @@ -//////////////////////////////////////////////////////////////////////////// -// A single DICOM dictionary i.e. a container for a collection of dictionary -// entries. There should be a single public dictionary (THE dictionary of -// the actual DICOM v3) but as many shadow dictionaries as imagers -// combined with all software versions... +// gdcmDict.h #ifndef GDCMDICT_H #define GDCMDICT_H @@ -14,8 +10,16 @@ typedef map TagKeyHT; typedef map TagNameHT; -/// Build a memory representation of a dicom dictionary by parsing -/// an ascii file +/* + * \defgroup gdcmDict + * \brief gdcmDict acts a memory representation of a dicom dictionary i.e. + * it is a container for a collection of dictionary entries. The + * dictionary is loaded from in an ascii file. + * There should be a single public dictionary (THE dictionary of + * the actual DICOM v3) but as many shadow dictionaries as imagers + * combined with all software versions... + * \see gdcmDictSet + */ class GDCM_EXPORT gdcmDict { string name; string filename; diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index a8c62405..631b038d 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -1,4 +1,4 @@ -// gdcmHeader.cxx +// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.61 2003/05/05 14:13:59 frog Exp $ #include #include diff --git a/src/gdcmHeader.h b/src/gdcmHeader.h index 2fc8e8c4..3373b99a 100644 --- a/src/gdcmHeader.h +++ b/src/gdcmHeader.h @@ -1,4 +1,4 @@ -// gdcmHeader.h +// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.h,v 1.21 2003/05/05 14:13:59 frog Exp $ #ifndef GDCMHEADER_H #define GDCMHEADER_H diff --git a/vtk/.cvsignore b/vtk/.cvsignore new file mode 100644 index 00000000..e8b184e8 --- /dev/null +++ b/vtk/.cvsignore @@ -0,0 +1,5 @@ +.deps +.libs +Makefile.in +Makefile +vtkgdcmdemo diff --git a/vtk/Makefile.am b/vtk/Makefile.am new file mode 100644 index 00000000..38c18fc8 --- /dev/null +++ b/vtk/Makefile.am @@ -0,0 +1,30 @@ +## Process this file with automake to produce Makefile.in +LIBS_VTK=-L/usr/lib/vtk \ + -lvtkCommon -lvtkIO -lvtkFiltering -lvtkRendering -lvtkGraphics \ + -lvtkImaging -lvtkpng -lvtkzlib -lvtkjpeg -lvtkexpat -lvtktiff \ + -lvtkftgl -lvtkfreetype +INCLUDE_VTK=-I/usr/include/vtk + +LIBS_X11= -L/usr/X11R6/lib -lX11 -lXt -lSM -lICE -lXext -lGL +## $(x_ldflags) +## $(x_libs) + +INCLUDES = \ + -I. \ + -I$(top_srcdir)/src \ + $(INCLUDE_VTK) + +LDADD = \ + $(top_builddir)/src/libgdcm.la \ + $(LIBS_VTK) \ + $(LIBS_X11) + +if BUILD_VTK +noinst_PROGRAMS = vtkgdcmdemo +vtkgdcmdemo_SOURCES = testvtkGdcmReader.cxx vtkGdcmReader.cxx + +else +all: +endif + + diff --git a/vtk/testvtkGdcmReader.cxx b/vtk/testvtkGdcmReader.cxx new file mode 100644 index 00000000..47a9ae88 --- /dev/null +++ b/vtk/testvtkGdcmReader.cxx @@ -0,0 +1,93 @@ +// $Header: /cvs/public/gdcm/vtk/Attic/testvtkGdcmReader.cxx,v 1.1 2003/05/05 14:13:59 frog Exp $ + +#include "vtkRenderer.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkPolyDataMapper.h" +#include "vtkActor.h" +#include "vtkImageMapper.h" +#include "vtkImageViewer.h" +#include "vtkMatrix4x4.h" +#include "vtkLookupTable.h" +#include "vtkMatrixToLinearTransform.h" +#include "vtkTexture.h" +#include "vtkPlaneSource.h" +#include "vtkTextureMapToPlane.h" +#include "vtkDataSetMapper.h" +#include "vtkActor.h" +#include "vtkImageCast.h" +#include "vtkPNGWriter.h" +#include "vtkTexture.h" + +#include "vtkGdcmReader.h" + + +int main( int argc, char *argv[] ) +{ + char a; + int *taille; + int x,y; + + // Lecture de l'image + vtkGdcmReader *reader = vtkGdcmReader::New(); + reader->DebugOn(); + // Alloc Used High + // 8 8 7 U : OK + // reader->SetFileName("../Data/CT-MONO2-8-abdo.dcm"); + // 16 12 11 U : OK but saturated + // reader->SetFileName("../Data/CT-MONO2-12-lomb-an2.acr2"); + // 16 12 11 U OK + //OKreader->SetFileName("../Data/MR-MONO2-12-an2.acr2"); + // 16 10 9 U OK + //reader->SetFileName("../Data/CR-MONO1-10-chest.dcm"); + //reader->Update(); + // 16 16 15 S: OK saturation ? + // reader->SetFileName("../Data/CT-MONO2-16-ort.dcm"); + // 16 16 15 S: + reader->SetFileName("../Data/CT-MONO2-16-ankle.dcm"); + reader->UpdateWholeExtent(); + vtkImageData *ima = reader->GetOutput(); + taille=ima->GetDimensions(); + x = taille[0]; y = taille[1]; + cout << "Taille de l'image en X=" << x << " et en Y=" << y << endl; + + vtkLookupTable *VTKtable = vtkLookupTable::New(); + VTKtable->SetNumberOfColors(1000); + VTKtable->SetTableRange(0,1000); + VTKtable->SetSaturationRange(0,0); + VTKtable->SetHueRange(0,1); + VTKtable->SetValueRange(0,1); + VTKtable->SetAlphaRange(1,1); + VTKtable->Build(); + // Texture + vtkTexture * VTKtexture = vtkTexture::New(); + VTKtexture->SetInput(ima); + VTKtexture->InterpolateOn(); + VTKtexture->SetLookupTable(VTKtable); + // PlaneSource + vtkPlaneSource *VTKplane = vtkPlaneSource::New(); + VTKplane->SetOrigin( -0.5, -0.5, 0.0); + VTKplane->SetPoint1( 0.5, -0.5, 0.0); + VTKplane->SetPoint2( -0.5, 0.5, 0.0); + // PolyDataMapper + vtkPolyDataMapper *VTKplaneMapper = vtkPolyDataMapper::New(); + VTKplaneMapper->SetInput(VTKplane->GetOutput()); + // Actor + vtkActor* VTKplaneActor = vtkActor::New(); + VTKplaneActor->SetTexture(VTKtexture); + VTKplaneActor->SetMapper(VTKplaneMapper); + VTKplaneActor->PickableOn(); + // + vtkRenderer *ren = vtkRenderer::New(); + vtkRenderWindow *renwin = vtkRenderWindow::New(); + renwin->AddRenderer(ren); + vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); + iren->SetRenderWindow(renwin); + ren->AddActor(VTKplaneActor); + ren->SetBackground(0,0,0.5); + renwin->Render(); + iren->Start(); + + return(0); +} + diff --git a/vtk/vtkGdcmReader.cxx b/vtk/vtkGdcmReader.cxx new file mode 100644 index 00000000..eaba22fe --- /dev/null +++ b/vtk/vtkGdcmReader.cxx @@ -0,0 +1,191 @@ +// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.1 2003/05/05 14:13:59 frog Exp $ +#include "vtkGdcmReader.h" +#include "vtkByteSwap.h" +#include +#include "vtkObjectFactory.h" +#include "vtkImageFlip.h" +#include "gdcm.h" + +vtkGdcmReader::vtkGdcmReader() +{ + // Constructor +} + +//---------------------------------------------------------------------------- +vtkGdcmReader::~vtkGdcmReader() +{ + // FIXME free memory +} + +// Configure the output e.g. WholeExtent, spacing, origin, scalar type... +void vtkGdcmReader::ExecuteInformation() +{ + //FIXME free any old memory + + // if the user has not set the extent, but has set the VOI + // set the zaxis extent to the VOI z axis + if (this->DataExtent[4]==0 && this->DataExtent[5] == 0 && + (this->DataVOI[4] || this->DataVOI[5])) + { + this->DataExtent[4] = this->DataVOI[4]; + this->DataExtent[5] = this->DataVOI[5]; + } + + this->ComputeInternalFileName(this->DataExtent[4]); + + // Check for file existence. + FILE *fp; + fp = fopen(this->InternalFileName,"rb"); + if (!fp) + { + vtkErrorMacro("Unable to open file " << this->InternalFileName); + return; + } + fclose(fp); + + // Check for Gdcm parsability + gdcmHeader GdcmHeader(this->InternalFileName); + if (!GdcmHeader.IsReadable()) + { + vtkErrorMacro("Gdcm cannot parse file " << this->InternalFileName); + return; + } + + int NX = GdcmHeader.GetXSize(); + int NY = GdcmHeader.GetYSize(); + int NZ = GdcmHeader.GetZSize(); + vtkDebugMacro("Image dimension as read from Gdcm:" << + NX << " " << NY << " " << NZ); + + if(NZ>1) this->SetFileDimensionality(3); + + // When the user has set the VOI, check it's coherence with the file content. + if (this->DataVOI[0] || this->DataVOI[1] || + this->DataVOI[2] || this->DataVOI[3] || + this->DataVOI[4] || this->DataVOI[5]) + { + if ((this->DataVOI[0] < 0) || + (this->DataVOI[1] >= NX) || + (this->DataVOI[2] < 0) || + (this->DataVOI[3] >= NY) || + (this->DataVOI[4] < 0) || + (this->DataVOI[5] >= NZ)) + { + vtkWarningMacro("The requested VOI is larger than the file's (" + << this->InternalFileName << ") extent "); + this->DataVOI[0] = 0; + this->DataVOI[1] = NX - 1; + this->DataVOI[2] = 0; + this->DataVOI[3] = NY - 1; + this->DataVOI[4] = 0; + this->DataVOI[5] = NZ - 1; + } + } + + // Positionate the Extent. + this->DataExtent[0] = 0; + this->DataExtent[1] = NX - 1; + this->DataExtent[2] = 0; + this->DataExtent[3] = NY - 1; + if(this->GetFileDimensionality()==3) + { + this->DataExtent[4] = 0; + this->DataExtent[5] = NZ - 1; + } + + // We don't need to positionate the Endian related stuff (by using + // this->SetDataByteOrderToBigEndian() or SetDataByteOrderToLittleEndian() + // since the // reading of the file is done by gdcm + + // But we need to set up the data type for downstream filters: + string type = GdcmHeader.GetPixelType(); + if ( type == "8U" ) + { + vtkDebugMacro("8 bits unsigned image"); + this->SetDataScalarTypeToUnsignedChar(); + } + else if ( type == "8S" ) + { + vtkErrorMacro("Cannot handle 8 bit signed files"); + return; + } + else if ( type == "16U" ) + { + vtkDebugMacro("16 bits unsigned image"); + this->SetDataScalarTypeToUnsignedShort(); + } + else if ( type == "16S" ) + { + vtkDebugMacro("16 bits signed image"); + this->SetDataScalarTypeToShort(); + //vtkErrorMacro("Cannot handle 16 bit signed files"); + } + else if ( type == "32U" ) + { + vtkDebugMacro("32 bits unsigned image"); + vtkDebugMacro("WARNING: forced to signed int !"); + this->SetDataScalarTypeToInt(); + } + else if ( type == "32S" ) + { + vtkDebugMacro("32 bits signed image"); + this->SetDataScalarTypeToInt(); + } + else + { + vtkErrorMacro("Bad File Type " << this->InternalFileName + << "Type " << type); + return; + } + + vtkImageReader::ExecuteInformation(); +} + +// Update -> UpdateData -> Execute -> ExecuteData (see vtkSource.cxx for +// last step. +// This function (redefinition of vtkImageReader::ExecuteData, see +// VTK/IO/vtkImageReader.cxx) reads a data from a file. The datas +// extent/axes are assumed to be the +// same as the file extent/order. +void vtkGdcmReader::ExecuteData(vtkDataObject *output) +{ + if (!this->FileName) + { + vtkErrorMacro("A valid FileName must be specified."); + return; + } + + vtkImageData *data = this->AllocateOutputData(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; + gdcmFile GdcmFile(this->InternalFileName); + size = GdcmFile.GetImageDataSize(); + unsigned char *mem = new unsigned char [size]; + if ( size != GdcmFile.GetImageDataSize() ) + { + vtkDebugMacro("Inconsistency with GetImageDataSize"); + vtkDebugMacro("Number of scalar components" + << this->NumberOfScalarComponents); + } + GdcmFile.GetImageDataIntoVector((void*)mem, size); + data->GetPointData()->GetScalars()->SetVoidArray(mem, size, 0); + //vtkImageFlip * Flip = vtkImageFlip::New(); + //Flip->SetInput(data); + //Flip->Update(); + //data = Flip->GetOutput(); + //Flip->SetInput(NULL); + this->Modified(); + +} + +void vtkGdcmReader::PrintSelf(ostream& os, vtkIndent indent) +{ + vtkImageReader::PrintSelf(os,indent); + //CLEANME os << indent << "TypeSize: " << this->TypeSize << "\n"; +} diff --git a/vtk/vtkGdcmReader.h b/vtk/vtkGdcmReader.h new file mode 100644 index 00000000..20eb484a --- /dev/null +++ b/vtk/vtkGdcmReader.h @@ -0,0 +1,21 @@ +// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.h,v 1.1 2003/05/05 14:13:59 frog Exp $ + +#ifndef __vtkGdcmReader_h +#define __vtkGdcmReader_h + +#include "vtkImageReader.h" + +class VTK_EXPORT vtkGdcmReader : public vtkImageReader +{ +public: + static vtkGdcmReader *New() {return new vtkGdcmReader;}; + vtkTypeMacro(vtkGdcmReader, vtkImageReader); + void PrintSelf(ostream& os, vtkIndent indent); +protected: + vtkGdcmReader(); + ~vtkGdcmReader(); + void ExecuteData(vtkDataObject *output); + virtual void ExecuteInformation(); +}; +#endif +