DICOMNIfTI/0000770000121300000240000000000011573434404012047 5ustar valeriogamesDICOMNIfTI/AUTHORS0000660000121300000240000000004711573434404013121 0ustar valeriogamesvalerio luccio (valerio.luccio@nyu.edu)DICOMNIfTI/build/0000770000121300000240000000000011573434403013145 5ustar valeriogamesDICOMNIfTI/CMakeLists.txt0000660000121300000240000000757211573434404014623 0ustar valeriogamescmake_minimum_required(VERSION 2.6) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) # Define project name and identify as C++ PROJECT(DINIFTI CXX C) # Configure man dir (but hide option for regular user) SET( DINIFTI_MAN_DIR man/man1 CACHE PATH "Directory where manpages will be installed." ) MARK_AS_ADVANCED( DINIFTI_MAN_DIR ) # Configure toplevel directories SET( PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "Top level.") SET( INCLUDEDIR ${PREFIX}/include CACHE PATH "Include files.") SET( LIBDIR ${PREFIX}/lib CACHE PATH "Libraries.") # Configure CTN FIND_PATH( DINIFTI_CTN_INCLUDE dicom.h PATHS ${INCLUDEDIR} PATH_SUFFIXES ctn DOC "Path to the CTN headers." ) FIND_LIBRARY( DINIFTI_CTN_LIB ctn PATHS ${LIBDIR} PATH_SUFFIXES ctn DOC "Location of the CTN library." ) # Configure NIfTI (+ znzlib) FIND_PATH( DINIFTI_NIFTIIO_INCLUDE nifti1.h PATHS ${INCLUDEDIR} PATH_SUFFIXES nifti niftilib libnifti DOC "Path to the NIfTIio library headers." ) FIND_PATH( DINIFTI_ZNZ_INCLUDE znzlib.h PATHS ${INCLUDEDIR} PATH_SUFFIXES znz znzlib libznz nifti libnifti niftilib DOC "Path to the znzlib headers." ) FIND_LIBRARY( DINIFTI_NIFTIIO_LIB niftiio PATHS ${LIBDIR} PATH_SUFFIXES nifti libnifti niftilib DOC "Location of the NIfTIio library." ) FIND_LIBRARY( DINIFTI_ZNZ_LIB znz PATHS ${LIBDIR} PATH_SUFFIXES znz libznz znzlib DOC "Location of the znz library." ) # platform dependent stuff INCLUDE( TestBigEndian ) TEST_BIG_ENDIAN(DINIFTI_IS_BIG_ENDIAN) IF(DINIFTI_IS_BIG_ENDIAN) # do whatever is necessary if system if big endian ADD_DEFINITIONS( -DARCHITECTURE=BIG_ENDIAN_ARCHITECTURE ) ELSE(DINIFTI_IS_BIG_ENDIAN) # for the little ones ADD_DEFINITIONS( -DARCHITECTURE=LITTLE_ENDIAN_ARCHITECTURE ) ENDIF(DINIFTI_IS_BIG_ENDIAN) IF(APPLE) # put MacOS X specific configuration here ADD_DEFINITIONS( -DOSX -DOS=OSX ) ELSEIF(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") # put Linux/Unix specific stuff here ADD_DEFINITIONS( -DLINUX -DOS=LINUX ) ENDIF(APPLE) ADD_DEFINITIONS( -DHAVE_ZLIB ) INCLUDE(CheckTypeSize) CHECK_TYPE_SIZE(short SHORTSIZE) ADD_DEFINITIONS( -DSHORTSIZE=${SHORTSIZE}*8) CHECK_TYPE_SIZE(int INTSIZE) ADD_DEFINITIONS( -DINTSIZE=${INTSIZE}*8) CHECK_TYPE_SIZE(long LONGSIZE) ADD_DEFINITIONS( -DLONGSIZE=${LONGSIZE}*8) # add all include paths INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include ${DINIFTI_CTN_INCLUDE} ${DINIFTI_NIFTIIO_INCLUDE} ) # Configure default install path IF( NOT DEFINED BINDIR ) SET( BINDIR ${PREFIX}/bin CACHE PATH "Where the executable goes.") ENDIF( NOT DEFINED BINDIR ) # dinifti ADD_EXECUTABLE(dinifti src/dinifti.cc src/dicomInfo.cc src/niftiout.cc) TARGET_LINK_LIBRARIES( dinifti ${DINIFTI_CTN_LIB} ${DINIFTI_NIFTIIO_LIB} ${DINIFTI_ZNZ_LIB} z ) # dicomhead ADD_EXECUTABLE(dicomhead src/dicomhead.cc src/dicomInfo.cc) TARGET_LINK_LIBRARIES( dicomhead ${DINIFTI_CTN_LIB} ) # Optional "OPTIMIZED" and "DEBUG" modes IF(OPTIMIZED) ADD_DEFINITIONS( -O ) SET_TARGET_PROPERTIES( dinifti dicomhead PROPERTIES LINK_FLAGS -O ) ENDIF(OPTIMIZED) IF(DEBUG) IF(APPLE) ADD_DEFINITIONS(-g) SET_TARGET_PROPERTIES( dinifti dicomhead PROPERTIES LINK_FLAGS -g ) ELSEIF(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") ADD_DEFINITIONS(-ggdb) SET_TARGET_PROPERTIES( dinifti dicomhead PROPERTIES LINK_FLAGS -ggdb ) ENDIF(APPLE) ENDIF(DEBUG) # configure where to install binaries INSTALL(TARGETS dinifti dicomhead RUNTIME DESTINATION ${BINDIR} COMPONENT RuntimeLibraries ) # install manpages FILE( GLOB DINIFTI_MANPAGES "man/*.1" ) INSTALL( FILES ${DINIFTI_MANPAGES} DESTINATION ${DINIFTI_MAN_DIR} ) DICOMNIfTI/config.guess0000770000121300000240000010047511573434404014376 0ustar valeriogames#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 # Free Software Foundation, Inc. # # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Written by Per Bothner . # Please send patches to . # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit system type (host/target name). # # Only a few systems have been added to this list; please add others # (but try to keep the structure clean). # # Use $HOST_CC if defined. $CC may point to a cross-compiler if test x"$CC_FOR_BUILD" = x; then if test x"$HOST_CC" != x; then CC_FOR_BUILD="$HOST_CC" else if test x"$CC" != x; then CC_FOR_BUILD="$CC" else CC_FOR_BUILD=cc fi fi fi # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 8/24/94.) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown dummy=dummy-$$ trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # Netbsd (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # Determine the machine/vendor (is the vendor relevant). case "${UNAME_MACHINE}" in amiga) machine=m68k-cbm ;; arm32) machine=arm-unknown ;; atari*) machine=m68k-atari ;; sun3*) machine=m68k-sun ;; mac68k) machine=m68k-apple ;; macppc) machine=powerpc-apple ;; hp3[0-9][05]) machine=m68k-hp ;; ibmrt|romp-ibm) machine=romp-ibm ;; *) machine=${UNAME_MACHINE}-unknown ;; esac # The Operating System including object format. if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi # The OS release release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. cat <$dummy.s .data \$Lformat: .byte 37,100,45,37,120,10,0 # "%d-%x\n" .text .globl main .align 4 .ent main main: .frame \$30,16,\$26,0 ldgp \$29,0(\$27) .prologue 1 .long 0x47e03d80 # implver \$0 lda \$2,-1 .long 0x47e20c21 # amask \$2,\$1 lda \$16,\$Lformat mov \$0,\$17 not \$1,\$18 jsr \$26,printf ldgp \$29,0(\$26) mov 0,\$16 jsr \$26,exit .end main EOF $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then case `./$dummy` in 0-0) UNAME_MACHINE="alpha" ;; 1-0) UNAME_MACHINE="alphaev5" ;; 1-1) UNAME_MACHINE="alphaev56" ;; 1-101) UNAME_MACHINE="alphapca56" ;; 2-303) UNAME_MACHINE="alphaev6" ;; 2-307) UNAME_MACHINE="alphaev67" ;; esac fi rm -f $dummy.s $dummy echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-cbm-sysv4 exit 0;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; arc64:OpenBSD:*:*) echo mips64el-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hkmips:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; atari*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; sun3*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy \ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i?86:AIX:*:*) echo i386-ibm-aix exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:4) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=4.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` rm -f $dummy.c $dummy esac HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i?86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; hppa*:OpenBSD:*:*) echo hppa-unknown-openbsd exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; F300:UNIX_System_V:*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; F301:UNIX_System_V:*:*) echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i386-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. ld_help_string=`cd /; ld --help 2>&1` ld_supported_emulations=`echo $ld_help_string \ | sed -ne '/supported emulations:/!d s/[ ][ ]*/ /g s/.*supported emulations: *// s/ .*// p'` case "$ld_supported_emulations" in *ia64) echo "${UNAME_MACHINE}-unknown-linux" exit 0 ;; i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit 0 ;; elf_i?86) echo "${UNAME_MACHINE}-pc-linux" exit 0 ;; i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit 0 ;; sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" exit 0 ;; armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" exit 0 ;; elf32arm*) echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" exit 0 ;; armelf_linux*) echo "${UNAME_MACHINE}-unknown-linux-gnu" exit 0 ;; m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" exit 0 ;; elf32ppc | elf32ppclinux) # Determine Lib Version cat >$dummy.c < #if defined(__GLIBC__) extern char __libc_version[]; extern char __libc_release[]; #endif main(argc, argv) int argc; char *argv[]; { #if defined(__GLIBC__) printf("%s %s\n", __libc_version, __libc_release); #else printf("unkown\n"); #endif return 0; } EOF LIBC="" $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null if test "$?" = 0 ; then ./$dummy | grep 1\.99 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi fi rm -f $dummy.c $dummy echo powerpc-unknown-linux-gnu${LIBC} exit 0 ;; esac if test "${UNAME_MACHINE}" = "alpha" ; then cat <$dummy.s .data \$Lformat: .byte 37,100,45,37,120,10,0 # "%d-%x\n" .text .globl main .align 4 .ent main main: .frame \$30,16,\$26,0 ldgp \$29,0(\$27) .prologue 1 .long 0x47e03d80 # implver \$0 lda \$2,-1 .long 0x47e20c21 # amask \$2,\$1 lda \$16,\$Lformat mov \$0,\$17 not \$1,\$18 jsr \$26,printf ldgp \$29,0(\$26) mov 0,\$16 jsr \$26,exit .end main EOF LIBC="" $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then case `./$dummy` in 0-0) UNAME_MACHINE="alpha" ;; 1-0) UNAME_MACHINE="alphaev5" ;; 1-1) UNAME_MACHINE="alphaev56" ;; 1-101) UNAME_MACHINE="alphapca56" ;; 2-303) UNAME_MACHINE="alphaev6" ;; 2-307) UNAME_MACHINE="alphaev67" ;; esac objdump --private-headers $dummy | \ grep ld.so.1 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi fi rm -f $dummy.s $dummy echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 elif test "${UNAME_MACHINE}" = "mips" ; then cat >$dummy.c < /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #ifdef __MIPSEB__ printf ("%s-unknown-linux-gnu\n", argv[1]); #endif #ifdef __MIPSEL__ printf ("%sel-unknown-linux-gnu\n", argv[1]); #endif return 0; } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy elif test "${UNAME_MACHINE}" = "s390"; then echo s390-ibm-linux && exit 0 else # Either a pre-BFD a.out linker (linux-gnuoldld) # or one that does not give us useful --help. # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. # If ld does not provide *any* "supported emulations:" # that means it is gnuoldld. echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 case "${UNAME_MACHINE}" in i?86) VENDOR=pc; ;; *) VENDOR=unknown; ;; esac # Determine whether the default compiler is a.out or elf cat >$dummy.c < #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif #else printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); #endif return 0; } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy fi ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. i?86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; i?86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i?86:*:5:7*) # Fixed at (any) Pentium or better UNAME_MACHINE=i586 if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; i?86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; i?86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:*:6*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) echo `uname -p`-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) if test "${UNAME_MACHINE}" = "x86pc"; then UNAME_MACHINE=pc fi echo `uname -p`-${UNAME_MACHINE}-nto-qnx exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSR-W:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) printf ("vax-dec-bsd\n"); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi #echo '(Unable to guess system type)' 1>&2 exit 1 DICOMNIfTI/config.sub0000770000121300000240000007540711573434404014047 0ustar valeriogames#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-02-10' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | msp430 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | msp430-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; or32 | or32-*) basic_machine=or32-unknown os=-coff ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sh64) basic_machine=sh64-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: DICOMNIfTI/configure.ac0000660000121300000240000000160111573434404014334 0ustar valeriogames# $Id: configure.ac,v 1.4 2005-12-12 22:19:14 valerio Exp $ AC_INIT(DICOMNIfTI, 1.0) dnl Checks the host. For now just Gnu-Linux and OSX-Darwin AC_CANONICAL_HOST system=$host case $system in sparc-sun-solaris2.*) OS_TYPE = "SOLARIS" OS_DBGF = "-g" ;; *-linux*) OS_TYPE="LINUX" OS_DBGF="-ggdb" ;; powerpc-apple-darwin*) OS_TYPE="OSX" LIBS="-lz" OS_DBGF="-g" PROC_TYPE="POWERPC" ;; i*-apple-darwin*) OS_TYPE="OSX" LIBS="-lz" OS_DBGF="-g" PROC_TYPE="INTEL" ;; esac AC_SUBST(OS_TYPE) AC_SUBST(OS_DBGF) AC_SUBST(PROC_TYPE) dnl this is to define where matlab lives AC_SUBST(TMW_ROOT) dnl Checks for programs. AC_PROG_CXX AC_PROG_CC AC_PROG_MAKE_SET AC_PROG_INSTALL dnl Checks for header files. AC_HEADER_STDC dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST dnl Checks for library functions. AC_OUTPUT(Makefile src/Makefile) DICOMNIfTI/COPYING0000770000121300000240000004307611573434404013117 0ustar valeriogames GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. DICOMNIfTI/include/0000770000121300000240000000000011767633531013501 5ustar valeriogamesDICOMNIfTI/include/dicomhead.h0000660000121300000240000000124211573434403015557 0ustar valeriogames#ifndef DICOMHEAD_H_INCLUDED #define DICOMHEAD_H_INCLUDED // $Id: dicomhead.h,v 1.2 2006-08-15 20:02:29 valerio Exp $ //**************************************************************************** // // Modification History (most recent first) // mm/dd/yy Who What // // 08/15/06 VPL GPL'ed it // 11/28/05 VPL // //**************************************************************************** #include #include #include #include #include using namespace std; using std::cin; using std::cout; using std::cerr; using std::endl; using std::setw; using std::ofstream; using std::ios; using std::string; #endif DICOMNIfTI/include/dicomInfo.h0000660000121300000240000001616411767633531015572 0ustar valeriogames#ifndef DICOMINFO_H_INCLUDED #define DICOMINFO_H_INCLUDED // $Id: dicomInfo.h,v 1.23 2007-11-15 16:20:44 valerio Exp $ //============================================================================ // CTN software is curtesy of // // Mallinckrodt Institute of Radiology // Washington University in St. Louis MO // http://wuerlim.wustl.edu/ // //============================================================================ //**************************************************************************** // // Modification History (most recent first) // mm/dd/yy Who What // // 10/17/11 VPL Added verbose parameter // 10/17/11 VPL Add optional haveNumSlices to constructor // 08/15/06 VPL GPL'ed it // 03/22/05 VPL Allow processing of multiple series // Add NYU License agreement // 01/17/03 VPL // //**************************************************************************** #include #include #include #include #include #include "dicom.h" #include "lst.h" #include "dicom_objects.h" #include "utility.h" #include "condition.h" typedef std::string::size_type size_type; std::string &DeSpace(std::string &strng); class DICOMImage { public: DICOMImage(const char *path, bool verbose = false, bool haveNumSlices = true); void AdjustSet(int numSlices, int imgDiff) { numSlices_ = numSlices; imageNum_ -= numSlices * (acqNum_ - 1) + imgDiff; } std::string &ImagePath() { return imgPath_; } std::string &SubjectID() { return subjID_; } std::string &SubjectName() { return subjName_; } int ImageNumber() const { return imageNum_; } bool Mosaic() const { return mosaic_; } bool D3() const { return d3_; } int NumSlices() const { return numSlices_; } int NumGroups() const { return numGroups_; } int GroupSize(int a = 0) { return groupSize_[a]; } int GroupStartImage(int a = 0) { return groupStartImage_[a]; } int GroupNumber(int imgNum = 1) { int gn = 0; while ( gn < numGroups_ ) { if ( imgNum < (groupStartImage_[gn] + groupSize_[gn]) ) break; ++gn; } // The gn index should never get to numGroups_, but you never know. return ( gn == numGroups_ ? 0 : gn ); } float SliceThickness() const { return sliceThickness_; } float SliceSpacing() const { return sliceSpacing_; } std::string &Comments() { return comments_; } int Columns() const { return columns_; } int Rows() const { return rows_; } float XFOV() const { return xFOV_; } float YFOV() const { return yFOV_; } int RepetitionTime() const { return repTime_; } std::string &SeriesID() { return seriesID_; } int FrequencyDim() const { return (phaseEncoding_ == 2 ? 1 : 2); } int PhaseDim() const { return phaseEncoding_; } float ImgRescaleSlope() const { return slope_; } float ImgRescaleIntercept() const { return intercept_; } std::string &SeriesDescription(){ return seriesDescription_; } std::string &SeriesNumber() { return seriesNumber_; } std::string &SeriesDate() { return seriesDate_; } std::string &SeriesTime() { return seriesTime_; } std::string &ACQDescription() { return acqDescription_; } std::string &Accession() { return accession_; } int ACQNumber() const { return acqNum_; } int ACQEchoNumber() const { return acqEchoNum_; } unsigned short ACQRows() const { return acqRows_; } unsigned short ACQColumns() const { return acqColumns_; } float RowSagCos() const { return rowCosines_[0]; } float RowCorCos() const { return rowCosines_[1]; } float RowTraCos() const { return rowCosines_[2]; } float ColSagCos() const { return colCosines_[0]; } float ColCorCos() const { return colCosines_[1]; } float ColTraCos() const { return colCosines_[2]; } float SagNorm() const { return sagNorm_; } float CorNorm() const { return corNorm_; } float TraNorm() const { return traNorm_; } float SagPos(int a = 0) const { return sagPos_[a]; } float CorPos(int a = 0) const { return corPos_[a]; } float TraPos(int a = 0) const { return traPos_[a]; } bool operator!() const { return error_; } operator void*() const { return error_ ? (void *)0 : (void *)this; } bool ReadSlice(U16 *data, int slice); bool ReadVolume(); void FreeVolume() { if ( volumeData_ != NULL) delete [] volumeData_; volumeData_ = NULL; } private: bool error_; bool verbose_; bool OpenFile(const char *path); bool GetImageNumber(); bool GetACQNumber(); bool GetACQEchoNumber(); bool GetACQMatrix(); bool GetMosaic(); bool GetD3(); bool GetNumSlices(); bool GetGroupsInfo(); bool GetSliceThickness(); bool GetSliceSpacing(); bool GetComments(); bool GetPosNorm(); bool GetPosNormSiemens(char *storage); bool GetColumns(); bool GetRows(); bool GetFOV(); bool GetTime(); bool GetRepetitionTime(); bool GetImgOrientation(); bool GetSeriesID(); bool GetPhaseEncoding(); bool GetImgRescaleIntercept(); bool GetImgRescaleSlope(); bool GetManufacturer(); bool GetSeriesDescription(); bool GetACQDescription(); bool MosaicAdjustments(); bool GetSubjectID(); bool GetSubjectName(); bool GetSeriesDate(); bool GetSeriesTime(); bool GetAccession(); bool GetSeriesNumber(); U32 GetData(DCM_TAG tag, char **storage); bool GetData(DCM_TAG tag, U32 *storage); bool GetData(DCM_TAG tag, U16 *storage); char *GetShadowSet(); DCM_OBJECT *handle_; std::string imgPath_; std::string subjID_; std::string subjName_; int imageNum_; int numGroups_; std::vector groupSize_; std::vector groupStartImage_; bool mosaic_; bool d3_; float sliceThickness_; float sliceSpacing_; std::string comments_; int acqNum_; int acqEchoNum_; unsigned short acqRows_; unsigned short acqColumns_; int columns_; int rows_; float xFOV_; float yFOV_; int repTime_; int phaseEncoding_; float intercept_; float slope_; unsigned short *volumeData_; std::string seriesID_; std::string seriesDescription_; std::string seriesNumber_; std::string acqDescription_; std::string seriesDate_; std::string seriesTime_; std::string accession_; enum MANUFACTURER {SIEMENS, GE, UNDEFINED}; MANUFACTURER manufacturer_; char *shadowSet_; std::vector rowCosines_; std::vector colCosines_; float sagNorm_; float corNorm_; float traNorm_; std::vector sagPos_; std::vector corPos_; std::vector traPos_; // Next are used only with Mosaics int numSlices_; int mosaicGridSize_; }; // Define a few usefull things: // // IMAGELIST: a list of DICOMImage objects, each describing and image // IMAGEMAP: a map of IMAGELISTs to timepoints, one list per time point // SERIESMAP: a map of IMAGEMAPs to series, one map per series typedef std::list IMAGELIST; typedef std::map IMAGEMAP; struct SeriesInfo { SeriesInfo() : mosaic(false), multiEcho(false), maxImgNum(0), minImgNum(0), maxAcqNum(0), minAcqNum(0), numSlices(0) {} std::string outName; bool mosaic; bool multiEcho; int maxImgNum; int minImgNum; int maxAcqNum; int minAcqNum; int numSlices; IMAGEMAP imageMap; }; typedef std::map SERIESMAP; #endif DICOMNIfTI/include/dinifti.h0000660000121300000240000000314011573434403015267 0ustar valeriogames#ifndef DINIFTI_H_INCLUDED #define DINIFTI_H_INCLUDED // $Id: dinifti.h,v 1.11 2007-10-15 17:16:28 valerio Exp $ //============================================================================ // CTN software is curtesy of // // Mallinckrodt Institute of Radiology // Washington University in St. Louis MO // http://wuerlim.wustl.edu/ // //============================================================================ //**************************************************************************** // // Modification History (most recent first) // mm/dd/yy Who What // // 10/04/06 Add DiniftiOptions class and verbose mode // (contributed by Michael Hanke) // 08/15/06 VPL GPL'ed it // 03/22/05 VPL Allow processing of multiple series // Add NYU License agreement // 01/24/05 VPL // //**************************************************************************** #include "dicomInfo.h" #define OUT_BUFFER_SIZE 1024*1024 // Need to do some prototyping to help us class DiniftiOptions; enum OUTPUT_TYPE { ANALYZE, NIfTI_SINGLE, NIfTI_DUAL, NIfTI_ASCII }; void StoreImageFiles(std::vector &dicomFiles, SERIESMAP &seriesMap, char *outName, const DiniftiOptions& opts); void ProcessSeries(SeriesInfo &seriesInfo, const DiniftiOptions& opts); class DiniftiOptions { public: DiniftiOptions() :useSerDesc(false), nameFormat(NULL), verbose(false), noact(false), numSlices(0), compressed(false), niftiFormat(NIfTI_SINGLE) {} bool useSerDesc; char *nameFormat; bool verbose; bool noact; int numSlices; bool compressed; OUTPUT_TYPE niftiFormat; }; #endif DICOMNIfTI/include/niftiout.h0000660000121300000240000000241111573434403015502 0ustar valeriogames#ifndef NIFTIOUT_H_INCLUDED #define NIFTIOUT_H_INCLUDED // $Id: niftiout.h,v 1.3 2006-08-15 20:02:29 valerio Exp $ //============================================================================ // CTN software is curtesy of // // Mallinckrodt Institute of Radiology // Washington University in St. Louis MO // http://wuerlim.wustl.edu/ // //============================================================================ //**************************************************************************** // // Modification History (most recent first) // mm/dd/yy Who What // // 08/15/06 VPL GPL'ed it // 03/22/05 VPL Allow processing of multiple series // Add NYU License agreement // 02/01/05 VPL // //**************************************************************************** #include #include #include #include #include using namespace std; using std::cin; using std::cout; using std::cerr; using std::endl; using std::ios; using std::string; typedef string::size_type size_type; #include "dinifti.h" #include "dicomInfo.h" #include "nifti1_io.h" class DICOMImage; bool NIfTICreateHeader(nifti_image &hdr, IMAGEMAP &imageMap); bool NIfTIWriteData(znzFile fp, nifti_image &hdr, IMAGEMAP &imageMap); #endif DICOMNIfTI/INSTALL0000660000121300000240000001005711573434404013104 0ustar valeriogamesRequirements ============ The program depends on the CTN library developed by the Mallinckrodt Institue of Radiology, Washington University in St. Louis MO, http://wuerlim.wustl.edu/. The source code can be downloaded from ftp://ftp.erl.wustl.edu/pub/dicom/software/ctn/ The program also depends on the nifticlib developed by the NIfTI project, http://nifti.nimh.nih.gov/. The source code can be downloaded from http://sourceforge.net/projects/niftilib. Basic Installation ================== Using cmake: ============ http://cmake.org/ 1. `cd' to the `build' subdirectory of the program's top level directory: cd $DINIFTI_ROOT/build 2. Type `cmake ..' to configure the package for your system. While running, cmake prints some messages telling which features it is checking for and what is missing. 3. Type `make all' to compile the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. USING GNU autoconf/configure: ============================= The file `configure.in' is used to create `configure' by a program called `autoconf'. You will need to run `autoconf' at least once to generate the correct `configure' shell script. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). 1. `cd' to the program's top level directory and type `autoconf'. You will need to do this only the first time you build, or if you are building on different architectures. 2. Type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 3. Type `make all' to compile the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by: USING cmake: ============ specifying it when running `cmake': cmake .. -DPREFIX:PATH= You can also specify separate include, lib and bin locations: cmake .. -DINCLUDEDIR:PATH= cmake .. -DLIBDIR:PATH= cmake .. -DBINDIR:PATH= All parameters can also be modified using `ccmake ..'. USING GNU autoconf/configure: ============================= by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. DICOMNIfTI/install-sh0000770000121300000240000001273611573434404014064 0ustar valeriogames#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 DICOMNIfTI/LICENSE0000660000121300000240000000300011573434404013046 0ustar valeriogamesCopyright (c) 2007, New York University All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * Neither the name of New York University nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. DICOMNIfTI/Makefile.in0000660000121300000240000000456211573434404014124 0ustar valeriogames# $Id: Makefile.in,v 1.1.1.1 2005-05-31 21:09:11 valerio Exp $ # -*- Mode: Makefile -*- # dbutils System Makefile. # # Autoconf/Configure tag. # @configure_input@ #============================================================================== # (Semi) Standard (GNU form) variable setup. # General Variables SHELL = /bin/sh # Installation Variables prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ includedir = @includedir@ libdir = @libdir@ libexecdir = @libexecdir@ mandir = @mandir@ # Build Variables top_srcdir = @top_srcdir@ srcdir = @srcdir@ # Variables for creating the source distribution SRC_DISTRIBUTION_FILES = Makefile.in \ configure \ configure.in \ config.sub \ config.guess \ install-sh \ README \ INSTALL \ RUNNING \ COPYRIGHT \ RELEASE-NOTES \ ChangeLog SRC_DISTRIBUTION_DIRS = src \ include \ examples \ doc DINIFTI_TARGETS = src INSTALL_TARGETS = src.i UNINSTALL_TARGETS = src.u CLEANING_TARGETS = src.clean # Targets. all: $(DINIFTI_TARGETS) @echo '' @echo "====================================================" @echo "System building: done." @echo '' # Standard targets. clean: $(CLEANING_TARGETS) @echo '' @echo "====================================================" @echo "System cleaning: done." @echo '' clean_dist: $(CLEANING_TARGETS) $(RM) core *~ \#* config.status config.log config.cache Makefile @echo '' @echo "====================================================" @echo "System cleaning for distribution: done." @echo '' dist: install: $(INSTALL_TARGETS) @echo '' @echo "====================================================" @echo "System install: done." @echo '' uninstall: #============================================================================== # Targets. FORCE: src: FORCE cd src; $(MAKE) all src.i: cd src; $(MAKE) install src.u: cd src; $(MAKE) uninstall src.clean: cd src; $(MAKE) clean include: FORCE cd include; $(MAKE) include.i: cd include; $(MAKE) install include.u: cd include; $(MAKE) uninstall include.clean: cd include; $(MAKE) clean libs: FORCE src.clean src # end of file -- Makefile -- DICOMNIfTI/man/0000770000121300000240000000000011573434404012622 5ustar valeriogamesDICOMNIfTI/man/dicomhead.10000660000121300000240000000120411573434404014617 0ustar valeriogames.TH "DICOMHEAD" "1" "August 2006" "Valerio Luccio" "User Commands" .SH "NAME" dicomhead \- prints a dump of the header data in DICOM images .SH "SYNOPSIS" \fBdicomhead\fR .SH "DESCRIPTION" \fBdicomhead\fR prints a dump of the information in the DICOM header of the specified image file. In addidtion to similar tools, \fBdicomhead\fR also extracts some information from the Siemens shadow set (number of groups, number of channels and sagital, axial and transverse position). .SH "AUTHOR" \fBdicomhead\fR is written by Valerio Luccio (valerio.luccio@nyu.edu). .SH "SEE ALSO" \fBHomepage:\fR http://cbi.nyu.edu/software/dinifti.php DICOMNIfTI/man/dinifti.10000660000121300000240000000733511573434404014343 0ustar valeriogames.TH "DINIFTI" "1" "August 2006" "Valerio Luccio" "User Commands" .SH "NAME" dinifti \- converts DICOM files into the NIfTI format .SH "SYNOPSIS" .BI "dinifti [" "options" "] " "" " " "" .SH "DESCRIPTION" \fBdinifti\fR converts a single or several files at once into the NIfTI data format. The DICOM input can be specified as a single filename, a list of file or a directory. In case of a directory all files in this directory will be converted. .PP Images belonging to the same recording series will be appropriately merged into a single 3d or 4d NIfTI file. To achieve this \fBdinifti\fR gathers the number of time points and number of slices per volume from the DICOM header. When this is impossible, \fBdinifti\fR will issue a warning (i.e. when it can find only 1 slice per volume and 1 time point). The user has the option of running the program using the \fB\-s\fR option and specifying the number of slices per volume. .PP A number of items are retrieved from the Siemens Shadow set. Following is a list of items and default value if this is not Siemens. .IP \fBNumber of groups\fR: 1 .IP \fBNumber of channels\fR: 1 .IP \fBSagital, Coronal and Transverse position\fR: From DICOM (0020,0032) .SH "OPTIONS" .TP \fB\-g\fR NIfTI files will be compressed. .TP \fB\-f\fR [a2|n2|n1] Set the output file format. If set to \fBa2\fR ANALYZE 7.5 file pairs (hdr/img) will be generates. Setting \fBn2\fR will cause \fBdinifti\fR to generate NIfTI image file pairs. The default output format (\fBn1\fR) are single NIfTI files (header and image data combined in one file). .TP \fB\-d\fR If set \fBdinifti\fR appends the series description from the DICOM header to the output file name(s). .IP If two image series share a common description \fBdinifti\fR will append as many \fB\fR characters as necessary to the second series description to create a unique filename. In this case a warning message is displayed that shows the old and the modified filename. .TP \fB\--name=""\fR Format output file name(s) according to string, which \fBhas to be enclosed in quotes (")\fR .IP The format is interpreted in the usual printf-like way. Ordinary characters are directly copied, a percent sign is represented by %%, otherwise % indicates a conversion. \fBThe special character "/" is translated to "~" to avoid confusion with the directory separator.\fR .IP .B If --name is present, -d flag will be ignored. .IP .B %I Subject ID .IP .B %N Subject name .IP .B %S Relative series number .IP .B %D Series description .IP .B %Y Series date (YYYYMMDD) .IP .B %T Series time (HHMM) .IP .B %A Accession number .IP .B %C Image comments .IP .B Example: --name="%Y:%T- %A - %I -%D(%S)" .TP \fB\-s\fR # This option can be used to specify the number of slices in the volume, if \fBdinifti\fR fails to autodetect the correct value. .TP \fB\-v\fR, \fB\-\-verbose\fR Enables verbose status messages. If any warning message occurs, this option can be helpful to determine which imageseries caused it. .TP \fB\-n\fR, \fB\-\-noact\fR If set, dinifti performs all processing steps, but does not write NIfTI files at the end. This can be useful to quickly inspect the content of a DICOM directory (if ran together with \fB--verbose\fR). .TP \fB\-h\fR, \fB\-\-help\fR Print this help page and exit. .TP \fB\-V\fR, \fB\-\-version\fR Print the version number and exit. .SH "AUTHOR" \fBdinifti\fR is written by Valerio Luccio (valerio.luccio@nyu.edu). .SH "SEE ALSO" \fBHomepage:\fR http://cbi.nyu.edu/software/dinifti.php .SH "MAILING LIST" \fBList page:\fR http://cbi.nyu.edu/mailman/listinfo/dinifti . \fBList email:\fR dinifti@cbi.nyu.edu .SH "LICENSE" The software is released under the standard BSD license: http://opensource.org/licenses/bsd-license.php DICOMNIfTI/README0000660000121300000240000000177211573434404012737 0ustar valeriogamesdinifti ======= The dinifti program converts MRI images stored in DICOM format to NIfTI format. For installation information see the INSTALL file. Distribution ------------ dinifti is licensed under the GNU General Public License (GPL), version 2. See COPYING. Usage ===== The program can convert single files, a list of files or a whole directory. If any of the input files are not in DICOM format, an error message will be printed, but the program will continue. Usage: dinifti [OPTION] Options: -g compressed output -f 'a2' - ANALYZE 7.5 Dual file 'n2' - NIfTI-2 Dual file 'n1' - NIfTI-1 Single file **Default** -d append series description to output file name(s) -h --help print this help and exit -v --version print version number and exit I/O Options can be single file, list of files or directory can be single file or directory DICOMNIfTI/src/0000770000121300000240000000000011773135740012641 5ustar valeriogamesDICOMNIfTI/src/dicomhead.cc0000660000121300000240000000355011573434404015066 0ustar valeriogames// $Id: dicomhead.cc,v 1.4 2006-08-15 21:30:17 valerio Exp $ //**************************************************************************** // // Modification History (most recent first) // mm/dd/yy Who What // // 11/28/05 VPL // //**************************************************************************** #include "dicomhead.h" #include "dicomInfo.h" int main(int argc, char **argv) { if (argc < 2) { cerr << "Usage: dicomhead " << endl << endl; exit(1); } DICOMImage *dcmImg = new DICOMImage(argv[1]); if (*dcmImg) { // Dump the header DCM_OBJECT *object; unsigned long options = DCM_ORDERLITTLEENDIAN | DCM_FORMATCONVERSION; printf("DICOM File: %s\n", argv[1]); if ( DCM_OpenFile(argv[1], options, &object) != DCM_NORMAL ) { DCM_CloseObject(&object); COND_PopCondition(TRUE); if (DCM_OpenFile(argv[1], options | DCM_PART10FILE, &object) != DCM_NORMAL ) { // Shouldn't happen since we've already opened it once COND_DumpConditions(); exit(1); } } if ( DCM_DumpElements(&object, 0) != DCM_NORMAL ) { COND_DumpConditions(); exit(1); } DCM_CloseObject(&object); // Append a couple of extra info's to the text file // To compute Z FOV (in mm) we need to know the spacing between slicing // and slice thickness. If the spacing is 0 (contigous) use only // thickness. float zfov = 0.; if ( (dcmImg->SliceSpacing() < 0.0001) && (dcmImg->SliceSpacing() > -0.0001) ) zfov = dcmImg->NumSlices() * dcmImg->SliceThickness(); else zfov = (dcmImg->NumSlices() - 1) * dcmImg->SliceSpacing() + dcmImg->SliceThickness(); cout << endl << "Z-Direction Cosines: {" << dcmImg->SagNorm() << ", " << dcmImg->CorNorm() << ", " << dcmImg->TraNorm() << "}" << endl << "Number of slices: " << dcmImg->NumSlices() << endl << "Z FOV (in mm): " << zfov << endl; } } DICOMNIfTI/src/dicomInfo.cc0000660000121300000240000013146111773135740015066 0ustar valeriogames// $Id: dicomInfo.cc,v 1.36 2008-01-22 19:08:11 valerio Exp $ //============================================================================ // DCM is part of the CTN library, curtesy of // // Mallinckrodt Institute of Radiology // Washington University in St. Louis MO // http://wuerlim.wustl.edu/ // //============================================================================ //**************************************************************************** // // Modification History (most recent first) // mm/dd/yy Who What // // 10/17/11 VPL Add verbose parameter // 10/17/11 VPL Add optional haveNumSlices to constructor // 03/22/05 VPL Allow processing of multiple series // Add NYU License agreement // 03/15/05 VPL Adjust some items after the fact if not mosaic // 03/08/05 VPL Make sure that we read shadow set only for mosaic images // //**************************************************************************** #include "dicomInfo.h" #include #include #include using namespace std; ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Replace white spaces and slashes with underscores in string /// /// @param strng - the string to be "despaced" /// /// @return strng - the cleaned string /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// string &DeSpace(string &strng) { size_type locsp = 0; while ( locsp < strng.size() ) { if ( (strng[locsp] == ' ') || (strng[locsp] == '/') ) strng[locsp] = '_'; ++locsp; } return strng; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Xctor for DICOMImage class /// /// @param path - path to the image /// verbose - show all messages /// haveNumSlices - don't need to read the number of slices from file ? /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// DICOMImage::DICOMImage(const char *path, bool verbose, bool haveNumSlices) : error_(false), handle_(NULL), imageNum_(0), numGroups_(0), mosaic_(false), d3_(false), sliceThickness_(0.0), sliceSpacing_(0.0), acqNum_(0), acqEchoNum_(0), columns_(-1), rows_(-1), xFOV_(-1), yFOV_(-1), repTime_(0), phaseEncoding_(0), intercept_(0.), slope_(0.), volumeData_(NULL), manufacturer_(UNDEFINED), shadowSet_(NULL), verbose_(verbose), numSlices_(0) { if ( ! OpenFile(path) ) { error_ = true; string msg = string("DICOMImage::DICOMImage: Cannot open file: ") + string(path); cerr << endl << "\t**** " << msg << endl; } else { imgPath_ = path; // Get the info we care about (if any fail, the error flag will be set) GetMosaic() && GetManufacturer() && GetImageNumber() && GetACQNumber() && GetACQEchoNumber() && GetACQMatrix() && GetD3() && GetSliceThickness() && (haveNumSlices || GetNumSlices()) && GetImgOrientation() && GetFOV() && GetColumns() && GetRows() && MosaicAdjustments() && GetPosNorm() && GetSliceSpacing() && GetComments() && GetRepetitionTime() && GetPhaseEncoding() && GetImgRescaleIntercept() && GetImgRescaleSlope() && GetGroupsInfo() && GetSeriesDescription() && GetSeriesNumber() && GetSeriesID() && GetACQDescription() && GetSubjectID() && GetSubjectName() && GetSeriesDate() && GetSeriesTime() && GetAccession(); } if (handle_ != NULL) DCM_CloseObject(&handle_); handle_ = NULL; } ////////////////////////////////////////////////////////////////////////////// /// /// /// Purpose: Fix a couple of parameters for mosaics /// /// @param NONE /// /// Returns: always true /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::MosaicAdjustments() { if (mosaic_) { // The total number of entries in the mosaic will be the smallest perfect square // greater than the number of slices. Each side is the sqaure root of it mosaicGridSize_ = int(ceil(sqrt(float(NumSlices())))); columns_ /= mosaicGridSize_; rows_ /= mosaicGridSize_; xFOV_ /= mosaicGridSize_; yFOV_ /= mosaicGridSize_; } return true; } ////////////////////////////////////////////////////////////////////////////// /// /// /// Purpose: Open image file /// /// @param path - path to image /// /// Returns: false == error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::OpenFile(const char *path) { bool retValue = true; unsigned long options = DCM_ORDERLITTLEENDIAN | DCM_FORMATCONVERSION | DCM_VRMASK; // Try opening as PART10, if it fails it's might be bcause it does not have // a preable and the try it that way if ( DCM_OpenFile(path, options | DCM_PART10FILE, &handle_) != DCM_NORMAL ) { DCM_CloseObject(&handle_); COND_PopCondition(TRUE); if ( DCM_OpenFile(path, options, &handle_) != DCM_NORMAL ) retValue = false; } return retValue; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the name of the manufacturer (0008,0070) /// /// @param NONE /// /// @return false if error /// /// Notes: For now we know only of SIEMENS and GE /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetManufacturer() { char *data = NULL; if (GetData(DCM_IDMANUFACTURER, &data) == 0) { string msg("DICOMImage::GetManufacturer: Cannot get value of manufacturer in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; if (data != NULL) delete [] data; return false; } if (strcmp(data, "SIEMENS") == 0) manufacturer_ = SIEMENS; else if (strcmp(data, "GE MEDICAL SYSTEMS") == 0) manufacturer_ = GE; delete [] data; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the acquisition repetiton time (0018,0080) /// /// @param NONE /// /// @return false if error /// /// Notes: DICOM stores the time in a string formated as hhmmss.fraction // we will store it in double representing the seconds. /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetRepetitionTime() { // The number is really stored as a string char *data = NULL; if (GetData(DCM_ACQREPETITIONTIME, &data) == 0) { string msg("DICOMImage::GetRepetitonTime: Cannot get value of acquisition repetition time in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; if (data != NULL) delete [] data; return false; } repTime_ = atoi(data); delete [] data; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the phase encoding (0018,1312) /// /// @param NONE /// /// @return false if error /// /// Notes: DICOM stores the time in a string as either ROW, COL or OTHER. In /// the case of OTHER, we will default to ROW. /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetPhaseEncoding() { // The number is really stored as a string char *data = NULL; if (GetData(DCM_ACQPHASEENCODINGDIRECTION, &data) == 0) { string msg("DICOMImage::GetPhaseEncoding: Cannot get value of phase encoding direction time in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; if (data != NULL) delete [] data; return false; } if ( strcmp(data, "COL") == 0 ) phaseEncoding_ = 2; else phaseEncoding_ = 1; delete [] data; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the image rescale intercept (0028,1052) /// /// @param NONE /// /// @return false if error /// /// Notes: This is an optional parameter. If not present, it will be set /// to 0 and the return is always true. /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetImgRescaleIntercept() { // The number is really stored as a string char *data = NULL; if (GetData(DCM_IMGRESCALEINTERCEPT, &data) == 0) { string msg("DICOMImage::GetImgRescaleIntercept: image "); msg += imgPath_; msg += "does not contain image rescale intercept parameter, intercept set to 0"; if ( verbose_ ) cerr << endl << "\t**** " << msg << endl; error_ = false; intercept_ = 0.; } else intercept_ = atof(data); if (data != NULL) delete [] data; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the image rescale slope (0028,1053) /// /// @param NONE /// /// @return false if error /// /// Notes: This is an optional parameter. If not present, it will be set /// to 0 and the return is always true. /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetImgRescaleSlope() { // The number is really stored as a string char *data = NULL; if (GetData(DCM_IMGRESCALESLOPE, &data) == 0) { string msg("DICOMImage::GetImgRescaleSlope: image "); msg += imgPath_; msg += "does not contain image rescale slope parameter, slope set to 0"; if ( verbose_ ) cerr << endl << "\t**** " << msg << endl; error_ = false; COND_PopCondition(TRUE); // Clear error from stack slope_ = 0.; } else slope_ = atof(data); if (data != NULL) delete [] data; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the series instance id (0020, 000e) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetSeriesID() { char *strn = NULL; if (GetData(DCM_RELSERIESINSTANCEUID, &strn) == 0) { string msg("DICOMImage::GetSeriesID: Cannot get value of series id in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; if (strn != NULL) delete [] strn; return false; } seriesID_ = strn; delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Build an acquisition description string like SPM5 /// /// @param NONE /// /// @return false if error /// /// Notes: SPM5 concatenates a number of different parameters. /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetACQDescription() { char *strn = NULL; if (GetData(DCM_ACQTRANSMITTINGCOIL, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack } else acqDescription_ = strn; if ( strn != NULL ) { delete [] strn; strn = NULL; } if (GetData(DCM_ACQMRACQUISITIONTYPE, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack } else acqDescription_ += string(" ") + strn; if ( strn != NULL ) { delete [] strn; strn = NULL; } if (GetData(DCM_ACQSCANNINGSEQUENCE, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack } else acqDescription_ += string(" ") + strn; if ( strn != NULL ) { delete [] strn; strn = NULL; } if (GetData(DCM_ACQREPETITIONTIME, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack } else acqDescription_ += string(" TR=") + strn; if ( strn != NULL ) { delete [] strn; strn = NULL; } if (GetData(DCM_ACQECHOTIME, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack } else acqDescription_ += string("/TE=") + strn; if ( strn != NULL ) { delete [] strn; strn = NULL; } if (GetData(DCM_ACQFLIPANGLE, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack } else acqDescription_ += string("/FA=") + strn; if ( strn != NULL ) { delete [] strn; strn = NULL; } tm acqDatTime; memset(&acqDatTime, 0, sizeof(acqDatTime)); if (GetData(DCM_IDACQUISITIONDATE, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack } else { acqDatTime.tm_mday = atoi(&(strn[6])); strn[6] = '\0'; acqDatTime.tm_mon = atoi(&(strn[4])) - 1; strn[4] = '\0'; acqDatTime.tm_year = atoi(strn) - 1900; } if ( strn != NULL ) { delete [] strn; strn = NULL; } if (GetData(DCM_IDACQUISITIONTIME, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack } else { // In theory this could be just the time or the date + time char *dec = strchr(strn, '.'); if ( dec != NULL ) { *dec = '\0'; dec -= 2; acqDatTime.tm_sec = atoi(dec); *dec = '\0'; dec -= 2; acqDatTime.tm_min = atoi(dec); *dec = '\0'; dec -= 2; acqDatTime.tm_hour = atoi(dec); } } if ( strn != NULL ) { delete [] strn; strn = NULL; } if ( (acqDatTime.tm_mday != 0) || (acqDatTime.tm_mon != 0) || (acqDatTime.tm_year != 0) || (acqDatTime.tm_sec != 0) || (acqDatTime.tm_min != 0) || (acqDatTime.tm_hour != 0) ) { strn = new char[32]; strftime(strn, 31, "%d-%b-%Y %H:%M:%S", &acqDatTime); acqDescription_ += string(" ") + strn; delete [] strn; strn = NULL; } if ( mosaic_ ) acqDescription_ += string(" Mosaic"); if ( acqDescription_.length() == 0 ) acqDescription_ = "DINIfTI"; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the subject ID (0010, 0020) /// /// @param NONE /// /// @return always true /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetSubjectID() { char *strn = NULL; if (GetData(DCM_PATID, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack subjID_ = ""; } else subjID_ = strn; delete [] strn; DeSpace(subjID_); return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the subject name (0010, 0010) /// /// @param NONE /// /// @return always true /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetSubjectName() { char *strn = NULL; if (GetData(DCM_PATNAME, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack subjName_ = ""; } else subjName_ = strn; delete [] strn; DeSpace(subjName_); return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the series date (0008, 0021) /// /// @param NONE /// /// @return always true /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetSeriesDate() { char *strn = NULL; if (GetData(DCM_IDSERIESDATE, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack seriesDate_ = ""; } else seriesDate_ = strn; delete [] strn; DeSpace(seriesDate_); return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the series time (0008, 0031) /// /// @param NONE /// /// @return always true /// /// Notes: Cut off past the minutes /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetSeriesTime() { char *strn = NULL; if (GetData(DCM_IDSERIESTIME, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack seriesTime_ = ""; } else { strn[4] = '\0'; seriesTime_ = strn; } delete [] strn; DeSpace(seriesTime_); return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value accession number (0008, 0050) /// /// @param NONE /// /// @return always true /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetAccession() { char *strn = NULL; if (GetData(DCM_IDACCESSIONNUMBER, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack accession_ = ""; } else accession_ = strn; delete [] strn; DeSpace(accession_); return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the series description (0008, 103e) /// /// @param NONE /// /// @return always true /// /// Notes: If we can't find the description, make something up /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetSeriesDescription() { char *strn = NULL; if (GetData(DCM_IDSERIESDESCR, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack seriesDescription_ = ""; } else seriesDescription_ = strn; delete [] strn; DeSpace(seriesDescription_); return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the image number (0020, 0013) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetImageNumber() { // The number is really stored as a string char *strn = NULL; if (GetData(DCM_RELIMAGENUMBER, &strn) == 0) { string msg("DICOMImage::ImageNumber: Cannot get value of image number in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; if (strn != NULL) delete [] strn; return false; } // Convert string to numerical value imageNum_ = atoi(strn); delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the series number (0020, 0011) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetSeriesNumber() { // The number is really stored as a string char *strn = NULL; if (GetData(DCM_RELSERIESNUMBER, &strn) == 0) { string msg("DICOMImage::SeriesNumber: Cannot get value of image number in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; if (strn != NULL) delete [] strn; return false; } // Convert string to numerical value seriesNumber_ = strn; delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the relative acquisition number (0020, 0012) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetACQNumber() { // The number is really stored as a string char *strn = NULL; if (GetData(DCM_RELACQUISITIONNUMBER, &strn) == 0) { string msg("DICOMImage::GetACQNumber: Cannot get value of image number in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; if (strn != NULL) delete [] strn; return false; } // Convert string to numerical value acqNum_ = atoi(strn); delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the acquisition echo number (0018, 0086) /// /// @param NONE /// /// @return false if error /// /// Notes: This applies to field maps /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetACQEchoNumber() { // The number is really stored as a string char *strn = NULL; if (GetData(DCM_ACQECHONUMBER, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack acqEchoNum_ = 0; } else { // Convert string to numerical value acqEchoNum_ = atoi(strn); } if (strn != NULL) delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the acquisition matrix (0018, 1310) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetACQMatrix() { U16 values[4] = {0,0,0,0}; if (GetData(DCM_ACQACQUISITIONMATRIX, values) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack } // Values are Phase Columns/Phase Rows/Frequency Column/Frequency Row // two will always be 0, the other two will give the accurate count if ( values[0] == 0 ) { acqRows_ = values[1]; acqColumns_ = values[2]; } else { acqColumns_ = values[0]; acqRows_ = values[3]; } return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the image orientation (0020, 0037) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetImgOrientation() { // The number is really stored as a string char *strn = NULL; if (GetData(DCM_RELIMAGEORIENTATIONPATIENT, &strn) == 0) { string msg("DICOMImage::GetImgOrientation: Cannot get value of patient orientation in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; if (strn != NULL) delete [] strn; return false; } // Convert string to numerical value // Two sets of direction cosines (x, y, z) for first row and first column // with respect to the patient, separated by back slashes. // First set is row values, second the colum values char *tok = strtok(strn, "\\"); rowCosines_.push_back(atof(tok)); tok = strtok(NULL, "\\"); rowCosines_.push_back(atof(tok)); tok = strtok(NULL, "\\"); rowCosines_.push_back(atof(tok)); tok = strtok(NULL, "\\"); colCosines_.push_back(atof(tok)); tok = strtok(NULL, "\\"); colCosines_.push_back(atof(tok)); tok = strtok(NULL, "\\"); colCosines_.push_back(atof(tok)); delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the mosaic flag (0008, 0008) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetMosaic() { // We have to parse what the header contains char *strn = NULL; if (GetData(DCM_IDIMAGETYPE, &strn) == 0) { string msg("DICOMImage::Mosaic: Cannot get value of image type in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; if (strn != NULL) delete [] strn; return false; } // See if the word "MOSAIC" is there mosaic_ = (strstr(strn, "MOSAIC") != NULL); delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the acquisition type flag (0018, 0023) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetD3() { // We have to parse what the header contains char *strn = NULL; if (GetData(DCM_ACQMRACQUISITIONTYPE, &strn) == 0) { error_ = false; COND_PopCondition(TRUE); // Clear error from stack d3_ = false; } else { // See if the string "3D" is there d3_ = (strstr(strn, "3D") != NULL); } if (strn != NULL) delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the slice thickness (0018,0050) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetSliceThickness() { // The number is really stored as a string char *strn = NULL; if (GetData(DCM_ACQSLICETHICKNESS, &strn) == 0) { string msg("DICOMImage::SliceThickness: Cannot get value of slice thickness in image "); error_ = false; COND_PopCondition(TRUE); // Clear error from stack sliceThickness_ = 1.; } else { // Convert string to numerical value sscanf(strn, "%f", &sliceThickness_); } if (strn != NULL) delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the slice spacing (0018,0088) /// /// @param NONE /// /// @return false if error /// /// Notes: If images are contigous, no spacing info will be available /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetSliceSpacing() { // The number is really stored as a string char *strn = NULL; if (GetData(DCM_ACQSLICESPACING, &strn) == 0) { sliceSpacing_ = 0; error_ = false; if (strn != NULL) delete [] strn; COND_PopCondition(TRUE); // Clear error from stack } else { // Convert string to numerical value sscanf(strn, "%f", &sliceSpacing_); } delete [] strn; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for the comments (0020,4000) /// /// @param NONE /// /// @return false if error /// /// Notes: This is used by raw images to store (that's why we don't care about /// catching an error). /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetComments() { char *data = NULL; if (GetData(DCM_RELIMAGECOMMENTS, &data) != 0) comments_ = data; else COND_PopCondition(TRUE); // Clear error from stack error_ = false; if (data != NULL) delete [] data; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for columns (0028, 0011) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetColumns() { U16 data; if (GetData(DCM_IMGCOLUMNS, &data) == 0) { columns_ = 0; error_ = true; return false; } columns_ = data; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the value for rows (0028, 0010) /// /// @param NONE /// /// @return false if error /// /// Notes: /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetRows() { U16 data; if (GetData(DCM_IMGROWS, &data) == 0) { rows_ = 0; error_ = true; return false; } rows_ = data; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Compute values of FOV's /// /// @param NONE /// /// @return false if error /// /// Notes: Read pixel spacing values (0028, 0030) and use previously read /// columns and rows /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetFOV() { // Values are stored in a string separated by backslashes char *strn = NULL; if (GetData(DCM_IMGPIXELSPACING, &strn) == 0) { xFOV_ = yFOV_ = 0; error_ = true; if (strn != NULL) delete [] strn; COND_PopCondition(TRUE); // Clear error from stack } else { // Extract numerical values and use them to compute FOVs // Make sure we have read the values for rows and columns (which should // be positive if ( rows_ < 0 ) { if ( GetRows() ) { if ( columns_ < 0 ) if ( ! GetColumns() ) { delete [] strn; return false; } } else { delete [] strn; return false; } } char *tok = strtok(strn, "\\"); yFOV_ = atof(tok) * float(rows_); tok = strtok(NULL, "\\"); xFOV_ = atof(tok) * float(columns_); delete [] strn; } return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get the shadow set data /// /// /// @return data - pointer to data /// /// Notes: Read it only once. We always return a copy which the user must /// delete. /// ////////////////////////////////////////////////////////////////////////////// char *DICOMImage::GetShadowSet() { static U32 len; if (shadowSet_ == NULL) { if (DCM_GetElementSize(&handle_, DCM_MAKETAG(0x0029,0x1020), &len) != DCM_NORMAL) { COND_PopCondition(TRUE); // Clear error from stack return NULL; } char *storage = NULL; if ((len = GetData(DCM_MAKETAG(0x0029,0x1020), &storage)) == 0) { if (storage != NULL) delete [] storage; return NULL; } // Find the beginning of what we're interested in // Start from the back of the buffer and find matching // "ASCCONV END"/"ASCCONV BEGIN" block // Cannot use standard string search methods 'cause this is full of NULLs U32 startp = len - 1; char *strn = &(storage[startp]); while ( startp > 0 ) { if ((*strn == '#') && (strncmp(strn, "### ASCCONV END ###", 18) == 0)) break; --strn; --startp; } while ( startp > 0 ) { if ((*strn == '#') && (strncmp(strn, "### ASCCONV BEGIN ###", 21) == 0)) break; --strn; --startp; } len = len - startp + 1; if (len > 0) { shadowSet_ = new char [len]; memcpy(shadowSet_, strn, sizeof(char)*(len)); } delete [] storage; } else len = strlen(shadowSet_); char *retValue = new char [len]; memcpy(retValue, shadowSet_, sizeof(char)*(len)); return retValue; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Read the Siemens special data (0029, 1020) and get the number of /// groups in this directory plus each group's size and starting /// image number. /// /// @param /// /// @return false if error /// /// Notes: This looks and feels like a hack .... ;-( /// We only know how to deal with Siemens shaodw set /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetGroupsInfo() { char *storage = GetShadowSet(); if ( (manufacturer_ != SIEMENS) || (storage == NULL) ) { numGroups_ = 1; groupSize_.resize(1); groupSize_[0] = 1; groupStartImage_.resize(1); groupStartImage_[0] = 1; return true; } bool found = false; // Find all of the info of the form "sGroupArray.asGroup[nn].nSize" and // store the last "nn" value found. char *tok = strtok(storage, "\n"); while ( tok ) { // Make sure we don't go past the end if ((*tok == '#') && (strncmp(tok, "### ASCCONV END ###", 18) == 0)) break; if ( ! strncmp(tok, "sGroupArray.asGroup[", 20) ) { char *valuep = strstr(tok, "["); int groupNum; sscanf(valuep, "[%i].", &groupNum); if ( groupNum >= numGroups_ ) { numGroups_ = groupNum + 1; // The indexes start at 0, we want the total # if ( groupSize_.size() < numGroups_ ) { groupSize_.resize(numGroups_); groupStartImage_.resize(numGroups_); } } valuep = strstr(tok, "= "); int parValue; sscanf(valuep, "= %d", &parValue); char *parp = strstr(tok, "]"); if ( ! strncmp(parp, "].nSize", 7) ) { groupSize_[groupNum] = parValue; } else if ( ! strncmp(parp, "].nLow", 6) ) { // What is stored is the last image number of th previous group groupStartImage_[groupNum] = parValue + 1; } found = true; } tok = strtok(NULL, "\n"); } if ( ! found ) { string msg("DICOMImage::GetGroupsInfo: Cannot get value of Siemens info in image "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl; error_ = true; delete [] storage; storage = NULL; return false; } // The first group has no start image number, set it to 1 for consistency groupStartImage_[0] = 1; delete [] storage; storage = NULL; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: If this is a Siemens image read the shadow set (0029, 1020) and // get the number of slices in this file. /// /// @param NONE /// /// @return Always true /// /// Notes: If this is not mosaic, we will have to fix it later. /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetNumSlices() { if ( manufacturer_ == SIEMENS ) { char *storage = GetShadowSet(); if (storage == NULL) { numSlices_ = 1; error_ = true; } else { bool found = false; // Believe it or not, we are looking only for one thing .... char *tok = strtok(storage, "\n"); while (tok) { if ( mosaic_ || !d3_ ) { if (! strncmp(tok, "sSliceArray.lSize", 17)) { char *valuep = strstr(tok, "="); sscanf(valuep, "=%i", &numSlices_); found = true; break; } } else { if (! strncmp(tok, "sSliceArray.asSlice[0].dThickness", 33)) { char *valuep = strstr(tok, "="); float fval; sscanf(valuep, "=%f", &fval); numSlices_ = int(0.5 + fval / sliceThickness_); found = true; break; } } tok = strtok(NULL, "\n"); } if (! found) error_ = true; delete [] storage; storage = NULL; } } else { char *strn = NULL; if (GetData(DCM_RELIMAGESINACQUISITION, &strn) == 0) { numSlices_ = 1; COND_PopCondition(TRUE); // Clear error from stack error_ = true; } else { numSlices_ = atoi(strn); } delete [] strn; } if ( error_ ) { error_ = false; string msg("DICOMImage::NumSlices: Cannot get number of slices from "); msg += imgPath_; cerr << endl << "\t**** " << msg << endl << "\t**** Setting value to 1 (can be changed with '-s' option on command line.)" << endl; } return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Store sag/cor/tra positons and normals. /// /// @param NONE /// /// @return false if error /// /// Notes: If this is SIEMENS, we'll have a list of values which we will get from /// the Siemens shadow set, otherwise read it from the DICOM header. /// The signs on the normal will have to be adjusted once we have the /// full set using AdjustSet(). /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetPosNorm() { sagNorm_ = rowCosines_.at(1) * colCosines_.at(2) - rowCosines_.at(2) * colCosines_.at(1); corNorm_ = rowCosines_.at(2) * colCosines_.at(0) - rowCosines_.at(0) * colCosines_.at(2); traNorm_ = rowCosines_.at(0) * colCosines_.at(1) - rowCosines_.at(1) * colCosines_.at(0); char *storage = NULL; if ( (mosaic_) && (manufacturer_ == SIEMENS) && ((storage = GetShadowSet()) != NULL) ) return GetPosNormSiemens(storage); else { char *str = NULL; if (GetData(DCM_RELIMAGEPOSITIONPATIENT, &str) == 0) { error_ = true; if (str != NULL) delete [] str; COND_PopCondition(TRUE); // Clear error from stack return false; } else { // Extract numerical values and push them on the lists char *tok = strtok(str, "\\"); float posValue = atof(tok); sagPos_.push_back(posValue); tok = strtok(NULL, "\\"); posValue = atof(tok); corPos_.push_back(posValue); tok = strtok(NULL, "\\"); posValue = atof(tok); traPos_.push_back(posValue); delete [] str; } } return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Store sag/cor/tra positons and normals. /// /// @param char *storage - the shadow set /// /// @return false if error /// /// Notes: Get a list of values from the Siemens shadow set. /// Siemens stores the value of the middle of the slice. The DICOM /// standard specifies the middle of the upper-left-hand pixel, so we /// have to adjust half FOV minus half pixel. /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetPosNormSiemens(char *storage) { // Find the info of the form "sSliceArray.asSlice[NN].sNormal.dSag/dCor/dTra" // and "sSliceArray.asSlice[NN].sPosition.dSag/dCor/dTra" for each slice (if // this a Mosaic, there will be more than one slice) char *tok = strtok(storage, "\n"); // Since the number of entries varies (sic), find the start of // sSliceArray.asSlice and stop parsing at the end of it bool parsed = false; float *values = new float [numSlices_ * 3]; memset(values, 0, sizeof(float) * numSlices_ * 3); if (tok) do { if (! strncmp(tok, "sSliceArray.asSlice[", 20)) { parsed = true; // Find out what slice number we're talking about char *valuep = strstr(tok, "["); int sliceNum; sscanf(valuep, "[%i].", &sliceNum); // For mosaic images load all slice info, // for others we want the slice that corresponds to this image // Always store at least the first, just in case there is only one if ( (mosaic_ && (sliceNum < numSlices_)) || (!mosaic_ && (sliceNum == (imageNum_ - 1))) || (sliceNum == 0) ) { if (strstr(tok, "].sPosition.d") == NULL) continue; // Figure out which of the three axis it is int axis = 0; if (strstr(tok, ".dCor") != NULL) axis = 1; else if (strstr(tok, ".dTra") != NULL) axis = 2; // Time to read the value and store it valuep = strstr(tok, "="); // For each slice, we will order the entries by axis int index = axis; if (mosaic_) index += sliceNum * 3; sscanf(valuep, "=%f", &(values[index])); } } else if (parsed) break; } while (tok = strtok(NULL, "\n")); // Compute adjustment values // First make sure that we've read FOVs (which are always positive) if ((xFOV_ < 0) || (yFOV_ < 0)) if (!GetFOV()) { delete [] storage; delete [] values; return false; } // Siemens draws the images starting at x=-FOV/2, y=-FOV/2 // therefore, we need to move FOV/2 from the center of the slice float rowProp = ((float)rows_ / 2) * ((float)xFOV_ / rows_); float colProp = ((float)columns_ / 2) * ((float)yFOV_ / columns_); float sagAdjust = - rowProp * rowCosines_.at(0) - colProp * colCosines_.at(0); float corAdjust = - rowProp * rowCosines_.at(1) - colProp * colCosines_.at(1); float traAdjust = - rowProp * rowCosines_.at(2) - colProp * colCosines_.at(2); // Now that we have our values, let's store them ... for (int slice = 0, index = 0; slice < numSlices_; ++slice) { sagPos_.push_back(values[index] + sagAdjust); ++index; corPos_.push_back(values[index] + corAdjust); ++index; traPos_.push_back(values[index] + traAdjust); ++index; } delete [] storage; storage = NULL; delete [] values; values = NULL; return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get data from image /// /// @param tag - which element /// @param storage - where to store info /// /// @return U32 len - length of item or 0 if error /// /// Notes: Overloaded string version /// ////////////////////////////////////////////////////////////////////////////// U32 DICOMImage::GetData(DCM_TAG tag, char **storage) { DCM_ELEMENT element; U32 len; if (DCM_GetElement(&handle_, tag, &element) != DCM_NORMAL || DCM_GetElementSize(&handle_, tag, &len) != DCM_NORMAL) { error_ = true; return 0; } void *ctx = NULL; if (*storage == NULL) *storage = new char [len+1]; element.d.string = *storage; U32 newLen; if (DCM_GetElementValue(&handle_, &element, &newLen, &ctx) != DCM_NORMAL) { error_ = true; return 0; } if (newLen > len) { string msg("DICOMImage::GetData: Inconsistent data size"); cerr << endl << "\t**** " << msg << endl; error_ = true; return 0; } // Terminate and strip trailing blanks (*storage)[len] = '\0'; if (len > 0) { while ((len > 0) && ((*storage)[--len] == ' ')) (*storage)[len] = '\0'; return len+1; } else return 0; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get data from image /// /// @param tag - which element /// @param storage - where to store info /// /// @return bool - false if error /// /// Notes: Overloaded U32 version /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetData(DCM_TAG tag, U32 *storage) { DCM_ELEMENT element; if (DCM_GetElement(&handle_, tag, &element) != DCM_NORMAL) { error_ = true; return false; } U32 len; void *ctx = NULL; element.d.ul = storage; if (DCM_GetElementValue(&handle_, &element, &len, &ctx) != DCM_NORMAL) { error_ = true; return false; } return true; } ////////////////////////////////////////////////////////////////////////////// /// /// Purpose: Get data from image /// /// @param tag - which element /// @param storage - where to store info /// /// @return bool - false if error /// /// Notes: Overloaded U16 version /// ////////////////////////////////////////////////////////////////////////////// bool DICOMImage::GetData(DCM_TAG tag, U16 *storage) { DCM_ELEMENT element; if (DCM_GetElement(&handle_, tag, &element) != DCM_NORMAL) { error_ = true; return false; } U32 len; void *ctx = NULL; element.d.us = storage; if (DCM_GetElementValue(&handle_, &element, &len, &ctx) != DCM_NORMAL) { error_ = true; return false; } return true; } //**************************************************************************** // // Purpose: Read the pixel data for one slice // // Parameters: U16 *data - where we store it // int slice - which slice in set (defaults to 0) // // Returns: bool false == error // // Notes: If _handle == NULL we need to open the file // //**************************************************************************** bool DICOMImage::ReadSlice(U16 *data, int slice) { // Maybe we've read the volume, maybe not if ( volumeData_ == NULL ) if ( ! ReadVolume() ) return false; if (slice >= numSlices_) { error_ = true; string msg = string("DICOMImage::ReadSlice: Trying to read past end of file: ") + imgPath_; cerr << endl << "\t**** " << msg << endl; return false; } // Find the slice in the set // If this is not mosaic, there is only one slice if (mosaic_) { // Mosaic side in pixels int mosPix = mosaicGridSize_ * columns_; // Determine the mosaic row and column for the slice and the increment int mosRow = slice / mosaicGridSize_; int mosCol = slice % mosaicGridSize_; int mosInc = mosPix - columns_; // We can now copy the data from the correct spot int mosInd = mosCol * columns_ + mosPix * mosRow * rows_; int datInd = 0; for (int row = 0; row < rows_; ++row, mosInd += mosInc) for (int col = 0; col < columns_; ++col, ++mosInd, ++datInd) data[datInd] = volumeData_[mosInd]; } else { memcpy((void *)data, (const void *)volumeData_, columns_ * rows_ * sizeof(U16)); } return true; } //**************************************************************************** // // Purpose: Read the whole volume and store it // // Parameters: NONE // // Returns: bool false = error // // Notes: // //**************************************************************************** bool DICOMImage::ReadVolume() { if (handle_ == NULL) { if ( ! OpenFile(imgPath_.c_str()) ) { error_ = true; string msg = string("DICOMImage::ReadVolume: Cannot open file: ") + imgPath_; cerr << endl << "\t**** " << msg << endl; return false; } } DCM_ELEMENT element; if ( (DCM_GetElement(&handle_, DCM_PXLPIXELDATA, &element) != DCM_NORMAL ) || (element.length > 0xFFFFFFFE) ) { error_ = true; string msg = string("DICOMImage::ReadVolumes: Error reading file: ") + imgPath_; cerr << endl << "\t**** " << msg << endl; return false; } // Element's length is in bytes volumeData_ = new U16 [element.length / 2]; element.d.ow = volumeData_; U32 len; void *ctx = NULL; if (DCM_GetElementValue(&handle_, &element, &len, &ctx) != DCM_NORMAL) { error_ = true; string msg = string("DICOMImage::ReadVolume: Error reading file: ") + imgPath_; cerr << endl << "\t**** " << msg << endl; delete [] volumeData_; volumeData_ = NULL; return false; } DCM_CloseObject(&handle_); handle_ = NULL; return true; } DICOMNIfTI/src/dinifti.cc0000660000121300000240000005761011773135740014610 0ustar valeriogames#define VERSION "2.31.1" //**************************************************************************** // // Modification History (most recent first) // mm/dd/yy Who What // // 10/04/06 Add DiniftiOptions class and verbose mode // (contributed by Michael Hanke) // 08/15/06 VPL Fix bugs in output // Make software GPL // Format --help and --version to be in standard form // 03/22/05 VPL Allow processing of multiple series // Add NYU License agreement // 01/24/05 VPL // //**************************************************************************** #include #include #include #include "dinifti.h" #include "niftiout.h" //**************************************************************************** // // Purpose: Comaprison of image entries // // Parameters: DICOMImage lhs - left-hand side item // DICOMImage rhs - left-hand side item // // Returns: 0 if rhs >= lhs // // Notes: // //**************************************************************************** static int CompareImages(const DICOMImage &lhs, const DICOMImage &rhs) { float lhsValue = lhs.SagPos() * lhs.SagNorm() + lhs.CorPos() * lhs.CorNorm() + lhs.TraPos() * lhs.TraNorm(); float rhsValue = rhs.SagPos() * rhs.SagNorm() + rhs.CorPos() * rhs.CorNorm() + rhs.TraPos() * rhs.TraNorm(); int retValue = 0; // If position the same, use image number to sort if (fabs(lhsValue - rhsValue) > 0.000001) retValue = lhsValue < rhsValue; else retValue = lhs.ImageNumber() < rhs.ImageNumber(); return retValue; } //**************************************************************************** // // Purpose: Compose file name from pieces and open for writing // // Parameters: char *&fname - where we store the name // const char *name - Root of output file // OUTPUT_TYPE form - NIfTI output format // bool compressed - write compressed // bool header - if true (default) then headr file, else // image file // // Returns: FILE *fp - pointer to open FILE // // Notes: // //**************************************************************************** static void SetFileName(char *&fname, const char *name, OUTPUT_TYPE form, bool compressed, bool header = true) { ostringstream outFileName(name, ostringstream::app); if (header) switch( form ) { case NIfTI_SINGLE: outFileName << ".nii"; break; case NIfTI_ASCII: outFileName << ".nia"; break; case ANALYZE: case NIfTI_DUAL: outFileName << ".hdr"; break; } else outFileName << ".img"; if (compressed) outFileName << ".gz"; fname = new char [outFileName.str().length() + 1]; strcpy(fname, outFileName.str().c_str()); } //**************************************************************************** // // Purpose: Generate output name based on format string // // Parameters: DICOMImage *dcmImg - current DICOM image // char *format - format string // std::string &name - where to append the format // // Returns: NONE // // Notes: // //**************************************************************************** static void FormattedName(DICOMImage *dcmImg, char *format, std::string &name) { // Loop through characters in format and process accordingly char *cp = format; while ( *cp != '\0' ) { if ( *cp == '%' ) { ++cp; switch ( *cp ) { case 'I': name += dcmImg->SubjectID(); break; case 'N': name += dcmImg->SubjectName(); break; case 'S': name += dcmImg->SeriesNumber(); break; case 'D': name += dcmImg->SeriesDescription(); break; case 'Y': name += dcmImg->SeriesDate(); break; case 'T': name += dcmImg->SeriesTime(); break; case 'A': name += dcmImg->Accession(); break; case 'C': name += dcmImg->Comments(); break; case '%': name += '%'; break; default: // Who knows, ignore it break; } } else { // Just append the character to the string // But use '~' instead of '~' if ( *cp == '/' ) name += '~'; else name += *cp; } ++cp; } } //**************************************************************************** // // Purpose: Display usage and leave // // Parameters: char **argv - standard arguments // // Returns: NONE // // Notes: // //**************************************************************************** void ShowHelp(char **argv) { cout << "'dinifti' converts DICOM image file to NIfTI format" << endl << endl << "Usage: " << argv[0] << " [OPTION] " << endl << endl << "Options:" << endl << " -g compressed output" << endl << " -f 'a2' - ANALYZE 7.5 Dual file" << endl << " 'n2' - NIfTI-2 Dual file" << endl << " 'n1' - NIfTI-1 Single file **Default**" << endl << " -d append series description to output file name(s)" << endl << " --name=\"\" format output file name(s) according to " << endl << " where : " << endl << " %I = subject ID" << endl << " %N = subject name" << endl << " %S = series number" << endl << " %D = series description" << endl << " %Y = series date" << endl << " %T = series time" << endl << " %A = accession number" << endl << " %C = image comments" << endl << " %% = percentage sign" << endl << " Example: " << endl << " --name=\"%Y:%T - %A - %I - %D(%S)\"" << endl << " will result in name(s) formed like" << endl << " date:time - accession - ID - description(number)" << endl << " N.B.: format string must be enclosed in quotes" << endl << " if format is specified, -d flag is ignored" << endl << " the reserved character \"/\" will be rendered as \"~\"" << endl << " -s # number of slices per volume" << endl << " -v --verbose enable verbose status output" << endl << " -n --noact do all processing, but do not write files" << endl << endl << " -h --help print this help and exit" << endl << " -V --version print version number and exit" << endl << endl << "I/O Options" << endl << " can be single file, list of files or directory" << endl << " can be single file or directory" << endl; exit(0); } //**************************************************************************** // // Purpose: // // Parameters: name of input file(s) or input directory // last parameter name of output directory (create if needed) // // Returns: // // Notes: // //**************************************************************************** int main(int argc, char **argv) { if (argc < 3) { if ( (argc > 1) && ((strcmp(argv[1], "--version") == 0) || (strcmp(argv[1], "-V") == 0)) ) { cout << "dinifti " << VERSION << endl; exit(0); } ShowHelp(argv); } // Last parameter is output file, get that out of the way int outNameIndex = --argc; DiniftiOptions opts; int parseArg = 1; while (parseArg < argc) { if (argv[parseArg][0] != '-') break; if (! strcmp(argv[parseArg], "-f") ) { ++parseArg; if (! strcmp(argv[parseArg], "a2") ) opts.niftiFormat = ANALYZE; else if (! strcmp(argv[parseArg], "n1") ) opts.niftiFormat = NIfTI_SINGLE; else if (! strcmp(argv[parseArg], "n2") ) opts.niftiFormat = NIfTI_DUAL; else { cerr << "\t**** Error: format " << argv[2] << " not supported." << endl << endl; ShowHelp(argv); } } else if (! strcmp(argv[parseArg], "-g") ) { opts.compressed = true; } else if (! strcmp(argv[parseArg], "-d") ) { opts.useSerDesc = true; } else if (! strncmp(argv[parseArg], "--name=", 7) ) { opts.nameFormat = new char [strlen(argv[parseArg]) - 6]; strcpy(opts.nameFormat, &(argv[parseArg][7])); } else if ( (strcmp(argv[parseArg], "-v") == 0) || (strcmp(argv[parseArg], "--verbose") == 0) ) { opts.verbose = true; } else if ( (strcmp(argv[parseArg], "-n") == 0) || (strcmp(argv[parseArg], "--noact") == 0) ) { opts.noact = true; } else if (! strcmp(argv[parseArg], "-s") ) { ++parseArg; opts.numSlices = atoi(argv[parseArg]); } else ShowHelp(argv); ++parseArg; } if (parseArg == argc) ShowHelp(argv); vector dicomFiles; // If only two file parameters, it might be a directory (try opening it) DIR *dirStr = NULL; if ((argc == parseArg + 1) && ( dirStr = opendir(argv[parseArg]))) { // If this is a directory, find all DICOM files there dirent *nextFile = NULL; while (nextFile = readdir(dirStr)) { // Avoid hidden files if (nextFile->d_name[0] != '.') dicomFiles.push_back(string(argv[parseArg]) + string("/") + string(nextFile->d_name)); } } else { while (--argc >= parseArg) dicomFiles.push_back(string(argv[argc])); } // Try to open DICOM file(s) and process one at a time and store in lists // then sort according to anatomical position // We create separate lists for each time point // If this is mosaic, each list will only contain one entry // The key is the acquisition number SERIESMAP seriesMap; StoreImageFiles(dicomFiles, seriesMap, argv[outNameIndex], opts); // Turn off excessive nifti messages nifti_set_debug_level(0); // Process each series, one at a time for (SERIESMAP::iterator series = seriesMap.begin(); series != seriesMap.end(); series++) ProcessSeries(series->second, opts); exit(0); } //**************************************************************************** // // Purpose: Create the series map from all the file's we've read // // Parameters: vector &dicomFiles - the list // SERIESMAP &seriesMap - where to store the map // char *outName - where it goes // // in DiniftiOptions class: // bool useSerDesc - append series description to name ? // char nameFormat - specified special format for name ? // int numSlices - number of slices per volume // // Returns: NONE // // Notes: Each series is identified by their series ID, but in special cases // (anatomical images), the same ID is assigned to images that // effectively belong to separate series. In this case an equal number of // images is assigned to each group and we create new virtual series with // the series ID appended with the group number. // // If numSlices not equal 0, use it to compute current acquisition number. // //**************************************************************************** void StoreImageFiles(vector &dicomFiles, SERIESMAP &seriesMap, char *outName, const DiniftiOptions& opts) { // Figure out if the outName is a directory or the name of a file const bool outDirectory = (opendir(outName) != NULL); // Make sure outname doesn't already have extension, or we end up with // "double" extension (e.g., ".nii.nii"), which FSL doesn't like if ( !outDirectory ) { char *extPos = strrchr(outName, '.'); if ( extPos != NULL ) if ( (strcmp(extPos, ".nii") == 0) || (strcmp(extPos, ".nia") == 0) || (strcmp(extPos, ".hdr") == 0) ) *extPos = '\0'; } int relSeriesNumber = 0; if (opts.verbose) { cout << "Reading " << dicomFiles.size() << " DICOM files." << endl; } while (dicomFiles.size() > 0) { string dcmFile(dicomFiles.back()); dicomFiles.pop_back(); DICOMImage *dcmImg = new DICOMImage(dcmFile.c_str(), opts.verbose, (opts.numSlices > 0)); if (*dcmImg) { // If no entry for this list exists yet, create it SeriesInfo si = seriesMap[dcmImg->SeriesID()]; int imgNum = dcmImg->ImageNumber(); // The qcquisition number can be provided by the user or // If the number of slices greater than 1, use them to compute it. // Else, if the echo number is greater than 0 use that (+1) // Finally it can come directly from the header int acqNum = 0; if ( opts.numSlices > 0 ) { acqNum = ((imgNum - 1) / opts.numSlices) + 1; } else if ( !dcmImg->Mosaic() && (dcmImg->NumSlices() > 1) ) { acqNum = ((imgNum - 1) / dcmImg->NumSlices()) + 1; } else if ( !dcmImg->Mosaic() && (dcmImg->ACQEchoNumber() > 0) ) { acqNum = dcmImg->ACQEchoNumber() + 1; } else acqNum = dcmImg->ACQNumber(); // Try to determine if the acquisition number makes sense IMAGELIST *timePoint = si.imageMap[acqNum]; if (timePoint == NULL) { si.imageMap[acqNum] = timePoint = new IMAGELIST; // If using series description, use that as the output name // else if outName is not a directory and more than one image, // create unique output name si.outName = outName; if (outDirectory) { if ( (opts.nameFormat != NULL) && (strlen(opts.nameFormat) > 0) ) { si.outName += string("/"); FormattedName(dcmImg, opts.nameFormat, si.outName); } else if ( opts.useSerDesc ) { si.outName += string("/") + dcmImg->SeriesDescription(); } else { if (outName[strlen(outName)-1] != '/') si.outName += string("/"); size_type begName = dcmImg->ImagePath().find_last_of('/'); size_type endName = dcmImg->ImagePath().find_last_of('.'); // If the extension is a number, it probably means something const int nameLen = dcmImg->ImagePath().length(); for (int extC = endName+1; extC < nameLen; ++extC) { char c = dcmImg->ImagePath()[extC]; if (! isdigit(c) ) break; if (extC == nameLen-1) endName = nameLen; } endName -= begName; si.outName += dcmImg->ImagePath().substr(++begName, --endName); } } else if ( (opts.nameFormat != NULL) && (strlen(opts.nameFormat) > 0) ) { si.outName += string("+"); FormattedName(dcmImg, opts.nameFormat, si.outName); } else if ( opts.useSerDesc ) { si.outName += string("+") + dcmImg->SeriesDescription(); } else if ( seriesMap.size() > 1 ) { ostringstream newFileName(si.outName, ostringstream::app); newFileName << "+" << ++relSeriesNumber; si.outName = newFileName.str(); } } timePoint->push_back(*dcmImg); si.mosaic = dcmImg->Mosaic(); si.numSlices = dcmImg->NumSlices(); si.multiEcho = (dcmImg->ACQEchoNumber() > 0); if (imgNum > si.maxImgNum) si.maxImgNum = imgNum; if ( (imgNum < si.minImgNum) || (si.minImgNum == 0) ) si.minImgNum = imgNum; if (acqNum > si.maxAcqNum) si.maxAcqNum = acqNum; if ( (acqNum < si.minAcqNum) || (si.minAcqNum == 0) ) si.minAcqNum = acqNum; seriesMap[dcmImg->SeriesID()] = si; } else delete dcmImg; } SERIESMAP newSeriesMap; // Go through the series and see if any are a special case // use this list to store series outNames to detect possible duplicates list series_ids; // do not increment the iterator here as this has to be handled conditionally at the end for (SERIESMAP::iterator series = seriesMap.begin(); series != seriesMap.end(); ) { SeriesInfo si = series->second; // Loop through images in each list and verify if number of images is // consistent, otherwise we need to split them in more lists std::map fixMap; for ( IMAGEMAP::iterator timeIter = si.imageMap.begin(); timeIter != si.imageMap.end(); ++timeIter ) { if ( ! si.mosaic ) { int acqNum = timeIter->first; IMAGELIST *timePointList = timeIter->second; fixMap[acqNum] = timePointList->size() != timePointList->front().NumSlices(); } } for ( std::map::iterator fixIter = fixMap.begin(); fixIter != fixMap.end(); ++fixIter ) { if ( fixIter->second ) { // We need to fix this list. Use echo number to augment list size. IMAGELIST *timePointList = si.imageMap[fixIter->first]; int baseAcqNum = fixIter->first; for ( IMAGELIST::iterator timeIter = timePointList->begin(); timeIter != timePointList->end(); ) { // Acquisition numbers start from 1, while echo start from 0 int thisAcqNum = timeIter->ACQEchoNumber(); if ( ++thisAcqNum != baseAcqNum ) { // This has to go in a new list, see if we need to create it. IMAGELIST *timePoint = si.imageMap[thisAcqNum]; if ( timePoint == NULL ) { si.imageMap[thisAcqNum] = timePoint = new IMAGELIST; if ( thisAcqNum > si.maxAcqNum ) si.maxAcqNum = thisAcqNum; } timePoint->push_back(*timeIter); timePointList->erase(timeIter++); } else ++timeIter; } series->second = si; } } // For each series, check the number of groups (first image in first time point is sufficient) IMAGEMAP fullImageMap = si.imageMap; IMAGEMAP::iterator fimIter = fullImageMap.begin(); IMAGELIST *firstTimePoint = fimIter->second; DICOMImage firstImg = firstTimePoint->front(); const int numGroups = firstImg.NumGroups(); // Try to guess if everything's allright with number of time points if (opts.verbose) { cout << "Found new image series. Using output destination '" << si.outName << "'." << endl; } // check for duplicate series outNames int dupes = count( series_ids.begin(), series_ids.end(), si.outName ); // if duplicate series name if (dupes) { // store the old for a useful warning message string old = si.outName; // appen '+' until we have a unique name while (dupes) { si.outName.append("+"); dupes = count( series_ids.begin(), series_ids.end(), si.outName ); } // issue warning to notify the name change cerr << endl << "\t**** WARNING: Duplicate image series name '" << old << "'" << endl << "\t**** New image series name is '" << si.outName << "'." << endl; // important: reassign the modified series info (lost otherwise) series->second = si; } // store the current image series name series_ids.push_back(si.outName); if ( (opts.numSlices == 0) && (si.numSlices == 1) && (si.maxAcqNum == si.minAcqNum) && (si.maxImgNum > si.minImgNum) ) { cerr << endl << "\t**** StoreImageFiles: Warning: number of slices per volume = 1" << endl << "\t**** and number of time points = 1." << endl << "\t**** If incorrect, run program with \"-s\" option." << endl; } const int numAcq = (si.multiEcho ? 1 : (si.maxAcqNum - si.minAcqNum + 1)); int numImgGroup = (si.maxImgNum - si.minImgNum + 1) / (numGroups * numAcq); if ( (numImgGroup > 0) && (numGroups > 1) ) { // We need to create "virtual" series and split the images among them string origSeriesID = series->first; // Hold the names in a map for easy retrieval map newSeriesNames; for (int group = 1; group <= numGroups; ++group) { ostringstream newName; newName << origSeriesID << "-" << group; newSeriesNames[group] = newName.str(); } for (IMAGEMAP::iterator timeIter = fullImageMap.begin(); timeIter != fullImageMap.end(); ++timeIter) { // Grab the full list of images for this time point // And split them up among the groups int acqNum = timeIter->first; IMAGELIST *timePoint = timeIter->second; for (IMAGELIST::iterator img = timePoint->begin(); img != timePoint->end(); ++img) { // If we have info from Siemen's shadow set, use it, otherwise // we know the acqisition number, figure out which group it belongs to. int group = img->GroupNumber(img->ImageNumber()) + 1; if ( (group == 1) && (img->GroupSize(0) == 0) ) group = (img->ImageNumber() - si.minImgNum) / numImgGroup + 1; SeriesInfo newSeriesInfo = newSeriesMap[newSeriesNames[group]]; IMAGELIST *newTimePoint = newSeriesInfo.imageMap[acqNum]; if (newTimePoint == NULL) { newSeriesInfo.imageMap[acqNum] = newTimePoint = new IMAGELIST; ostringstream newName; newName << si.outName << "-" << group; newSeriesInfo.outName = newName.str(); newSeriesInfo.mosaic = si.mosaic; // If we have Siemen's info from Siemen's showdow set, use it if (img->GroupSize(0) > 0 ) { newSeriesInfo.numSlices = img->GroupSize(group -1); newSeriesInfo.minImgNum = img->GroupStartImage(group-1); newSeriesInfo.maxImgNum = newSeriesInfo.minImgNum + newSeriesInfo.numSlices - 1; } else { newSeriesInfo.minImgNum = (group - 1) * numImgGroup + si.minImgNum; newSeriesInfo.maxImgNum = group * numImgGroup + si.minImgNum - 1; } newSeriesInfo.maxAcqNum = si.maxAcqNum; newSeriesInfo.minAcqNum = si.minAcqNum; } newTimePoint->push_back(*img); newSeriesMap[newSeriesNames[group]] = newSeriesInfo; } } // Now we can get rid of the old entries // FIRST increment the iterator THEN erase the entry // otherwise the iterator becomes invalid seriesMap.erase(series++); } else // if not incremented above do here ++series; } // Move the added series to permanent storage seriesMap.insert(newSeriesMap.begin(), newSeriesMap.end()); // If not mosaic sort and do some post-processing for (SERIESMAP::iterator series = seriesMap.begin(); series != seriesMap.end(); series++) { SeriesInfo si = series->second; if (!si.mosaic) { const int numAcq = (si.multiEcho ? 1 : (si.maxAcqNum - si.minAcqNum + 1)); const int numSlices = (opts.numSlices > 0 ? opts.numSlices : (si.numSlices > 1 ? si.numSlices : (si.maxImgNum - si.minImgNum + 1) / numAcq)); for (IMAGEMAP::iterator timeIter = si.imageMap.begin(); timeIter != si.imageMap.end(); ++timeIter) { IMAGELIST *timePoint = timeIter->second; timePoint->sort(CompareImages); for (IMAGELIST::iterator image = timePoint->begin(); image != timePoint->end(); image++) image->AdjustSet(numSlices, si.minImgNum-1); } } } } //**************************************************************************** // // Purpose: Process a series // // Parameters: SeriesInfo &seriesInfo - the series // // in DiniftiOptions class: // OUTPUT_TYPE niftiFormat - how the output is written // bool compressed - compressed output format // // Returns: // // Notes: The name will be taken from the first file in the series // //**************************************************************************** void ProcessSeries(SeriesInfo &seriesInfo, const DiniftiOptions& opts) { // Create NIfTI header with default values if (opts.verbose) { cout << "Processing image series ('" << seriesInfo.outName << "')." << endl; } nifti_image niftiHdr; if (! NIfTICreateHeader(niftiHdr, seriesInfo.imageMap)) return; niftiHdr.nifti_type = (int)opts.niftiFormat; // main processing loop over the repeat counters SetFileName(niftiHdr.fname, seriesInfo.outName.c_str(), opts.niftiFormat, opts.compressed); // In case of two files, set the name here before nifti muck about with it if ( (opts.niftiFormat == ANALYZE) || (opts.niftiFormat == NIfTI_DUAL) ) SetFileName(niftiHdr.iname, seriesInfo.outName.c_str(), opts.niftiFormat, opts.compressed, false); if (!opts.noact) { znzFile outfp = NULL; outfp = nifti_image_write_hdr_img(&niftiHdr, 2, "wb"); if (outfp == NULL) { cerr << "Writing output header failed for " << niftiHdr.fname << ". Continuing to next series." << endl << endl; } else { NIfTIWriteData(outfp, niftiHdr, seriesInfo.imageMap); znzclose(outfp); } } // Clean up time delete [] niftiHdr.fname; if (niftiHdr.iname != NULL) delete [] niftiHdr.iname; } DICOMNIfTI/src/Makefile.in0000660000121300000240000000760611573434404014715 0ustar valeriogames# $Id: Makefile.in,v 1.12 2007-02-20 20:18:07 valerio Exp $ # -*- Mode: Makefile -*- # Autoconf/Configure tag. # @configure_input@ #============================================================================== # (Semi) Standard (GNU form) variable setup # General Variables SHELL = /bin/sh RM = rm RM_F = rm -f CP = cp CC = @CC@ CXX = @CXX@ INSTALL = @INSTALL@ # Installation Variables prefix = @prefix@ exec_prefix = @exec_prefix@ includedir = @includedir@ libdir = @libdir@ libexecdir = @libexecdir@ mandir = @mandir@ # Build Variables top_srcdir = @top_srcdir@ srcdir = @srcdir@ bindir = @bindir@ VPATH = @srcdir@:@top_srcdir@/include LIBS = @LIBS@ LOCAL_LIBS = -L${libdir} -L${libdir}/ctn -lctn -lniftiio -lznz -lz loc_incdir = @top_srcdir@/include OS = @OS_TYPE@ # Different parameters for different systems ifeq ($(PROC_TYPE),POWERPC) ARCHITECTURE = BIG_ENDIAN_ARCHITECTURE else ARCHITECTURE = LITTLE_ENDIAN_ARCHITECTURE endif # Other Variables EXECNAME = dinifti DINIFTISRC = dinifti.cc dicomInfo.cc niftiout.cc DINITFIINC = $(loc_incdir)/dinifti.h $(loc_incdir)/dicomInfo.h $(loc_incdir)/niftiout.h DCMHEADSRC = dicomhead.cc dicomInfo.cc DCMHEADINC = $(loc_incdir)/dicomhead.h $(loc_incdir)/dicomInfo.h OBJECTS = $(CXXSRC:.cc=.o) CPPFLAGS = -I@srcdir@ -I$(loc_incdir) -I$(includedir) -I$(includedir)/nifti -I$(includedir)/ctn $(GCINCLUDEFLAG) -DHAVE_ZLIB CXXFLAGS = -D$(OS) -DARCHITECTURE=$(ARCHITECTURE) -DSHORTSIZE=16 -DINTSIZE=32 -DLONGSIZE=32 CFLAGS = -D$(OS) -DARCHITECTURE=$(ARCHITECTURE) -DSHORTSIZE=16 -DINTSIZE=32 -DLONGSIZE=32 OPTFLAGS = "-O -D$(OS)" DBGFLAGS = "@OS_DBGF@ $(CXXFLAGS)" PROFLAGS = "-g -pg $(CXXFLAGS)" $(DINIFTIOBJ): $(DINIFTINC) $(DCMHEADOBJ): $(DCMHEADINC) all: dinifti dicomhead clean: dinifti.clean dicomhead.clean install: dinifti.install dicomhead.install cleanit: $(RM_F) $(OBJECTS) $(EXECNAME) $(EXECNAME).dbg $(EXECNAME).opt installit: $(EXECNAME) $(INSTALL) -b $(EXECNAME) $(bindir) debug: cleanit $(MAKE) CXXFLAGS=$(DBGFLAGS) CFLAGS=$(DBGFLAGS) EXECNAME="$(EXECNAME).dbg" executable optimized: cleanit $(MAKE) CXXFLAGS=$(OPTFLAGS) CFLAGS=$(OPTFLAGS) executable profile: cleanit $(MAKE) CXXFLAGS=$(PROFLAGS) CXXFLAGS=$(PROFLAGS) EXECNAME="$(EXECNAME).opt" executable executable: $(OBJECTS) $(CXX) $(CXXFLAGS) -o $(EXECNAME) $(OBJECTS) $(LOCAL_LIBS) $(LIBS) #=============================================================================== dinifti: $(DINIFTISRC) $(DINIFTIINC) $(MAKE) CXXSRC="$(DINIFTISRC)" INCLUDES="$(DINIFTIINC)" EXECNAME=dinifti executable dinifti.clean: $(MAKE) CXXSRC="$(DINIFTISRC)" EXECNAME=dinifti cleanit dinifti.install: $(DINIFTISRC) $(DINIFTIINC) $(MAKE) CXXSRC="$(DINIFTISRC)" INCLUDES="$(DINIFTIINC)" EXECNAME=dinifti installit dinifti.debug: $(DINIFTISRC) $(DINIFTIINC) $(MAKE) CXXSRC="$(DINIFTISRC)" INCLUDES="$(DINIFTIINC)" EXECNAME=dinifti debug dinifti.optimized: $(DINIFTISRC) $(DINIFTIINC) $(MAKE) CXXSRC="$(DINIFTISRC)" INCLUDES="$(DINIFTIINC)" EXECNAME=dinifti optimized dinifti.profile: $(DINIFTISRC) $(DINIFTIINC) $(MAKE) CXXSRC="$(DINIFTISRC)" INCLUDES="$(DINIFTIINC)" EXECNAME=dinifti profile dicomhead: $(DCMHEADSRC) $(DCMHEADINC) $(MAKE) CXXSRC="$(DCMHEADSRC)" INCLUDES="$(DCMHEADINC)" EXECNAME=dicomhead executable dicomhead.clean: $(MAKE) CXXSRC="$(DCMHEADSRC)" EXECNAME=dicomhead cleanit dicomhead.install: $(DCMHEADSRC) $(DCMHEADINC) $(MAKE) CXXSRC="$(DCMHEADSRC)" INCLUDES="$(DCMHEADINC)" EXECNAME=dicomhead installit dicomhead.debug: $(DCMHEADSRC) $(DCMHEADINC) $(MAKE) CXXSRC="$(DCMHEADSRC)" INCLUDES="$(DCMHEADINC)" EXECNAME=dicomhead debug dicomhead.optimized: $(DCMHEADSRC) $(DCMHEADINC) $(MAKE) CXXSRC="$(DCMHEADSRC)" INCLUDES="$(DCMHEADINC)" EXECNAME=dicomhead optimized dicomhead.profile: $(DCMHEADSRC) $(DCMHEADINC) $(MAKE) CXXSRC="$(DCMHEADSRC)" INCLUDES="$(DCMHEADINC)" EXECNAME=dicomhead profile # end of file -- Makefile -- DICOMNIfTI/src/niftiout.cc0000660000121300000240000002704111767633531015022 0ustar valeriogames// $Id: niftiout.cc,v 1.17 2007-11-15 16:19:42 valerio Exp $ //**************************************************************************** // // Modification History (most recent first) // mm/dd/yy Who What // // 10/17/11 VPL Intercept and slope are now computed // 04/25/07 VPL ndim (a.k.a dim[0]) should be 3 for anatomical, 4 for time // series with 1 coil, 5 otherwise. // 01/31/07 VPL Protect against missing images at the beginning of series // 10/24/06 VPL Set hdr.ndim to 4 when only one coil. // Set hdr.nv, hdr.nw, hdr.du, hdr.dv, hdr.dw to 1. // Set hdr.scl_slope to 0. // 03/22/05 VPL Allow processing of multiple series // Add NYU License agreement // 02/01/05 VPL // //**************************************************************************** #include "niftiout.h" //**************************************************************************** // // Purpose: Compute slice distance // // Parameters: nifti_image &hdr - the header for NIfTI // list *imageList - pointer to the list of images // // Returns: bool false - error // // Notes: // //**************************************************************************** static bool SliceDistance(nifti_image &hdr, IMAGELIST *imageList) { bool retValue = true; IMAGELIST::iterator image = imageList->begin(); if ( !image->Mosaic() && (imageList->size() != hdr.nz) ) { cerr << endl << "\t**** Number of slices provided, " << imageList->size() << ", does not match value in header, " << hdr.nz << "." << endl << "\t Value in header can be overridden with \"-s\" flag." << endl; return false; } if ( hdr.nz < 2 ) // Only one slice, so use slice thinkness { cerr << endl << "\t**** SliceDistance: WARNING: Number of slices is less than two" << endl << "\t**** Using slice thinkness as slice distance" << endl; hdr.dz = image->SliceThickness(); } else { float x = image->SagPos(); float y = image->CorPos(); float z = image->TraPos(); // If this is Mosaic, compute from slices within image // Else from first slice from contigous images if (image->Mosaic()) { x -= image->SagPos(1); y -= image->CorPos(1); z -= image->TraPos(1); } else { image++; x -= image->SagPos(); y -= image->CorPos(); z -= image->TraPos(); } hdr.dz = (float) sqrt(x*x + y*y + z*z); if( hdr.dz < 0.00001) // if distance between slices is zero, use slice thickness hdr.dz = image->SliceThickness(); } return retValue; } //**************************************************************************** // // Purpose: Compute quaternion // // Parameters: nifti_image &hdr - the header for NIfTI // list *imageList - pointer to the list of images // // Returns: NONE // // Notes: Copied from n2n2.c by L&R Fleisher // //**************************************************************************** static void FindQuaternion(nifti_image &hdr, IMAGELIST *imageList) { // Get the lowest slice and call it k = 0 IMAGELIST::iterator image = imageList->begin(); hdr.qto_xyz.m[0][0] = -image->RowSagCos(); hdr.qto_xyz.m[0][1] = -image->ColSagCos(); hdr.qto_xyz.m[0][2] = -image->SagNorm(); hdr.qto_xyz.m[1][0] = -image->RowCorCos(); hdr.qto_xyz.m[1][1] = -image->ColCorCos(); hdr.qto_xyz.m[1][2] = -image->CorNorm(); hdr.qto_xyz.m[2][0] = image->RowTraCos(); hdr.qto_xyz.m[2][1] = image->ColTraCos(); hdr.qto_xyz.m[2][2] = image->TraNorm(); // offset = slicePosition(center) - M*(i,j,k of center) // since we are working with the first slice k = 0. hdr.qoffset_x = -image->SagPos(); hdr.qoffset_y = -image->CorPos(); hdr.qoffset_z = image->TraPos(); nifti_mat44_to_quatern(hdr.qto_xyz, &(hdr.quatern_b), &(hdr.quatern_c), &(hdr.quatern_d), NULL, NULL, NULL, NULL, NULL, NULL, &(hdr.qfac)); } //**************************************************************************** // // Purpose: Fill in NIfTI header with default values // // Parameters: nifti_image &hdr - the header to fill // IMAGEMAP &imageMap - the image set ordered by timepoint // // Returns: bool false == error // // Notes: Copied from n2n2.c by L&R Fleisher // // Look at nifti_image_write in nifiti1_io.c, and at nifti_1_header // struct in nifti1.h for description of the fields of the data // header. The nifti_image struct items initialized below are (mostly) // in the order given in nifti1_io.h // // THE FUNCTION FILLS THE DEFAULT VALUES INTO nifti_image AS FOUND IN // THE INPUT.HERE IS THE LIST OF WHAT ONE MAY WANT TO CHANGE ELSEWHERE: // - nifti_type file format should be set according to user specifications // notice that only float storage type is supported, see a note below // // - hdr.ndim is set to 5 when there is more than one coil, else it is // set to 4. // // FIXME WILL NEVER BE FIXED // - hdr.dz is set to distance between slice centers contrary // to specification of ANALYZE/NIFTI standard which requires dz // be slice thickness! In other words, // slicethicknes != z-grid spacing = dz. // This is probably correct and is a mistake in the standard. // Also, for 3D acquisitions what is slice thickness? // inside find_slice_thinkness, use get_slicethickness() // - hdr.dt is set to time between slices // If it is zero, it is set to time between volumes. // How to define the time of the slice???? // - datatype is set for int storage type. // If other storage types are desired the field should be set // accordingly // - slice_code // - slice_duration // - iname and fname if used, do not belong here // - toffset do not understand what it is. // //**************************************************************************** bool NIfTICreateHeader(nifti_image &hdr, IMAGEMAP &imageMap) { bool retValue = true; IMAGELIST *imageList = imageMap.begin()->second; IMAGELIST::iterator image = imageList->begin(); memset(&hdr, 0, sizeof(nifti_image)); hdr.nx = image->Columns(); hdr.ny = image->Rows(); hdr.nz = image->NumSlices(); // number of slices per volume hdr.nt = imageMap.size(); // number of timepoints hdr.nu = 1; // either just 1, or combined into 1 if ( hdr.nt == 1 ) { hdr.ndim = 3; } else { hdr.ndim = 4; } hdr.nv = 1; hdr.nw = 1; hdr.nvox = (size_t)(hdr.nx * hdr.ny * hdr.nz * hdr.nt); hdr.datatype = DT_SIGNED_SHORT; // hdr.nbyper should be sizeof(int) for this datatype, but NIFTI does // something else nifti_datatype_sizes(hdr.datatype, &(hdr.nbyper), &(hdr.swapsize)); hdr.dx = image->XFOV() / ((float)hdr.nx); hdr.dy = image->YFOV() / ((float)hdr.ny); if (! SliceDistance(hdr, imageList)) { cerr << endl << "\t**** CreateNIfTIHeader: Cannot find slice distance for " << image->ImagePath() << "." << endl << endl; return false; } // hdr.dt is specified as time between slices (what does it mean??) // use time between volumes instead, as it is clearer if( hdr.nt > 1 ) { hdr.dt = image->RepetitionTime(); } else { cerr << endl << "\t**** CreateNIfTIHeader: WARNING: number of repetitions is less than two" << endl << "\t**** time between volumes is set to zero" << endl; hdr.dt = 0.0; } hdr.du = 1.0; hdr.dv = 1.0; hdr.dw = 1.0; hdr.scl_slope = image->ImgRescaleSlope(); hdr.scl_inter = image->ImgRescaleIntercept(); hdr.cal_min = 0; hdr.cal_max = 0; // quaternions in scanner-based system hdr.qform_code = NIFTI_XFORM_SCANNER_ANAT; hdr.sform_code = 0; hdr.freq_dim = image->FrequencyDim(); hdr.phase_dim = image->PhaseDim(); hdr.slice_dim = 3; hdr.slice_code = 0; hdr.slice_start = 0; hdr.slice_end = hdr.nz - 1; hdr.slice_duration = 0.0; FindQuaternion(hdr, imageList); hdr.toffset = 0.0; // Time is since 0:00 of the day hdr.xyz_units = NIFTI_UNITS_MM; // these are probably correct hdr.time_units = NIFTI_UNITS_MSEC; // no coil intent in the format specification // should we make it NIFTI_INTENT_VECTOR ? hdr.intent_code = NIFTI_INTENT_NONE; hdr.intent_p1 = 0.0; hdr.intent_p2 = 0.0; hdr.intent_p3 = 0.0; hdr.intent_name[0] = '\0' ; hdr.aux_file[0] = '\0'; hdr.byteorder = nifti_short_order(); /* use host byte order */ hdr.data = NULL; strncpy(hdr.descrip, image->ACQDescription().c_str(), 79); hdr.descrip[79] = '\0'; return retValue; } //**************************************************************************** // // Purpose: Write the data to the NIfTI file // // Parameters: znzFile fp - the (opened) output file // nifti_image &hdr - NIfTI header with all the good info // IMAGEMAP &imageMap - map with sorted list of images per timepoint // // Returns: bool false == error // // Notes: // //**************************************************************************** bool NIfTIWriteData(znzFile fp, nifti_image &hdr, IMAGEMAP &imageMap) { // For now start with just one coil mode .... COMB aka norm int numPix = hdr.nx * hdr.ny; hdr.data = (void *)(new unsigned short [numPix]); if (hdr.data == NULL) { cerr << "\t**** NIfTIWriteData: Error: memory allocation failure." << endl << endl; return false; } // Assume, order is the same for all repetitions for (IMAGEMAP::iterator imageList = imageMap.begin(); imageList != imageMap.end(); imageList++) { // If this a mosaic, load the volume at once IMAGELIST::iterator img = imageList->second->begin(); const bool mosaic = img->Mosaic(); // Loop through slices and read the slice values const int numSlices = img->NumSlices(); for (int slice = 0; slice < numSlices; ++slice) { // This should never happen if (img == imageList->second->end()) { cerr << "\t**** NIfTIWriteData: Error: " << "Image list larger than number off slices." << endl << endl; // clean write buffer delete [] static_cast(hdr.data); return false; } // Clear out the array we use for reading memset(hdr.data, 0, numPix * sizeof(unsigned short)); // All elements are assumed to be the same size or NIFTI/ANALYZE // will break if ((img->Columns() != hdr.nx) || (img->Rows() != hdr.ny)) { cerr << "\t**** NIfTIWriteData: Error: " << "NIFTI does not support acquisition of slices with different FOVs. " << endl << "\t Aborting conversion" << endl << endl; img->FreeVolume(); // clean write buffer delete [] static_cast(hdr.data); return false; } if (!img->ReadSlice((unsigned short *)hdr.data, slice)) { cerr << "\t**** NIfTIWriteData: Error: " << "Error reading data from DICOM file " << img->ImagePath() << "." << endl << "\t Aborting conversion" << endl << endl; img->FreeVolume(); // clean write buffer delete [] static_cast(hdr.data); return false; } if ( nifti_write_buffer(fp, hdr.data, numPix * hdr.nbyper) != (numPix * hdr.nbyper)) { cerr << "\t**** NIfTIWriteData: Error: while processing image " << img->ImagePath() << "." << endl << "\t Data write failed. Aborting conversion" << endl << endl; img->FreeVolume(); // clean write buffer delete [] static_cast(hdr.data); return false; } if (!mosaic) { img->FreeVolume(); img++; } } if (img != imageList->second->end()) img->FreeVolume(); } // clean write buffer delete [] static_cast(hdr.data); return true; }