From 9a647e1121ce24849974b420b8b75d6a74c20b9b Mon Sep 17 00:00:00 2001 From: frog Date: Wed, 15 May 2002 20:12:36 +0000 Subject: [PATCH] Initial revision --- Makefile | 25 +++++++++ README | 1 + dcm.i | 7 +++ dcmlib.h | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 Makefile create mode 100644 README create mode 100644 dcm.i create mode 100644 dcmlib.h diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..3da31f28 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ + +###CC = gcc +###LINK = gcc -shared -o ptinpoly.so +SWIG = ~/Local/bin/swig +SWIGFLAGS= -python -c++ + +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=$(PYTHON_INCLUDES) + +%.o : %.cxx + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ +%_wrap.cxx : %.i + $(SWIG) $(SWIGFLAGS) $(PYTHON_INCLUDES) -o $@ $< + +all: dcm_wrap.o + +clean: + rm -f *_wrap* *.so *.o *.pyc + +.SECONDARY: dcm_wrap.cxx + diff --git a/README b/README new file mode 100644 index 00000000..a1d5c20d --- /dev/null +++ b/README @@ -0,0 +1 @@ +Requires Swig version >= 1.3.11 for handling member overloading. diff --git a/dcm.i b/dcm.i new file mode 100644 index 00000000..c2b404a4 --- /dev/null +++ b/dcm.i @@ -0,0 +1,7 @@ +%module dcm +%{ +#include "dcmlib.h" +%} +%rename(new_dcmHeader_c) dcmHeader::dcmHeader(char*); + +%include dcmlib.h diff --git a/dcmlib.h b/dcmlib.h new file mode 100644 index 00000000..7f43acb9 --- /dev/null +++ b/dcmlib.h @@ -0,0 +1,166 @@ +// Terminology : +// * in DCMlib tag = (group, element, name, value representation) e.g. +// (0x0010, 0x0010, "Patient_Name", _ID_Patient_Name +// group = 16 bit integer +// element = 16 bit integer +// name = char * ("Patient_Name") +// value representation (e.g. "AE" = "Application Entity", +// "FD", "Floating Point Double") +// * in DCMTK tag = (group, element) but they are many more fields in +// the implementation (see below). What are the relevant ones ? +// struct DBI_SimpleEntry { +// Uint16 group; +// Uint16 element; +// Uint16 upperGroup; +// Uint16 upperElement; +// DcmEVR evr; +// const char* tagName; +// int vmMin; +// int vmMax; +// const char* standardVersion; +// DcmDictRangeRestriction groupRestriction; +// DcmDictRangeRestriction elementRestriction; +// }; +// +// static const DBI_SimpleEntry simpleBuiltinDict[] = { +// { 0x0000, 0x0000, 0x0000, 0x0000, +// EVR_UL, "CommandGroupLength", 1, 1, "dicom98", +// DcmDictRange_Unspecified, DcmDictRange_Unspecified },...} + +// +// Open questions: +// * in libido a dictionary entry goes : +// {0x0018,0x1251,"SH","ACQ","Transmitting Coil"}. What does the fourth +// entry refer to ? +// * what type of Dicom files can this library read ? ACR/NEMA/Dicom v2 +// or v3 part10 ? dcmtk/dcmdata/docs/datadict.txt mentions :all +// standard DICOM tags (including those found in supplements 1, 2, 3, 4, 5, +// 6, 7, 8, 9, 10), obsolete ACR/NEMA version 2 tags, obsolete SPI tags, and +// the tags used by Papyrus version 3... +// Note en DCMTK the dictionary contains a standard version entry, like +// "dicom98", dicom99", "ACR/NEMA2" +// * the convertion from VR to native types depends on native types of +// target language (Python, Tcl a priori don't share the same native +// representations). Where should this go ? +// * the dcmHeader::Set*Tag* family members cannot be defined as protected +// (Swig limitations for as Has_a dependency between dcmFile and dcmHeader) +// +// Plateforms: Un*xes and Win32/VC++6.0 or Win32/Cygwin + + +#include // For size_t +// Dummy declaration for the time being +typedef int Dict; +typedef int gint16; // We shall need glib.h ! + +// The typical usage of objects of this class is to classify a set of +// dicom files according to header information e.g. to create a file hierachy +// reflecting the Patient/Study/Serie informations, or extracting a given +// SerieId. Accesing the content (image[s] or volume[s]) is beyond the +// functionality of this class (see dmcFile below). +class dcmHeader { +private: + Dict* PubDict; // Public Dictionary + Dict* ShaDict; // Shadow Dictionary (optional) + int swapcode; +public: + dcmHeader(); + dcmHeader(char* filename); + ~dcmHeader(); + + // Retrieve all potentially available tag [tag = (group, element)] names + // from the standard (or public) dictionary (hence static). Typical usage: + // enable the user of a GUI based interface to select his favorite fields + // for sorting or selection. + static char ** GetDcmTagNames(); + char* GetDcmTag(char* TagName); + // Value Representation (VR) might be needed by caller to convert the + // string typed content to caller's native type (think of C/C++ vs + // Python). + char* GetDcmTagValRep(char* TagName); + + // When some proprietary shadow groups are disclosed, whe can set + // up an additional specific dictionary to access extra information. + int SetShadowDict(char* filename); + int SetShadowDict(char** dictionary); //???????? + int AddShadowDict(char* filename); //???????? + int DelShadowDict(); + + // Retrieve all potentially available shadowed tag names + char** GetShadowTagNames(); + char* GetShadowTag(char* TagName); + + int SetTag(char* content, gint16 group, gint16 element); + int SetTagByName(char* content, char* TagName); + int SetShadowTag(char* content, gint16 group, gint16 element); + int SetShadowTagByName(char* content, char* ShadowTagName); + + // Enable caller's low-level manual access to shadowed info + char* GetDcmTagByNumber(gint16 group, gint16 element); + // Does this make ANY sense ? + char* GetDcmTagByNumberValRep(char* TagName); + int GetSwapCode(); +}; + +// In addition to Dicom header exploration, this class is designed +// for accessing the image/volume content. One can also use it to +// write Dicom files. +class dcmFile +{ +private: + dcmHeader* Header; + void* Data; + int Parsed; // weather allready parsed + char* OrigalFileName; // To avoid file overwrite +public: + // Constructor dedicated to writing a new DICOMV3 part10 compliant + // file (see SetFileName, SetDcmTag and Write) + dcmFile(); + // Opens (in read only and when possible) an existing file and checks + // for DICOM compliance. Returns NULL on failure. + // Note: the in-memory representation of all available tags found in + // the DICOM header is post-poned to first header information access. + // This avoid a double parsing of public part of the header when + // one sets an a posteriori shadow dictionary (efficiency can be + // seen a a side effect). + dcmFile(char* filename); + // For promotion (performs a deepcopy of pointed header object) + dcmFile(dcmHeader* header); + ~dcmFile(); + + // On writing purposes. When instance was created through + // dcmFile(char* filename) then the filename argument MUST be different + // from the constructor's one (no overwriting aloud). + int SetFileName(char* filename); + + // Allocates necessary memory, copies the data (image[s]/volume[s]) to + // newly allocated zone and return a pointer to it: + void * GetImageData(); + // Returns size (in bytes) of required memory to contain data + // represented in this file. + size_t GetImageDataSize(); + // Copies (at most MaxSize bytes) of data to caller's memory space. + // Returns an error code on failure (if MaxSize is not big enough) + int GetImageDataHere(void* destination, size_t MaxSize ); + // Allocates ExpectedSize bytes of memory at this->Data and copies the + // pointed data to it. + int SetImageData(void * Data, size_t ExpectedSize); + // Push to disk. + int Write(); + +///// Repeat here all the dcmHeader public members !!! +}; + +//class dcmSerie : dcmFile; +//class dcmMultiFrame : dcmFile; + +// +//Examples: +// * dcmFile WriteDicom; +// WriteDicom.SetFileName("MyDicomFile.dcm"); +// string * AllTags = dcmHeader.GetDcmTagNames(); +// WriteDicom.SetDcmTag(AllTags[5], "253"); +// WriteDicom.SetDcmTag("Patient Name", "bozo"); +// WriteDicom.SetDcmTag("Patient Name", "bozo"); +// WriteDicom.SetImageData(Image); +// WriteDicom.Write(); -- 2.45.1