From 5fbee0c35cc0f02ceea5d5a8be0c1900c63143bb Mon Sep 17 00:00:00 2001 From: frog Date: Mon, 7 Jul 2003 17:05:12 +0000 Subject: [PATCH] * src/gdcmElValSet.cxx, gdcmFile.cxx: JPR bug fix, removal of garbage debug code. * TODO, vtk/vtkGdcmReader.cxx: upcoming fixes comments. * gdcmPython/testSuite.py: JPR bug fix, brutal erasement of test suite reported error. * PACKAGER file added (describes what a packager must do when packaging a new release). * MANIFEST.in, now declares jconfig.linux and jconfig.vc * configure.in: upgraded version number to 0.3.0 * fixing build of rpm (through rpm -ta): - Doc/Makefile.am exports proper doxygen files - src/jpeg/libijg8/Makefile.am exports the include files. --- Frog --- ChangeLog | 14 +++++++ Doc/Makefile.am | 9 ++++- MANIFEST.in | 2 + PACKAGER | 75 ++++++++++++++++++++++++++++++++++++ TODO | 16 ++++++-- configure.in | 2 +- gdcmPython/__init__.py | 5 ++- gdcmPython/testSuite.py | 9 ++++- src/config.h | 2 +- src/gdcmElValSet.cxx | 8 ---- src/gdcmFile.cxx | 12 ------ src/jpeg/libijg8/Makefile.am | 30 ++++++++------- vtk/.cvsignore | 1 + vtk/vtkGdcmReader.cxx | 52 ++++++++++++++++++++++--- 14 files changed, 188 insertions(+), 49 deletions(-) create mode 100644 PACKAGER diff --git a/ChangeLog b/ChangeLog index bbcb6daa..9e190088 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2003-07-07 Eric Boix + * src/gdcmElValSet.cxx, gdcmFile.cxx: JPR bug fix, removal of + garbage debug code. + * TODO, vtk/vtkGdcmReader.cxx: upcoming fixes comments. + * gdcmPython/testSuite.py: JPR bug fix, brutal erasement of + test suite reported error. + * PACKAGER file added (describes what a packager must do when + packaging a new release). + * MANIFEST.in, now declares jconfig.linux and jconfig.vc + * configure.in: upgraded version number to 0.3.0 + * fixing build of rpm (through rpm -ta): + - Doc/Makefile.am exports proper doxygen files + - src/jpeg/libijg8/Makefile.am exports the include files. + 2003-07-07 Benoit Regrain * vtk/vtkGdcmReader.cxx : bug fix when loading only 1 file. * src/gdcmHeader.h : formatting code diff --git a/Doc/Makefile.am b/Doc/Makefile.am index 141bd198..8ac7d5b8 100644 --- a/Doc/Makefile.am +++ b/Doc/Makefile.am @@ -1,7 +1,14 @@ HTML_DIR=$(datadir)/gdcm/html TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) -EXTRA_DIST = DoxyfileDeveloppers +EXTRA_DIST = \ + DoxyfileDeveloppers \ + DoxyfileUsers \ + DoxyDevelInstal.txt \ + DoxyIntroduction.txt \ + DoxyPython.txt \ + DoxyInstallation.txt \ + DoxyMainPage.txt all-local: html.developper/index.html diff --git a/MANIFEST.in b/MANIFEST.in index 17845e13..8eab6430 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,7 @@ include *.py recursive-include src *.h +include src/jpeg/libijg8/jconfig.linux +include src/jpeg/libijg8/jconfig.vc recursive-include vtk *.h recursive-include Dicts *.dic recursive-include Test *.* diff --git a/PACKAGER b/PACKAGER new file mode 100644 index 00000000..1d2657a0 --- /dev/null +++ b/PACKAGER @@ -0,0 +1,75 @@ +Here is the checklist when freezing a version of gdcm: + +* First stage, checkings: + 1/ Un*x: + Notation: we here assume you have a cvs tree in GDCMHOME directory. + cvs -d:pserver:anonymous@cvs.creatis.insa-lyon.fr:2402/cvs/public login + cvs -d:pserver:anonymous@cvs.creatis.insa-lyon.fr:2402/cvs/public co gdcm + cd gdcm + export GDCMHOME=`pwd` + cvs -d:pserver:anonymous@cvs.creatis.insa-lyon.fr:2402/cvs/public co gdcmData + + 1a/ check the full compilation is effective: + ./autogen.sh --enable-vtk --enable-python --enable-doxygen + make + + 1b/ check the python test suite is clean (python testSuite.py) + cd gdcmPython + export PYTHONPATH=`pwd`/.. + ln -s .libs/pygdcm.so _gdcm.so + ln -s .libs/vtkgdcmPython.so . + python testSuite.py + + 1c/ check the setup.py distutil script is operational and then validate + its produced packages through the test suite, in all following cases + - Direct installation: + cd $(GDCMHOME) + python setup.py install --prefix=/tmp/ + cd /tmp/lib/python2.2/site-packages/ + ln -s $(GDCMDATAHOME) . + export PYTHONPATH=`pwd` + cd gdcmPython/ + python testSuite.py + - Binary distribution: + cd $(GDCMHOME) + python setup.py bdist --formats=rpm + su + rpm -Uvh dist/gdcmPython-0.[n].i386.rpm + cd /usr/lib/python2.2/site-packages/ + Check out gdcmData + cd gdcmPython + python testSuite.py + rpm --erase gdcmPython + - Source distribution and then binary distribution (out of build + source distro): + cd $(GDCMHOME) + python setup.py sdist + cd /tmp + tar zxvf ~/cvs/gdcm/dist/gdcmPython-*.tar.gz + cd gdcmPython-*/ + python setup.py bdist --formats=rpm + As root, repeat above installation with rpm and test. + + 2/ Windoze: + +* Second stage: preparing packaging: + - Update the version number in configure.in (AM_INIT_AUTOMAKE) + - Update the version number in setup.py (version entry in setup object). + +* Third stage: packaging + 1/ Un*x + 1a/ Packaging at the C/C++/Python level (i.e. exports both libraries, + include files and python package) + - Make sure you have a ~/.rpmmacros file containing the line + %_topdir + and that exists and contains the subdirs + BUILD, SOURCES, RPMS/i386, SRPMS, SPECS + - cd $(GDCMHOME) + - ./autogen.sh --enable-vtk --enable-python --enable-doxygen + - make release (generates gdcm-x.y.z.tar.gz) + - rpm -ta gdcm-x.y.z.tar.gz + 1b/ Packaging at the python level: + cd $(GDCMHOME) + python setup.py sdist + python setup.py bdist --formats=rpm + collect both source distro and binary distro diff --git a/TODO b/TODO index b7a40513..4a208ce4 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,13 @@ +* Split gdcmHeader through inheritance to create gdcmHeaderHelper + that would regroup all the heuristics above a gdcmHeader e.g. the + functions GetXsize(), GetXSpacing(), GetXImagePosition()... + Those functions are the one using the results of the parsing as + done by gdcmHeader to provide the user with heuristics above various + values found in the header (the simplest form being to default a value). +* vtk/vtkGdcmHeader.cxx: if speed becomes a concern some changes can + be made a the cost of memory consumption (refer to header of + vtk/vtkGdcmHeader.cxx) +* Add a GetVersion() global function. * gdcmElValSet::SetElValueLengthByNumber IMNSHO should be trashed. It's only purpose is a onliner substitute to calling GetElValueByNumber and then SetLength. This only obfuscates the caller code more than @@ -34,10 +44,10 @@ below the specified size. When accessing the value of such an element the content is unfound ! Find a decent way of loading the value on explicit demand. -* fournir une method qui ne fait que lire les elements passes en arguments +* JPR: fournir une method qui ne fait que lire les elements passes en arguments sous forme d'une liste. -* gdcmHeader::CheckSwap() dans le cas ACR pas propre, degager tout de suite - si on a deduit que c'en est pas... +* JPR: gdcmHeader::CheckSwap() dans le cas ACR pas propre, degager tout de + suite si on a deduit que c'en est pas... * python /usr/lib/python2.2/site-packages/DaVaW/demo/dvwDcmReader.py and load image /home/frog/cvs/DCMlib/Data/CT-MONO2-16-ankle.dcm will yield wrong coloring scheme as opposed to diff --git a/configure.in b/configure.in index 492bbad6..a54cd262 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(src/gdcmDict.cxx) -AM_INIT_AUTOMAKE(gdcm, 0.1.0) +AM_INIT_AUTOMAKE(gdcm, 0.3.0) AM_MAINTAINER_MODE AM_CONFIG_HEADER(src/config.h) diff --git a/gdcmPython/__init__.py b/gdcmPython/__init__.py index a4c36f33..26de4736 100644 --- a/gdcmPython/__init__.py +++ b/gdcmPython/__init__.py @@ -17,11 +17,10 @@ def BuildInstallOrPreinstallPath(DirName, FileName): PreInstallModePath = os.path.join(__path__[0], "..", DirName + "/") if os.path.isfile(os.path.join(PreInstallModePath, FileName)): return PreInstallModePath - print "Unfound directory ", DirName return None ### Setup the path to the dictionaries. WARNING: this needs to be done -# BEFORE importation of the shadow classse generated by swig as found +# BEFORE importation of the shadow classes generated by swig as found # in gdcm, since the dynamic library loads the standard dictionary # when dynamically loaded. # We consider we succefully found the dictionaries path when we encounter @@ -42,6 +41,8 @@ except KeyError: ### Set up the path to the data images for the demos. GDCM_DATA_PATH = BuildInstallOrPreinstallPath("Test", "test.acr") +if not GDCM_DATA_PATH: + print "GDCM_DATA_PATH is not setup properly: unfound Test directory" ### Set up the path to the data images of the test suite. GDCM_TEST_DATA_PATH = BuildInstallOrPreinstallPath("gdcmData", "test.acr") diff --git a/gdcmPython/testSuite.py b/gdcmPython/testSuite.py index 7efdf672..8a19d58b 100644 --- a/gdcmPython/testSuite.py +++ b/gdcmPython/testSuite.py @@ -528,14 +528,19 @@ class gdcmTestCase(unittest.TestCase): Source.GetImageData() TargetFileName = "junk" Target = Source.WriteDcmImplVR(TargetFileName) - Sign = '5af8739c15dd579dea223eb3930cacda' + Sign = 'c3d27238647b7eaa773bff6ea0692b54' ComputeSign = md5.new(open(TargetFileName).read()).hexdigest() - #print ComputeSign self.assertEqual(ComputeSign, Sign, ("Wrong signature for file %s (got %s, shoud be %s)" % (SourceFileName, ComputeSign, Sign)) ) os.unlink(TargetFileName) if __name__ == '__main__': + if not GDCM_TEST_DATA_PATH: + print "GDCM_TEST_DATA_PATH is not setup properly. This test suite" + print " requires that some Dicom reference files be installed." + print " For further details on installation of gdcmData, please" + print " refer to the developper's section of page " + print " http://www.creatis.insa-lyon.fr/Public/Gdcm" unittest.main() diff --git a/src/config.h b/src/config.h index 49922152..52353876 100644 --- a/src/config.h +++ b/src/config.h @@ -39,5 +39,5 @@ #define PACKAGE "gdcm" /* Version number of package */ -#define VERSION "0.1.0" +#define VERSION "0.3.0" diff --git a/src/gdcmElValSet.cxx b/src/gdcmElValSet.cxx index 1d6e42b3..044ee8eb 100644 --- a/src/gdcmElValSet.cxx +++ b/src/gdcmElValSet.cxx @@ -322,14 +322,6 @@ void gdcmElValSet::UpdateGroupLength(bool SkipSequence, FileType type) { groupHt[key] += 2 + 2 + 4 + elem->GetLength(); } } - - if(1) // unnormalized way to see what happened - for (GroupHT::iterator g = groupHt.begin(); - g != groupHt.end(); - ++g){ - printf("groupKey %s : %d\n",g->first.c_str(),g->second); - } - unsigned short int gr_bid; for (GroupHT::iterator g = groupHt.begin(); // for each group we found diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index 94f86cb7..3431c0f8 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -2,12 +2,6 @@ #include "gdcmFile.h" #include "gdcmUtil.h" - - -// TODO : remove DEBUG -#define DEBUG 0 - - #include "iddcmjpeg.h" using namespace std; @@ -89,8 +83,6 @@ bool gdcmFile::ReadPixelData(void* destination) { if ( !OpenFile()) return false; - printf("GetPixelOffset() %d\n",GetPixelOffset() ); - if ( fseek(fp, GetPixelOffset(), SEEK_SET) == -1 ) { CloseFile(); return false; @@ -119,15 +111,11 @@ bool gdcmFile::ReadPixelData(void* destination) { fread(&ln,4,1,fp); if(GetSwapCode()) ln=SwapLong(ln); - if (DEBUG) - printf ("ln %d\n",ln); fseek(fp,ln,SEEK_CUR); fseek(fp,4,SEEK_CUR); fread(&ln,4,1,fp); if(GetSwapCode()) ln=SwapLong(ln); - if (DEBUG) - printf ("ln image comprimée %d\n",ln); // ------------------------------- JPEG LossLess : call to Jpeg Libido diff --git a/src/jpeg/libijg8/Makefile.am b/src/jpeg/libijg8/Makefile.am index d3cc3ae7..757b0ff7 100644 --- a/src/jpeg/libijg8/Makefile.am +++ b/src/jpeg/libijg8/Makefile.am @@ -52,16 +52,20 @@ libgdcmijpeg8_la_SOURCES= \ jmemmgr.c \ jmemnobs.c -###libgdcmincludedir = $(includedir) -###libgdcmijpeg8include_HEADERS = \ -### jchuff.h \ -### jconfig.h \ -### jdct.h \ -### jdhuff.h \ -### jerror.h \ -### jinclude.h \ -### jmemsys.h \ -### jmorecfg.h \ -### jpegint.h \ -### jpeglib.h \ -### jversion.h +libgdcmijpeg8includedir = $(includedir) +libgdcmijpeg8include_HEADERS = \ + jchuff.h \ + jconfig.h \ + jdct.h \ + jdhuff.h \ + jerror.h \ + jinclude.h \ + jmemsys.h \ + jmorecfg.h \ + jpegint.h \ + jpeglib.h \ + jversion.h + +EXTRA_DIST = \ + jconfig.linux \ + jconfig.vc diff --git a/vtk/.cvsignore b/vtk/.cvsignore index d7020d1a..d729749f 100644 --- a/vtk/.cvsignore +++ b/vtk/.cvsignore @@ -5,3 +5,4 @@ Makefile vtkgdcmdemo *.la *.lo +vtkGdcmReaderPython.cxx diff --git a/vtk/vtkGdcmReader.cxx b/vtk/vtkGdcmReader.cxx index 8d521ff0..5dd9fcfe 100644 --- a/vtk/vtkGdcmReader.cxx +++ b/vtk/vtkGdcmReader.cxx @@ -1,4 +1,47 @@ -// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.16 2003/07/07 10:26:14 regrain Exp $ +// $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.17 2003/07/07 17:05:17 frog Exp $ +// ////////////////////////////////////////////////////////////// +// WARNING TODO CLENAME +// Actual limitations of this code: +// +// /////// Redundant and unnecessary header parsing +// In it's current state this code actually parses three times the Dicom +// header of a file before the corrersponding image gets loaded in the +// ad-hoc vtkData ! +// Here is the process: +// 1/ First loading happens in ExecuteInformation which in order to +// positionate the vtk extents calls CheckFileCoherence. The purpous +// of CheckFileCoherence is to make sure all the images in the future +// stack are "homogenous" (same size, same representation...). This +// can only be achieved by parsing all the Dicom headers... +// 2/ ExecuteData is then responsible for the next two loadings: +// 2a/ ExecuteData calls AllocateOutputData that in turn seems to +// (indirectely call) ExecuteInformation which ends up in a second +// header parsing +// 2b/ the core of ExecuteData then needs gdcmFile (which in turns +// initialiszes gdcmHeader in the constructor) in order to access +// the data-image. +// +// Possible solution: +// maintain a list of gdcmFiles (created by say ExecuteInformation) created +// once and for all accross the life of vtkGdcmHeader (it would only load +// new gdcmFile if the user changes the list). ExecuteData would then use +// those gdcmFile and hence avoid calling the consctutor: +// - advantage: the header of the files would only be parser once. +// - drawback: once execute information is called (i.e. on creation of +// a vtkGdcmHeader) the gdcmFile sctructue is loaded in memory. +// The average size of a gdcmHeader being of 100Ko, is one +// loads 10 stacks of images with say 200 images each, you +// end-up with a loss of 200Mo... +// +// /////// Never unallocated memory: +// ExecuteData allocates space for the pixel data [which will get pointed +// by the vtkPointData() through the call +// data->GetPointData()->GetScalars()->SetVoidArray(mem, StackNumPixels, 0);] +// This data is never "freed" neither in the desctutor nor when the +// filename list is extended, ExecuteData is called a second (or third) +// time... +// ////////////////////////////////////////////////////////////// + #include #include #include @@ -14,7 +57,6 @@ vtkGdcmReader::vtkGdcmReader() //---------------------------------------------------------------------------- vtkGdcmReader::~vtkGdcmReader() { - // FIXME free memory this->RemoveAllFileName(); this->InternalFileNameList.clear(); } @@ -283,7 +325,6 @@ int vtkGdcmReader::CheckFileCoherence() // Configure the output e.g. WholeExtent, spacing, origin, scalar type... void vtkGdcmReader::ExecuteInformation() { - //FIXME free any old memory this->TotalNumberOfPlanes = this->CheckFileCoherence(); if ( this->TotalNumberOfPlanes == 0) { @@ -423,8 +464,7 @@ size_t vtkGdcmReader::LoadImageInMemory( // (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. +// extent/axes are assumed to be the same as the file extent/order. void vtkGdcmReader::ExecuteData(vtkDataObject *output) { if (this->InternalFileNameList.empty()) @@ -433,7 +473,7 @@ void vtkGdcmReader::ExecuteData(vtkDataObject *output) return; } - // FIXME : the bad parse of header is made when allocating OuputData + // FIXME : extraneous parsing of header is made when allocating OuputData vtkImageData *data = this->AllocateOutputData(output); data->SetExtent(this->DataExtent); data->GetPointData()->GetScalars()->SetName("DicomImage-Volume"); -- 2.45.1