From: frog Date: Mon, 3 Mar 2003 17:56:21 +0000 (+0000) Subject: * Eventually, python/gdcmPython was renamed to gdcmPython. This X-Git-Tag: April2003~35 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=29f93a14132dd0c6d9d9480ea038a2a4e8ed7e93;p=gdcm.git * Eventually, python/gdcmPython was renamed to gdcmPython. This was done in a last ditch attempt to get setup.py _really_ operationnal. The python/gdcmPython layaout add the advantage of hidding away the python related distutils specific files (MANIFEST.in, setup.py, distutils*.py...) from the main directory. Alas, the src directory was out of scope (i.e. it's relative position to setup.py was ../src) which made things impossible to handle (see previous version of python/setup.py). Crossing fingers... --- diff --git a/.cvsignore b/.cvsignore index b1a0530f..ed19bc64 100644 --- a/.cvsignore +++ b/.cvsignore @@ -9,3 +9,7 @@ configure libtool ltmain.sh aclocal.m4 +*.pyc +build +dist +MANIFEST diff --git a/ChangeLog b/ChangeLog index 794a35e9..efd55ecf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-03-03 Eric Boix + * Eventually, python/gdcmPython was renamed to gdcmPython. This + was done in a last ditch attempt to get setup.py _really_ + operationnal. The python/gdcmPython layaout add the advantage + of hidding away the python related distutils specific files + (MANIFEST.in, setup.py, distutils*.py...) from the main directory. + Alas, the src directory was out of scope (i.e. it's relative + position to setup.py was ../src) which made things impossible to + handle (see previous version of python/setup.py). Crossing fingers... + 2003-02-20 Eric Boix * python/setup.py now works on Un*x. (harder than I thougth) * python/distutilsSwigCPlusPlus.py can now have include files diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..0d995412 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,4 @@ +include distutilsSwigCPlusPlus.py +recursive-include src *.h +recursive-include Dicts *.dic +recursive-include Data *.* diff --git a/distutilsSwigCPlusPlus.py b/distutilsSwigCPlusPlus.py new file mode 100644 index 00000000..733e039d --- /dev/null +++ b/distutilsSwigCPlusPlus.py @@ -0,0 +1,146 @@ +from distutils.command.build_ext import build_ext +from distutils.core import Extension +from types import ListType +import os + +class mybuild_ext(build_ext): + """ + This distutils command is meant to be used with MyExtension extension, which + defines a swig_include attribute. + """ + build_ext.user_options.append(('swig-include=','S', + "list of directories for swig to search in" + + "for header files")) + + def initialize_options (self): + build_ext.initialize_options(self) + self.swig_include = None + + def finalize_options (self): + build_ext.finalize_options(self) + if self.swig_include!=None: + self.swig_include=self.swig_include.split(":") + + def build_extension(self, ext): + # command-line arguments prevail over extension arguments + # but if no command-line argument is defined, extension argument is + # taken into account + if self.swig_include==None:self.swig_include=ext.swig_include + if self.swig_cpp==None:self.swig_cpp=ext.swig_cpp + + build_ext.build_extension(self,ext) + + def swig_sources (self, sources): + + """Walk the list of source files in 'sources', looking for SWIG + interface (.i) files. Run SWIG on all that are found, and + return a modified 'sources' list with SWIG source files replaced + by the generated C (or C++) files. + """ + + new_sources = [] + swig_sources = [] + swig_targets = {} + + # XXX this drops generated C/C++ files into the source tree, which + # is fine for developers who want to distribute the generated + # source -- but there should be an option to put SWIG output in + # the temp dir. + + ## Modified lines (compared to buil_exts.wig_sources original method) + if self.swig_cpp: + target_ext = '_wrap.cpp' + else: + target_ext = '_wrap.c' + ## End of modification + + for source in sources: + (base, ext) = os.path.splitext(source) + if ext == ".i": # SWIG interface file + new_sources.append(base + target_ext) + swig_sources.append(source) + swig_targets[source] = new_sources[-1] + elif ext == ".h": + continue + else: + new_sources.append(source) + + if not swig_sources: + return new_sources + + swig = self.find_swig() + + ## Modified lines (compared to buil_exts.wig_sources original method) + swig_cmd = [swig, "-python"] + if self.swig_cpp: + swig_cmd.append("-c++") + + if self.swig_include: + for pth in self.swig_include: + swig_cmd.append("-I%s"%pth) + ## End of modification + + for source in swig_sources: + target = swig_targets[source] + self.announce("swigging %s to %s" % (source, target)) + self.spawn(swig_cmd + ["-o", target, source]) + print swig_cmd + ["-o", target, source] + ## Modified lines (compared to buil_exts.wig_sources original method) + # When swig generated some shadow classes, place them under + # self.build_lib (the build directory for Python source). + import string + swig_shadow = string.split(os.path.basename(source), ".")[0] + swig_shadow = swig_shadow + '.py' + infile = os.path.join(os.path.dirname(source), swig_shadow) + if os.path.isfile(infile): + outfile = [self.build_lib, self.distribution.get_name()] + outfile.append(swig_shadow) + outfile = apply(os.path.join, outfile) + self.copy_file(infile, outfile, preserve_mode=0) + ## End of modification + + return new_sources + +class MyExtension(Extension): + """ + This class extends basic distutils Extension class, adding two keyword + arguments : + * swig_cpp, which triggers -c++ mode when swigging + * swig_include, which specifies -I flag when swigging + This class is meant to be build with mybuild_ext distutils command. + """ + def __init__(self,swig_include=None,swig_cpp=None,**args): + Extension.__init__(self,**args) + + assert ((swig_include==None or type(swig_include) is ListType), + "swig_include must be a list of strings") + + self.swig_include = swig_include or [] + self.swig_cpp = swig_cpp + +""" +Example of use of these classes in distutils setup method : + +from Transfert.tcDistUtils import mybuild_ext,MyExtension +setup(name="xxx", + version="X.Y", + description="blah blah blah", + author="John Doe", + author_email="i.hate@spam.com", + url="http://www.fakeurl.com", + packages=["yyy"], + cmdclass={'build_ext':mybuild_ext}, # redirects default build_ext + ext_modules=[MyExtension(name="src/xxx, # instance of our Extension class + sources=["src/xxx.cpp", + "src/xxx.i"], + include_dirs=["/usr/include/python2.1", + "/usr/include/vtk"], + libraries=["vtkGraphics"], + swig_cpp=1, # C++ support + swig_include=["src"] # SWIG include dirs + ) + ] + ) + +and then run "python setup.py build"... +""" diff --git a/gdcmPython/.cvsignore b/gdcmPython/.cvsignore new file mode 100644 index 00000000..2b797954 --- /dev/null +++ b/gdcmPython/.cvsignore @@ -0,0 +1,5 @@ +gdcm.py +*.pyc +gdcm_wrap.cpp +gdcm_wrap.cxx +gdcm_wrap.doc diff --git a/gdcmPython/Makefile b/gdcmPython/Makefile new file mode 100644 index 00000000..cde6e854 --- /dev/null +++ b/gdcmPython/Makefile @@ -0,0 +1,43 @@ +.SECONDARY: + +SWIG = swig +SWIGFLAGS= -python -c++ + +TARGET=_gdcm.so + +GDCMDIR=../src +GDCMLIB=$(GDCMDIR)/.libs/libgdcm.a +GDCMINCLUDES=-I$(GDCMDIR) + +PYTHON=python +PYTHON_PREFIX =`$(PYTHON) -c "import sys; print sys.exec_prefix"` +PYTHON_VERSION =`$(PYTHON) -c "import sys; print sys.version[:3]"` +PYTHON_INCLUDES="-I$(PYTHON_PREFIX)/include/python$(PYTHON_VERSION)" + +CXXFLAGS=$(GDCMINCLUDES) +CPPFLAGS=-g -Wall -Wunused-variable +LDFLAGS=-g + +%_wrap.o : %_wrap.cxx + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(PYTHON_INCLUDES) $< -o $@ +%_wrap.cxx : %.i + $(SWIG) $(SWIGFLAGS) $(PYTHON_INCLUDES) $(GDCMINCLUDES) -o $@ $< +%.o : %.cxx + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ + + +all: gdcm_wrap.o $(GDCMLIB) + g++ -shared $^ -o $(TARGET) $(LDFLAGS) + +test: + $(PYTHON) -c"import _gdcm" + +clean: + rm -f *_wrap* *.so *.o *.pyc gdcm.py + +$(GDCMLIB): FORCE + cd $(GDCMDIR); make + +FORCE: + +#.SECONDARY: dcm_wrap.cxx diff --git a/gdcmPython/__init__.py b/gdcmPython/__init__.py new file mode 100644 index 00000000..f454cdb1 --- /dev/null +++ b/gdcmPython/__init__.py @@ -0,0 +1,63 @@ +import os, sys + +### Setup the path to the dictionaries. WARNING: this needs to be done +# BEFORE importation of the shadow classse 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 +# the standard dictionary i.e. the file dicomV3.dic. + +try: + ### First consider the environnement variable. + os.environ["GDCM_DICT_PATH"] + if not os.path.isfile(os.path.join(os.environ["GDCM_DICT_PATH"], + "dicomV3.dic")): + raise KeyError +except KeyError: + # When environnement variable is unavailable assume the package was + # properly installed i.e. the layout is such that the directory containing + # the dictionaries is BELOW (the root is at the top) the current file. + # Note: when importing this __init__ file the pathes are relative to the + # invocation directory. In order to get them relative to the package + # (or more simply to this file) we rely on the __path__ variable. + InstallModePath = os.path.join(__path__[0], "Dicts/") + if os.path.isfile(os.path.join(InstallModePath, "dicomV3.dic")): + os.environ["GDCM_DICT_PATH"] = InstallModePath + PreInstallModePath = None + else: + # When both environnement variable and proper package installation + # strategy fail we eventually consider the pre-installation mode + # i.e. when developpers are toying in a CVS tree. In this case + # the layout is such that the directory containing the dictionaries is + # ABOVE (the root is at the top) the current directory. + PreInstallModePath = os.path.join(__path__[0], "..", "Dicts/") + if os.path.isfile(os.path.join(PreInstallModePath, "dicomV3.dic")): + os.environ["GDCM_DICT_PATH"] = PreInstallModePath + InstallModePath = None + else: + print "Unfound gdcm dictionaries path" + sys.exit(1) + +### Set up the path to the data images (for the test suite and the demo +# examples). As for GDCM_DICT_PATH we offer both proper python package +# installation scheme and the pre-install mode (see above). +if InstallModePath: + GDCM_DATA_PATH = os.path.join(__path__[0], "Data") +else: + if PreInstallModePath: + GDCM_DATA_PATH = os.path.join(__path__[0], "..","Data") + else: + print "Unfound data path" + sys.exit(1) + +### Import the swig generated shadow classes. +try: + import gdcm +except ImportError,e: + print e + raise ImportError, "gdcm extension not imported." + +### Expose only the necessary stuff +gdcmHeader = gdcm.gdcmHeader +gdcmDictSet = gdcm.gdcmDictSet +gdcmFile = gdcm.gdcmFile diff --git a/gdcmPython/demo/.cvsignore b/gdcmPython/demo/.cvsignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/gdcmPython/demo/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/gdcmPython/demo/explore.py b/gdcmPython/demo/explore.py new file mode 100644 index 00000000..aa92d787 --- /dev/null +++ b/gdcmPython/demo/explore.py @@ -0,0 +1,27 @@ +from gdcmPython import * + +### Get filename from command line or default it +try: + FileName = sys.argv[1] +except IndexError: + FileName = os.path.join(GDCM_DATA_PATH, "test.acr") + +if not os.path.isfile(FileName): + print "Cannot open file ", FileName + sys.exit() + +toRead = gdcmHeader(FileName) +toRead.LoadElements() +ValDict = toRead.GetPubElVal() +ExploreElements = ["Patient Name", "Patient ID", + "Study Date", "Study Time", "Study ID", + "Study Instance UID", + "Series Number", + "Modality"] + +for elem in ExploreElements: + print "[%s] = " % elem, + try: + print "[%s]" % ValDict[elem] + except KeyError: + print "NOT FOUND" diff --git a/gdcmPython/demo/printGroupedPublicDict.py b/gdcmPython/demo/printGroupedPublicDict.py new file mode 100644 index 00000000..153e173b --- /dev/null +++ b/gdcmPython/demo/printGroupedPublicDict.py @@ -0,0 +1,19 @@ +from gdcmPython import * + +print "##############################################################" +print "### Display all the possible tags of the current public" +print "### dictionary" +print "##############################################################" +PubList = gdcmDictSet.GetPubDictTagNames() +for i in range(0, len(PubList)): + print " ", PubList[i] + +print "##############################################################" +print "### Display all the possible tags of the current public" +print "### dictionary, but grouped by using the Fourth field" +print "##############################################################" +PubDict = gdcmDictSet.GetPubDictTagNamesByCategory() +for fourth in PubDict: + print " ############ Fourth group = ", fourth, " ##############" + for key in PubDict[fourth]: + print " ", key diff --git a/gdcmPython/demo/test.py b/gdcmPython/demo/test.py new file mode 100644 index 00000000..653b4b8c --- /dev/null +++ b/gdcmPython/demo/test.py @@ -0,0 +1,26 @@ +from gdcmPython import * + +### Get filename from command line or default it +try: + FileName = sys.argv[1] +except IndexError: + FileName = os.path.join(GDCM_DATA_PATH, "test.acr") + +if not os.path.isfile(FileName): + print "Cannot open file ", FileName + sys.exit() + +# On debugging purposes uncomment the next line +#s = raw_input("Hit any key in this window to exit") + +### Build the header element list +toRead = gdcmHeader(FileName) +toRead.LoadElements() + +print "##############################################################" +print "### Display all the elements and their respective values" +print "## found in the ", FileName, " file." +print "##############################################################" +ValDict = toRead.GetPubElVal() +for key in ValDict.keys(): + print "[%s] = [%s]" %(key, ValDict[key]) diff --git a/gdcmPython/demo/testAll.py b/gdcmPython/demo/testAll.py new file mode 100644 index 00000000..e46fda06 --- /dev/null +++ b/gdcmPython/demo/testAll.py @@ -0,0 +1,36 @@ +from gdcmPython import * + +# Test each file of the Data directory + +AllFiles = [ + "CR-MONO1-10-chest.dcm", + "CT-MONO2-16-brain.dcm", + "CT-MONO2-16-ort.dcm", + "CT-MONO2-16-ankle.dcm", + "CT-MONO2-8-abdo.dcm", + "CT-MONO2-12-lomb-an2.acr2", + "CT-MONO2-16-chest.dcm", + "MR-MONO2-12-angio-an1.acr1", + "MR-MONO2-12-an2.acr2", + "MR-MONO2-16-head.dcm", + "MR-MONO2-12-shoulder.dcm", + "OT-PAL-8-face.dcm", + "OT-MONO2-8-a7.dcm", + "US-RGB-8-esopecho.dcm", + "US-RGB-8-epicard.dcm", + "MR-MONO2-8-16x-heart.dcm", + "NM-MONO2-16-13x-heart.dcm", + "US-MONO2-8-8x-execho.dcm", + "US-PAL-8-10x-echo.dcm", + "XA-MONO2-8-12x-catheter.dcm", + ] + +if __name__ == '__main__': + for file in AllFiles: + fileName = os.path.join(GDCM_DATA_PATH, file) + print "############## file :", fileName + toRead = gdcmHeader(fileName) + toRead.LoadElements() + ValDict = toRead.GetPubElVal() + for key in ValDict.keys(): + print " [%s] = [%s]" %(key, ValDict[key]) diff --git a/gdcmPython/gdcm.i b/gdcmPython/gdcm.i new file mode 100644 index 00000000..6e00374c --- /dev/null +++ b/gdcmPython/gdcm.i @@ -0,0 +1,80 @@ +%module gdcm +%{ +#include "gdcm.h" + +// Utility functions on strings for removing leading and trailing spaces +void EatLeadingAndTrailingSpaces(string & s) { + while ( s.length() && (s[0] == ' ') ) + s.erase(0,1); + while ( s.length() && (s[s.length()-1] == ' ') ) + s.erase(s.length()-1, 1); +} +%} +typedef unsigned short guint16; +typedef unsigned int guint32; + +%typemap(out) list * { + PyObject* NewItem = (PyObject*)0; + PyObject* NewList = PyList_New(0); // The result of this typemap + for (list::iterator NewString = ($1)->begin(); + NewString != ($1)->end(); ++NewString) { + NewItem = PyString_FromString(NewString->c_str()); + PyList_Append( NewList, NewItem); + } + $result = NewList; +} + +// Convert a c++ hash table in a python native dictionary +%typemap(out) map > * { + PyObject* NewDict = PyDict_New(); // The result of this typemap + PyObject* NewKey = (PyObject*)0; + PyObject* NewVal = (PyObject*)0; + + for (map >::iterator tag = ($1)->begin(); + tag != ($1)->end(); ++tag) { + string first = tag->first; + // Do not publish entries whose keys is made of spaces + if (first.length() == 0) + continue; + NewKey = PyString_FromString(first.c_str()); + PyObject* NewList = PyList_New(0); + for (list::iterator Item = tag->second.begin(); + Item != tag->second.end(); ++Item) { + NewVal = PyString_FromString(Item->c_str()); + PyList_Append( NewList, NewVal); + } + PyDict_SetItem( NewDict, NewKey, NewList); + } + $result = NewDict; +} + +// Convert a c++ hash table in a python native dictionary +%typemap(out) TagElValueHT & { + PyObject* NewDict = PyDict_New(); // The result of this typemap + string RawName; // Element name as gotten from gdcm + PyObject* NewKey = (PyObject*)0; // Associated name as python object + string RawValue; // Element value as gotten from gdcm + PyObject* NewVal = (PyObject*)0; // Associated value as python object + + for (TagElValueHT::iterator tag = $1->begin(); tag != $1->end(); ++tag) { + + // The element name shall be the key: + RawName = tag->second->GetName(); + // gdcm unrecognized (including not loaded because their size exceeds + // the user specified treshold) elements are exported with their + // TagKey as key. + if (RawName == "Unknown") + RawName = tag->second->GetKey(); + NewKey = PyString_FromString(RawName.c_str()); + + // Element values are striped from leading/trailing spaces + RawValue = tag->second->GetValue(); + EatLeadingAndTrailingSpaces(RawValue); + NewVal = PyString_FromString(RawValue.c_str()); + + PyDict_SetItem( NewDict, NewKey, NewVal); + } + $result = NewDict; +} + +%include gdcm.h diff --git a/gdcmPython/testSuite.py b/gdcmPython/testSuite.py new file mode 100644 index 00000000..e053d655 --- /dev/null +++ b/gdcmPython/testSuite.py @@ -0,0 +1,505 @@ +import unittest +import os +from gdcmPython import * + +class gdcmTestCase(unittest.TestCase): + # The files whose name starts with a modality (e.g. CR-MONO1-10-chest.dcm) + # come from Sebastien Barre's Dicom2 highly recommendable site + # http://www.barre.nom.fr/medical/samples/index.html + BarreFiles = [ + #################################### + # CR modality examples: + #################################### + ["CR-MONO1-10-chest.dcm", + [ ["Modality", "CR"], + #"Transfer Syntax UID" is absent. + ["Rows", "440"], + ["Columns", "440"], + ["Bits Stored", "10"], + ["Bits Allocated", "16"], + ["High Bit", "9"], + ["Pixel Representation", "0"], + ["Manufacturer", "FUJI PHOTO FILM CO. LTD."], + ["Manufacturer Model Name", "9000"], + ["7fe0|0010", "gdcm::NotLoaded. Address:776 Length:387200"] ] ], + #################################### + # CT modality examples: + #################################### + ["CT-MONO2-16-brain.dcm", + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Explicit VR, LE + ["Modality", "CT"], + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "16"], + ["Bits Allocated", "16"], + ["High Bit", "15"], + ["Pixel Representation", "1"], + ["Manufacturer", "Picker International, Inc."], + ["Manufacturer Model Name", "PQ5000"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1680 Length:524288"] ] ], + ["CT-MONO2-16-ort.dcm", + [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit VR, LE + ["Modality", "CT"], + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "16"], + ["Bits Allocated", "16"], + ["High Bit", "15"], + ["Pixel Representation", "1"], + ["Manufacturer", "GE MEDICAL SYSTEMS"], + ["Manufacturer Model Name", "HiSpeed CT/i"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1674 Length:524288"] ] ], + ["CT-MONO2-16-ankle.dcm", + [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit, little + ["Modality", "CT"], + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "16"], + ["Bits Allocated", "16"], + ["High Bit", "15"], + ["Pixel Representation", "1"], + ["Manufacturer", "GE MEDICAL SYSTEMS"], + ["Manufacturer Model Name", "GENESIS_ZEUS"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1148 Length:524288"] ] ], + ["CT-MONO2-8-abdo.dcm", + [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit, little + ["Modality", "CT"], + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Manufacturer", "FUJI"], + ["7fe0|0010", "gdcm::NotLoaded. Address:796 Length:262144"] ] ], + ["CT-MONO2-12-lomb-an2.acr2", + [ ["Modality", "CT"], + #"Transfer Syntax UID" and "Photometric Interpretation" are absent. + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "12"], + ["Bits Allocated", "16"], + ["High Bit", "11"], + ["Pixel Representation", "0"], + ["Manufacturer", "SIEMENS"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1230 Length:524288"] ] ], + ["CT-MONO2-16-chest.dcm", + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg... + ["Modality", "CT"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "400"], + ["Columns", "512"], + ["Bits Stored", "16"], + ["Bits Allocated", "16"], + ["High Bit", "15"], + ["Pixel Representation", "1"], + ["Manufacturer", "GE MEDICAL SYSTEMS"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1638 Length:143498"] ] ], + #################################### + ### MR modality examples: + #################################### + ["MR-MONO2-12-angio-an1.acr1", + [ ["Recognition Code", "ACR-NEMA 1.0"], + ["Modality", "MR"], + #"Transfer Syntax UID" and "Photometric Interpretation" are absent. + ["Rows", "256"], + ["Columns", "256"], + ["Bits Stored", "12"], + ["Bits Allocated", "12"], + ["High Bit", "11"], + ["Pixel Representation", "0"], + ["Manufacturer", "Philips"], + # Note: 256*256*12/8 = 98304 + ["7fe0|0010", "gdcm::NotLoaded. Address:650 Length:98304"] ] ], + ["MR-MONO2-12-an2.acr2", + [ ["Modality", "MR"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "256"], + ["Columns", "256"], + ["Bits Stored", "12"], + ["Bits Allocated", "16"], + ["High Bit", "11"], + ["Pixel Representation", "0"], + ["Manufacturer", "SIEMENS"], + ["Manufacturer Model Name", "MAGNETOM VISION"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1866 Length:131072"] ] ], + ["MR-MONO2-16-head.dcm", + [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Imp VR, LE + ["Modality", "MR"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "256"], + ["Columns", "256"], + ["Bits Stored", "16"], + ["Bits Allocated", "16"], + ["High Bit", "15"], + ["Pixel Representation", "1"], + ["Manufacturer", "GE MEDICAL SYSTEMS"], + ["Manufacturer Model Name", "GENESIS_SIGNA"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1804 Length:131072"] ] ], + # MR-MONO2-12-shoulder example is present in the Jpeg section. + # MR-MONO2-16-knee is not present in the test suite since it is too + # closely related to MR-MONO2-16-head.dcm to be of interest. + #################################### + # OT modality examples: + #################################### + # OT-MONO2-8-hip is not present in the test suite since it is too + # closely related to OT-MONO2-8-a7 to be of interest. + ["OT-PAL-8-face.dcm", + # Interest: has a color palette + [#"Transfer Syntax UID", and "Manufacturer" are absent. + ["Modality", "OT"], + ["Photometric Interpretation", "PALETTE COLOR"], + ["Rows", "480"], + ["Columns", "640"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1654 Length:307200"] ] ], + # OT-MONO2-8-colon is not present in the test suite since it is too + # closely related to OT-MONO2-8-a7 to be of interest. + ["OT-MONO2-8-a7.dcm", + [#"Transfer Syntax UID" is absent. + ["Modality", "OT"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Manufacturer", "Philips Medical Systems"], + ["7fe0|0010", "gdcm::NotLoaded. Address:438 Length:262144"] ] ], + #################################### + # US (Ultra Sound) modality examples: + #################################### + ["US-RGB-8-esopecho.dcm", + # Interest: RGB image + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Exp VR, LE + ["Modality", "US"], + ["Photometric Interpretation", "RGB"], + ["Rows", "120"], + ["Columns", "256"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Manufacturer", "Acme Products"], + # FIXME: 92160 / (120*256) = 3 bytes per pixel NOT 1. Maybe + # it has something to do with [Samples Per Pixel] = [3] ??? + ["7fe0|0010", "gdcm::NotLoaded. Address:904 Length:92160"] ] ], + ["US-RGB-8-epicard.dcm", + # Interest: Big endian transfert syntax + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.2"], # Big endian + ["Modality", "US"], + ["Photometric Interpretation", "RGB"], + ["Rows", "480"], + ["Columns", "640"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Manufacturer", "G.E. Medical Systems"], + ["Manufacturer Model Name", "LOGIQ 700"], + # FIXME: 921600/(480*640) = 3 bytes per pixel NOT 1. Maybe + # it has something to do with [Samples Per Pixel] = [3] ??? + ["Implementation Version Name", "OFFIS-DCMTK-311"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1012 Length:921600"] ] ], + ] + + MultiFrameFiles = [ + # The number of images is contained in the "Number of Frames" element + ["MR-MONO2-8-16x-heart.dcm", + # Interest: multi-frame + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE + ["Number of Frames", "16"], + ["Modality", "MR"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "256"], + ["Columns", "256"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Manufacturer", "Philips"], + # Note: 256*256*16=1048576 (16 is the number of Frames) + ["7fe0|0010", "gdcm::NotLoaded. Address:920 Length:1048576"] ] ], + ["NM-MONO2-16-13x-heart.dcm", + # Interest: NM modality, multi-frame + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE + ["Number of Frames", "13"], + ["Modality", "NM"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "64"], + ["Columns", "64"], + ["Bits Stored", "16"], + ["Bits Allocated", "16"], + ["High Bit", "15"], + ["Pixel Representation", "0"], + ["Manufacturer", "ACME Products"], + # Note: 64*64*13*2=106496 + ["7fe0|0010", "gdcm::NotLoaded. Address:1234 Length:106496"] ] ], + ["US-MONO2-8-8x-execho.dcm", + # Interest: multi-frame + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE + ["Number of Frames", "8"], + ["Modality", "US"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "120"], + ["Columns", "128"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Manufacturer", "Acme Products"], + ["7fe0|0010", "gdcm::NotLoaded. Address:976 Length:122880"] ] ], + ["US-PAL-8-10x-echo.dcm", + # Interest: RLE (Run Length Encoded) compression, multiframe + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.5"], # RLE + ["Number of Frames", "10"], + ["Modality", "US"], + ["Photometric Interpretation", "PALETTE COLOR"], + ["Rows", "430"], + ["Columns", "600"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Manufacturer", "ACME Products"], + ["7fe0|0010", "gdcm::NotLoaded. Address:2428 Length:481182"] ] ], + ["XA-MONO2-8-12x-catheter.dcm", + # Interest: XA modality, multi-frame + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg + ["Number of Frames", "12"], # 12 images + ["Modality", "XA"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Manufacturer", "Acme Products"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1006 Length:920072"] ] ], + ] + + GdcmFiles = [ + ["gdcm-MR-SIEMENS-16.acr1", + # Interest: good old Acr-Nema Version 1, see also Oddities below + [ ["Recognition Code", "ACR-NEMA 1.0"], + ["Modality", "MR"], + ["Rows", "256"], + ["Columns", "256"], + ["Bits Stored", "12"], + ["Bits Allocated", "16"], + ["High Bit", "11"], + ["Pixel Representation", "0"], + ["Manufacturer", "SIEMENS"], + ["Manufacturer Model Name", "GBS III"], + # FIXME: this image looks padded at the end. The length of the file + # is 140288. Notice that, 256*256*2 + 1024 = 131072 + 1024 = 132096 + ["7fe0|0010", "gdcm::NotLoaded. Address:8192 Length:132096"], + # Oddities: "Study ID" and "Series Number" are empty + ["Study ID", ""], + ["Series Number", ""] ] ], + # Oddities: "Study" and "Serie Instance UID" are not present + ["gdcm-MR-SIEMENS-16.acr2", + # Interest: Acr-Nema Version 2 + [ ["Recognition Code", "ACR-NEMA 2.0"], + ["Modality", "MR"], + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "12"], + ["Bits Allocated", "16"], + ["High Bit", "11"], + ["Pixel Representation", "0"], + ["Manufacturer", "SIEMENS"], + ["Manufacturer Model Name", "MAGNETOM VISION"], + ["Study Instance UID", + "1.3.12.2.1107.5.2.4.7630.20000918174641000"], + ["Study ID", "1"], + ["Series Instance UID", + "1.3.12.2.1107.5.2.4.7630.20000918175714000007"], + ["Series Number", "7"], + ["7fe0|0010", "gdcm::NotLoaded. Address:6052 Length:524288"] ] ], + ["gdcm-US-ALOKA-16.dcm", + # Interest: - possesses 3 LUTS: a Green (checked), a Red and BLue. + # - announced as implicit VR, but really explicit VR. + [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit VR, LE + ["Modality", "US"], + ["Photometric Interpretation", "PALETTE COLOR"], + ["Segmented Green Palette Color LUT Data", + "gdcm::NotLoaded. Address:89576 Length:113784"], + ["Rows", "480"], + ["Columns", "640"], + ["Bits Stored", "16"], + ["Bits Allocated", "16"], + ["High Bit", "15"], + ["Pixel Representation", "0"], + ["Manufacturer", "ALOKA CO., LTD."], + ["Manufacturer Model Name", "SSD-4000"], + ["7fe0|0010", "gdcm::NotLoaded. Address:258740 Length:614400"] ] ], + ["gdcm-MR-PHILIPS-16.dcm", + # Interest: - possesses a sequence + # - dicom file, with a recognition code of ACR-NEMA1 + [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit VR, LE + ["Recognition Code", "ACR-NEMA 1.0"], + ["Modality", "MR"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "256"], + ["Columns", "256"], + ["Bits Stored", "8"], + ["Bits Allocated", "16"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Manufacturer", "Philips Medical Systems"], + ["Manufacturer Model Name", "Gyroscan Intera"], + ["Sequence Variant", "OTHER"], + ["7fe0|0010", "gdcm::NotLoaded. Address:6584 Length:131072"] ] ], + ["gdcm-MR-PHILIPS-16-NonRectPix.dcm", + # Interest: - pixels are non rectangular + # - private elements are in explicit VR (which is normal) + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Explicit VR, LE + ["Modality", "MR"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "64"], + ["Columns", "160"], + ["Bits Stored", "12"], + ["Bits Allocated", "16"], + ["High Bit", "11"], + ["Pixel Representation", "0"], + ["Manufacturer", "Philips Medical Systems"], + ["Manufacturer Model Name", "Gyroscan Intera"], + ["Pixel Spacing", "0.487416\\0.194966"], + ["7fe0|0010", "gdcm::NotLoaded. Address:5010 Length:20480"] ] ], + ["gdcm-CR-DCMTK-16-NonSamplePerPix.dcm", + # Interest: - Misses the "Samples Per Pixel" element which prevents + # e-film from reading it. + # - Misses the Manufacturer related info + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Explicit VR, LE + ["Modality", "CR"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "750"], + ["Columns", "750"], + ["Bits Stored", "8"], + ["Bits Allocated", "8"], + ["High Bit", "7"], + ["Pixel Representation", "0"], + ["Implementation Version Name", "OFFIS_DCMTK_341"], + ["7fe0|0010", "gdcm::NotLoaded. Address:740 Length:562500"] ] ], + ] + + GdcmJpegFiles = [ + ["gdcm-JPEG-Extended.dcm", + # Interest: Jpeg compression [Extended (2,4)] + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.51"], + ["Modality", "CT"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "12"], + ["Bits Allocated", "16"], + ["High Bit", "11"], + ["Pixel Representation", "0"], + ["Manufacturer", "SIEMENS"], + ["Manufacturer Model Name", "Volume Zoom"], + ["7fe0|0010", "gdcm::NotLoaded. Address:2946 Length:192218"] ] ], + ["MR-MONO2-12-shoulder.dcm", + # Interest: Jpeg compression [Lossless, non-hierar. (14)] + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.57"], + ["Modality", "MR"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "1024"], + ["Columns", "1024"], + ["Bits Stored", "12"], + ["Bits Allocated", "16"], + ["High Bit", "11"], + ["Pixel Representation", "0"], + ["Manufacturer", "Philips Medical Systems"], + ["Manufacturer Model Name", "Gyroscan NT"], + ["7fe0|0010", "gdcm::NotLoaded. Address:1580 Length:718948"] ] ], + ["gdcm-JPEG-LossLess3a.dcm", + # Interest: - Jpeg compression [Lossless, hierar., first-order + # pred. 14, Select. Val. 1] + # - contains a sequence [circa (0008,2112)] + # - contains additional data after the pixels ??? + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], + ["Modality", "CT"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "512"], + ["Columns", "512"], + ["Bits Stored", "12"], + ["Bits Allocated", "16"], + ["High Bit", "11"], + ["Pixel Representation", "0"], + ["Manufacturer", "SIEMENS"], + ["Manufacturer Model Name", "Volume Zoom"] ] ], + # FIXME: the pixel data looks like corrupted. As stated by "od -A d -c" + # 0002528 à 177 020 \0 O B \0 \0 ÿ ÿ ÿ ÿ þ ÿ \0 à + # 0002544 \0 \0 \0 \0 þ ÿ \0 à 202 ? 003 \0 ÿ Ø ÿ Ã + # which we interpret as follows: + # - 2528: (à 177, 020 \0) = (0x7fe0, 0x0010) i.e. Pixel Data tag, + # - 2532: OB i.e. encapsulated encoded Pixel Data, + # - 2534: Two bytes reserved, + # - 2536: ÿ ÿ ÿ ÿ = 0xffffffff i.e. data element length is undefined. + # - 2540: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. basic offset table + # item tag + # - 2544: \0 \0 \0 \0 i.e. offset table as length zero, i.e. no + # item value for offset table. + # - 2548: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. item tag of first + # fragment of (encoded) pixel data. + # - 2552: 202 ? 003 \0 = 212866 bytes i.e. length of first fragment + # of (encoded) pixel data. + # and so the next item tag should be found at the 2556+212866 th + # octet i.e. at address 215422. But, as stated by od, we find: + # 0215408 E u Ö 026 Î É 7 ¬ Ã ¸ ó ¿ ÿ Ù \f ° + # 0215424 ¶ 016 P Ñ 002 016 + # and (\f °, ¶ 016) is NOT an OB item TAG which is required to be + # present (at least there should be a sequence delimiter), refer to + # PS 3.5-2001 page 50. + ["gdcm-JPEG-LossLess3b.dcm", + # Interest: - Jpeg compression [Lossless, hierar., first-order + # pred. 14, Select. Val. 1] + # - encoding is sligthly different from LossLess3a.dcm ??? + [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], + ["Modality", "CR"], + ["Photometric Interpretation", "MONOCHROME2"], + ["Rows", "2076"], + ["Columns", "1876"], + ["Bits Stored", "15"], + ["Bits Allocated", "16"], + ["High Bit", "14"], + ["Pixel Representation", "0"], + ["Manufacturer", "Philips Medical Systems"], + ["Manufacturer Model Name", "Cassette Holder Type 9840 500 35201"], + ["7fe0|0010", "gdcm::NotLoaded. Address:3144 Length:4795668"] ] ], + ] + + def _BaseTest(self, FileSet): + for entry in FileSet: + fileName = os.path.join(GDCM_DATA_PATH, entry[0]) + toRead = gdcmHeader(fileName) + toRead.LoadElements() + valDict = toRead.GetPubElVal() + for subEntry in entry[1]: + element = subEntry[0] + value = subEntry[1] + self.assertEqual(valDict[element], value, + ("Wrong %s for file %s (got %s, shoud be %s)" + % (element,fileName, valDict[element], value)) ) + + def testBarre(self): + gdcmTestCase._BaseTest(self, gdcmTestCase.BarreFiles) + + def testMultiFram(self): + gdcmTestCase._BaseTest(self, gdcmTestCase.MultiFrameFiles) + + def testFiles(self): + gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmFiles) + + def testJpeg(self): + gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmJpegFiles) + +if __name__ == '__main__': + unittest.main() + diff --git a/gdcmPython/win32/gdcmpy.dsp b/gdcmPython/win32/gdcmpy.dsp new file mode 100644 index 00000000..36485ffe --- /dev/null +++ b/gdcmPython/win32/gdcmpy.dsp @@ -0,0 +1,146 @@ +# Microsoft Developer Studio Project File - Name="gdcmpy" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=gdcmpy - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gdcmpy.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gdcmpy.mak" CFG="gdcmpy - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gdcmpy - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "gdcmpy - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gdcmpy - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDCMPY_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /w /W0 /GX /O2 /I "$(CREATIS)\python22\include" /I "..\..\src" /I "$(CREATIS)\glib-1.3\src\glib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDCMPY_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib c:/creatis/python21/libs/python21.lib /nologo /dll /machine:I386 /out:"../_gdcm.dll" +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Cmds=copy gdcm.py ..\*.* +# End Special Build Tool + +!ELSEIF "$(CFG)" == "gdcmpy - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDCMPY_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /w /W0 /Gm /GX /ZI /Od /I "$(CREATIS)\python22\include" /I "..\..\src" /I "$(CREATIS)\glib-1.3\src\glib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDCMPY_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib c:/creatis/python21/libs/python21_d.lib /nologo /dll /debug /machine:I386 /out:"../_gdcm_d.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gdcmpy - Win32 Release" +# Name "gdcmpy - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\gdcm.i + +!IF "$(CFG)" == "gdcmpy - Win32 Release" + +# Begin Custom Build +ProjDir=. +InputPath=..\gdcm.i +InputName=gdcm + +"$(ProjDir)\$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + C:\creatis\SWIG\swig -python -c++ -I..\..\src -o $(ProjDir)\$(InputName)_wrap.cxx $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "gdcmpy - Win32 Debug" + +# Begin Custom Build - C:\creatis\SWIG-1.3.16\swig -python -c++ -I ..\..\src -o $(ProjDir)\$(InputName)_wrap.c $(InputPath) +ProjDir=. +InputPath=..\gdcm.i +InputName=gdcm + +"$(ProjDir)\$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + C:\creatis\SWIG\swig -python -c++ -I..\..\src -o $(ProjDir)\$(InputName)_wrap.cxx $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gdcm_wrap.cxx +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\src\win32\gdcmdll\Release\gdcmdll.lib +# End Source File +# End Target +# End Project diff --git a/gdcmPython/win32/gdcmpycomplet.dsp b/gdcmPython/win32/gdcmpycomplet.dsp new file mode 100644 index 00000000..e2dc3ab2 --- /dev/null +++ b/gdcmPython/win32/gdcmpycomplet.dsp @@ -0,0 +1,196 @@ +# Microsoft Developer Studio Project File - Name="gdcmpycomplet" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=gdcmpycomplet - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gdcmpycomplet.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gdcmpycomplet.mak" CFG="gdcmpycomplet - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gdcmpycomplet - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "gdcmpycomplet - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gdcmpycomplet - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "gdcmpycomplet___Win32_Release" +# PROP BASE Intermediate_Dir "gdcmpycomplet___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "gdcmpycomplet___Win32_Release" +# PROP Intermediate_Dir "gdcmpycomplet___Win32_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDCMPYCOMPLET_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /w /W0 /GX /O2 /I "$(CREATIS)\python22\include" /I "..\..\..\src" /I "$(CREATIS)\glib-1.3\src\glib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDCMPYCOMPLET_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib Wsock32.lib /nologo /dll /machine:I386 /out:"../_gdcm.dll" +# Begin Special Build Tool +ProjDir=. +SOURCE="$(InputPath)" +PostBuild_Cmds=move $(ProjDir)\gdcm.py $(ProjDir)\..\ +# End Special Build Tool + +!ELSEIF "$(CFG)" == "gdcmpycomplet - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "gdcmpycomplet___Win32_Debug" +# PROP BASE Intermediate_Dir "gdcmpycomplet___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "gdcmpycomplet___Win32_Debug" +# PROP Intermediate_Dir "gdcmpycomplet___Win32_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDCMPYCOMPLET_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /w /W0 /Gm /GX /ZI /Od /I "$(CREATIS)\python22\include" /I "..\..\..\src" /I "$(CREATIS)\glib-1.3\src\glib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDCMPYCOMPLET_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib Wsock32.lib /nologo /dll /debug /machine:I386 /out:"../_gdcm_d.dll" /pdbtype:sept +# Begin Special Build Tool +ProjDir=. +SOURCE="$(InputPath)" +PostBuild_Cmds=mv $(ProjDir)\gdcm.py $(ProjDir)\..\ +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "gdcmpycomplet - Win32 Release" +# Name "gdcmpycomplet - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\gdcm.i + +!IF "$(CFG)" == "gdcmpycomplet - Win32 Release" + +# Begin Custom Build +ProjDir=. +InputPath=..\gdcm.i +InputName=gdcm + +"$(ProjDir)\$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + C:\creatis\SWIG\swig -python -c++ -I..\..\..\src -o $(ProjDir)\$(InputName)_wrap.cxx $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "gdcmpycomplet - Win32 Debug" + +# Begin Custom Build - Performing Custom Build Step on $(InputPath) +ProjDir=. +InputPath=..\gdcm.i +InputName=gdcm + +"$(ProjDir)\$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + C:\creatis\SWIG\swig -python -c++ -I..\..\..\src -o $(ProjDir)\$(InputName)_wrap.cxx $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gdcm_wrap.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmDict.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmDictEntry.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmDictSet.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmElValSet.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmElValue.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmException.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmException.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmFile.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmHeader.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmHeaderIdo.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gdcmUtil.cxx +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=..\..\..\..\..\Python22\libs\python22.lib +# End Source File +# End Group +# End Target +# End Project diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..acb4caef --- /dev/null +++ b/setup.py @@ -0,0 +1,48 @@ +from distutils.core import setup +import glob, os, sys, shutil +from distutilsSwigCPlusPlus import * + +ThisModule='gdcmPython' +gdcmPythonSrcDir=ThisModule +gdcmSrcDir ="src" +gdcmDictsDir ="Dicts" +gdcmDataDir ="Data" + +# Due to a disutil oddity on Unices : see +# http://aspn.activestate.com/ASPN/Mail/Message/distutils-sig/588325 +if(os.name=='posix'): + targetDir=os.path.join('lib','python'+sys.version[:3],'site-packages') + libraries=["stdc++"] +else: + targetDir=os.path.join('lib','site-packages') + libraries=["WSOCK32"] + +targetDir=os.path.join(targetDir, ThisModule) + +Sources = [] +Sources.extend(glob.glob(os.path.join(gdcmSrcDir,"*.cxx"))) +Sources.extend(glob.glob(os.path.join(gdcmSrcDir,"*.h"))) +Sources.append(os.path.join(gdcmPythonSrcDir,"gdcm.i")) + +setup(name=ThisModule, + version="0.1", + description="...", + author="frog", + author_email="frog@creatis.insa-lyon.fr", + url="http://www.creatis.insa-lyon.fr/", + packages=[ gdcmPythonSrcDir, + gdcmPythonSrcDir + '.demo' ], + cmdclass={'build_ext':mybuild_ext}, # redirects default build_ext + ext_modules=[MyExtension( + name='_gdcm', + sources=Sources, + include_dirs=[gdcmSrcDir], + libraries=libraries, + swig_cpp=1, + swig_include=[ gdcmSrcDir] ) ], + data_files=[(os.path.join(targetDir,"Data"), + glob.glob(os.path.join(gdcmDataDir,"*.*"))), + (os.path.join(targetDir,"Dicts"), + glob.glob(os.path.join(gdcmDictsDir,"*.*"))), + ] + )