[med-svn] [mricron] 06/17: Imported Upstream version 0.20130828.1~dfsg.1
Michael Hanke
mih at alioth.debian.org
Sun Sep 22 10:49:55 UTC 2013
This is an automated email from the git hooks/post-receive script.
mih pushed a commit to branch master
in repository mricron.
commit 90c5196ea331ee3027a6dd8e4846d48439512461
Author: Michael Hanke <michael.hanke at gmail.com>
Date: Sat Sep 21 09:36:08 2013 +0200
Imported Upstream version 0.20130828.1~dfsg.1
---
MultiSlice.lfm | 12 +-
MultiSlice.lrs | 14 +-
MultiSlice.pas | 7 +
Text.lrs | 22 +-
WINRES.or | Bin 9868 -> 9868 bytes
_clean.bat | 1 +
_dcm2nii.bat | 8 +
_delphizip.bat | 4 +-
_maclipo.bat | 3 +-
_macscriptintel.bat | 3 +
_xclean.bat | 4 +
about.lfm | 6 +-
about.lrs | 32 +-
btn/autocon.bmp | Bin 1782 -> 1782 bytes
btn/autocontrast.png | Bin 1351 -> 1351 bytes
btn/bucket24.png | Bin 1136 -> 1136 bytes
btn/colorbar.bmp | Bin 918 -> 918 bytes
btn/colorzero.bmp | Bin 1710 -> 1710 bytes
btn/icon.png | Bin 3935 -> 3935 bytes
btn/info.bmp | Bin 1566 -> 1566 bytes
btn/magichat.png | Bin 880 -> 880 bytes
btn/new/3dx.png | Bin 1013 -> 1013 bytes
btn/new/autoclose24.png | Bin 865 -> 865 bytes
btn/new/autocontrast.png | Bin 1351 -> 1351 bytes
btn/new/bucket24.png | Bin 1362 -> 1362 bytes
btn/new/bucket24x.png | Bin 1136 -> 1136 bytes
btn/new/colorbar.png | Bin 397 -> 397 bytes
btn/new/colorbarzero.png | Bin 640 -> 640 bytes
btn/new/crosshairs.png | Bin 393 -> 393 bytes
btn/new/ellipse.png | Bin 787 -> 787 bytes
btn/new/hat.png | Bin 892 -> 892 bytes
btn/new/hires.bmp | Bin 382 -> 382 bytes
btn/new/hires.png | Bin 538 -> 538 bytes
btn/new/hires16.png | Bin 245 -> 245 bytes
btn/new/hires16b.png | Bin 242 -> 242 bytes
btn/new/hires16lx.png | Bin 212 -> 212 bytes
btn/new/hires16win.PNG | Bin 287 -> 287 bytes
btn/new/hires16winz.PNG | Bin 287 -> 287 bytes
btn/new/hires256.png | Bin 1207 -> 1207 bytes
btn/new/hires256b.png | Bin 1207 -> 1207 bytes
btn/new/magichat.png | Bin 999 -> 999 bytes
btn/new/pen24.png | Bin 732 -> 732 bytes
btn/new/refresh.png | Bin 699 -> 699 bytes
btn/pastedpic_08032008_133503.png | Bin 48778 -> 48778 bytes
btn/pen.bmp | Bin 1782 -> 1782 bytes
btn/penauto.bmp | Bin 1782 -> 1782 bytes
btn/refresh.bmp | Bin 1782 -> 1782 bytes
btn/render.png | Bin 3817 -> 3817 bytes
btn/roi3d.bmp | Bin 1782 -> 1782 bytes
btn/roiellipse.bmp | Bin 1782 -> 1782 bytes
btn/roifill.bmp | Bin 1782 -> 1782 bytes
btn/roihide.bmp | Bin 1782 -> 1782 bytes
btn/xbars.bmp | Bin 1782 -> 1782 bytes
btn/zcolor.png | Bin 192 -> 192 bytes
btn/zcolorbar.bmp | Bin 918 -> 918 bytes
common/define_types.pas | 61 +-
common/dialogsx.pas | 32 +-
common/gzio2.pas | 45 +-
common/nifti_hdr.pas | 11 +-
crop.pas | 211 +-
crop.pas => crop_old.pas | 0
cropedges.lfm | 16 +-
cropedges.lrs | 58 +-
cropedges.pas | 6 +
dcm2nii/PARtoNRRD_Philips_RelX.zip | Bin 16690 -> 16690 bytes
dcm2nii/convert.pas | 568 ++--
dcm2nii/convertsimple.pas | 20 +-
dcm2nii/csaread.pas | 40 +-
dcm2nii/dcm2nii.cfg | 5 +-
dcm2nii/dcm2nii.dof | 62 +-
dcm2nii/dcm2nii.ico | Bin 766 -> 766 bytes
dcm2nii/dcm2nii.ini | 2 +
dcm2nii/dcm2nii.lpi | 833 +++--
dcm2nii/dcm2nii.lpr | 2 +-
dcm2nii/dcm2nii.or | Bin 1880 -> 1880 bytes
dcm2nii/dcm2nii.rci | 6 -
dcm2nii/dcm2nii.res | Bin 1660 -> 1656 bytes
dcm2nii/dcm2nii48.ico | Bin 17542 -> 17542 bytes
dcm2nii/dcm2niigui.app/Contents/MacOS/dcm2niigui | 1 -
dcm2nii/dcm2niigui.ico | Bin 17542 -> 17542 bytes
dcm2nii/dcm2niigui.ini | 6 +-
dcm2nii/dcm2niigui.lpi | 439 +--
dcm2nii/dcm2niigui.lpr | 2 +-
dcm2nii/dcm2niigui.manifest | 17 +
dcm2nii/dcm2niigui.or | Bin 7392 -> 4396 bytes
dcm2nii/dcm2niigui.rc | 6 +
dcm2nii/dcm2niigui.res | Bin 18568 -> 18568 bytes
dcm2nii/dialogs_msg.pas | 27 +
dcm2nii/dicomcompat.pas | 580 ++--
.../{dicomcompat.pas => dicomcompat_28June.pas} | 280 +-
dcm2nii/dicomfast.pas | 16 +-
dcm2nii/dicomfastread.pas | 48 +-
dcm2nii/dicomtypes.pas | 31 +-
dcm2nii/example/attention.nii.gz | Bin 3867 -> 0 bytes
dcm2nii/example/cutr.ini | 23 -
dcm2nii/example/fmri2r.ini | 24 -
dcm2nii/example/fmri3r.ini | 22 -
dcm2nii/example/fmrir.ini | 22 -
dcm2nii/example/lesions/1.voi | Bin 17430 -> 0 bytes
dcm2nii/example/lesions/10.voi | Bin 10690 -> 0 bytes
dcm2nii/example/lesions/11.voi | Bin 11831 -> 0 bytes
dcm2nii/example/lesions/12.voi | Bin 13414 -> 0 bytes
dcm2nii/example/lesions/13.voi | Bin 10198 -> 0 bytes
dcm2nii/example/lesions/14.voi | Bin 15461 -> 0 bytes
dcm2nii/example/lesions/15.voi | Bin 10936 -> 0 bytes
dcm2nii/example/lesions/16.voi | Bin 11507 -> 0 bytes
dcm2nii/example/lesions/17.voi | Bin 11551 -> 0 bytes
dcm2nii/example/lesions/18.voi | Bin 11438 -> 0 bytes
dcm2nii/example/lesions/19.voi | Bin 11080 -> 0 bytes
dcm2nii/example/lesions/2.voi | Bin 13119 -> 0 bytes
dcm2nii/example/lesions/20.voi | Bin 10404 -> 0 bytes
dcm2nii/example/lesions/21.voi | Bin 11005 -> 0 bytes
dcm2nii/example/lesions/22.voi | Bin 11679 -> 0 bytes
dcm2nii/example/lesions/23.voi | Bin 11473 -> 0 bytes
dcm2nii/example/lesions/24.voi | Bin 9567 -> 0 bytes
dcm2nii/example/lesions/3.voi | Bin 13062 -> 0 bytes
dcm2nii/example/lesions/4.voi | Bin 10333 -> 0 bytes
dcm2nii/example/lesions/5.voi | Bin 13618 -> 0 bytes
dcm2nii/example/lesions/6.voi | Bin 16209 -> 0 bytes
dcm2nii/example/lesions/7.voi | Bin 14027 -> 0 bytes
dcm2nii/example/lesions/8.voi | Bin 15355 -> 0 bytes
dcm2nii/example/lesions/9.voi | Bin 14958 -> 0 bytes
dcm2nii/example/lesions/binomial.val | 29 -
dcm2nii/example/lesions/continuous.val | 29 -
dcm2nii/example/saccades.nii.gz | Bin 8222 -> 0 bytes
dcm2nii/fpc-res.or | Bin 1946 -> 1946 bytes
dcm2nii/fpc-res.res | Bin 1672 -> 0 bytes
dcm2nii/gui.dfm | Bin 2462 -> 2463 bytes
dcm2nii/gui.lfm | 14 +-
dcm2nii/gui.lrs | 22 +-
dcm2nii/gui.pas | 59 +-
dcm2nii/lsjpeg.pas | 1528 ++++-----
dcm2nii/manifest.or | Bin 1308 -> 1308 bytes
dcm2nii/manifest.res | Bin 1191 -> 0 bytes
dcm2nii/nifti_form.dfm | Bin 2791 -> 2791 bytes
dcm2nii/nifti_form.lfm | 86 +-
dcm2nii/nifti_form.lrs | 117 +-
dcm2nii/niftiutil.pas | 252 +-
dcm2nii/nii_3dto4d.pas | 54 +-
dcm2nii/nii_4dto3d.pas | 79 +-
dcm2nii/nii_asl.pas | 78 +-
dcm2nii/nii_crop.pas | 78 +-
dcm2nii/nii_orient.pas | 18 +-
dcm2nii/nii_reslice.pas | 10 +-
dcm2nii/paramstrs.pas | 84 +-
dcm2nii/parconvert.pas | 268 +-
dcm2nii/philips_bvec.pas | 232 ++
dcm2nii/pref_form.dfm | Bin 3630 -> 3630 bytes
dcm2nii/pref_form.pas | 4 +-
dcm2nii/prefs.pas | 21 +-
dcm2nii/readint.dfm | Bin 644 -> 644 bytes
dcm2nii/sortdicom.pas | 65 +-
dcm2nii/untar.pas | 10 +-
dcm2nii/windowsxp.res | Bin 736 -> 736 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/LibTar.pas | 0
.../PARtoNRRD_Philips_RelX.zip | Bin 16690 -> 16690 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/SelectFolder.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/convert.pas | 339 +-
.../convertsimple.pas | 2 +-
{dcm2nii => dcm2nii_prePARRECDTI}/csaread.pas | 4 +-
.../dcm2nii.app/Contents/Info.plist | 0
.../dcm2nii.app/Contents/MacOS/dcm2nii | 0
.../dcm2nii.app}/Contents/PkgInfo | 0
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2nii.cfg | 5 +-
.../dcm2nii.dof | 25 +-
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2nii.dpr | 0
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2nii.ico | Bin 766 -> 766 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2nii.ini | 2 +
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2nii.lpi | 865 +++---
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2nii.lpr | 0
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2nii.or | Bin 1880 -> 1880 bytes
dcm2nii_prePARRECDTI/dcm2nii.res | Bin 0 -> 1656 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2nii48.ico | Bin 17542 -> 17542 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2niigui.cfg | 0
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2niigui.dof | 0
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2niigui.dpr | 0
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2niigui.ico | Bin 17542 -> 17542 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2niigui.ini | 6 +-
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2niigui.lpi | 322 +-
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2niigui.lpr | 0
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2niigui.lrs | 0
dcm2nii_prePARRECDTI/dcm2niigui.manifest | 17 +
dcm2nii_prePARRECDTI/dcm2niigui.or | Bin 0 -> 4396 bytes
dcm2nii_prePARRECDTI/dcm2niigui.rc | 7 +
{dcm2nii => dcm2nii_prePARRECDTI}/dcm2niigui.res | Bin 18568 -> 18404 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/dicom.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/dicomcompat.pas | 236 +-
{dcm2nii => dcm2nii_prePARRECDTI}/dicomfast.pas | 0
.../dicomfastread.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/dicomtypes.pas | 7 +-
{dcm2nii => dcm2nii_prePARRECDTI}/diskfree.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/extrafpc.cfg | 0
{dcm2nii => dcm2nii_prePARRECDTI}/filename.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/fpc-res.or | Bin 1946 -> 1946 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/gui.dfm | Bin 2462 -> 2463 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/gui.lfm | 15 +-
dcm2nii_prePARRECDTI/gui.lrs | 47 +
{dcm2nii => dcm2nii_prePARRECDTI}/gui.pas | 33 +-
{dcm2nii => dcm2nii_prePARRECDTI}/guii.lrs | 0
{dcm2nii => dcm2nii_prePARRECDTI}/lsjpeg.pas | 1528 ++++-----
{dcm2nii => dcm2nii_prePARRECDTI}/manifest.or | Bin 1308 -> 1308 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/nifti_form.dfm | Bin 2791 -> 2791 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/nifti_form.lfm | 86 +-
dcm2nii_prePARRECDTI/nifti_form.lrs | 62 +
{dcm2nii => dcm2nii_prePARRECDTI}/nifti_form.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/niftiutil.pas | 339 +-
{dcm2nii => dcm2nii_prePARRECDTI}/nii_3dto4d.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/nii_4dto3d.pas | 29 +-
{dcm2nii => dcm2nii_prePARRECDTI}/nii_asl.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/nii_crop.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/nii_math.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/nii_orient.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/nii_reslice.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/notes.txt | 0
{dcm2nii => dcm2nii_prePARRECDTI}/paramstrs.pas | 37 +-
{dcm2nii => dcm2nii_prePARRECDTI}/parconvert.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/pref_form.dfm | Bin 3630 -> 3630 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/pref_form.lfm | 0
{dcm2nii => dcm2nii_prePARRECDTI}/pref_form.lrs | 0
{dcm2nii => dcm2nii_prePARRECDTI}/pref_form.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/prefs.pas | 21 +-
{dcm2nii => dcm2nii_prePARRECDTI}/readint.dfm | Bin 644 -> 644 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/readint.lrs | 0
{dcm2nii => dcm2nii_prePARRECDTI}/readint.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/sortdicom.pas | 29 +-
{dcm2nii => dcm2nii_prePARRECDTI}/untar.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/userdir.pas | 0
{dcm2nii => dcm2nii_prePARRECDTI}/windowsxp.res | Bin 736 -> 736 bytes
{dcm2nii => dcm2nii_prePARRECDTI}/zconf.inc | 0
example/attention.nii.gz | Bin 3867 -> 3867 bytes
example/dataset/1.voi | Bin 17441 -> 17441 bytes
example/dataset/10.voi | Bin 10703 -> 10703 bytes
example/dataset/11.voi | Bin 11845 -> 11845 bytes
example/dataset/12.voi | Bin 13425 -> 13425 bytes
example/dataset/13.voi | Bin 10209 -> 10209 bytes
example/dataset/14.voi | Bin 15475 -> 15475 bytes
example/dataset/15.voi | Bin 10948 -> 10948 bytes
example/dataset/16.voi | Bin 11519 -> 11519 bytes
example/dataset/17.voi | Bin 11562 -> 11562 bytes
example/dataset/18.voi | Bin 11449 -> 11449 bytes
example/dataset/19.voi | Bin 11093 -> 11093 bytes
example/dataset/2.voi | Bin 13131 -> 13131 bytes
example/dataset/20.voi | Bin 10415 -> 10415 bytes
example/dataset/21.voi | Bin 11017 -> 11017 bytes
example/dataset/22.voi | Bin 11690 -> 11690 bytes
example/dataset/23.voi | Bin 11486 -> 11486 bytes
example/dataset/24.voi | Bin 9578 -> 9578 bytes
example/dataset/3.voi | Bin 13074 -> 13074 bytes
example/dataset/4.voi | Bin 10343 -> 10343 bytes
example/dataset/5.voi | Bin 13631 -> 13631 bytes
example/dataset/6.voi | Bin 16221 -> 16221 bytes
example/dataset/7.voi | Bin 14037 -> 14037 bytes
example/dataset/8.voi | Bin 15369 -> 15369 bytes
example/dataset/9.voi | Bin 14971 -> 14971 bytes
example/saccades.nii.gz | Bin 8222 -> 8222 bytes
fpc-res.or | Bin 62006 -> 62006 bytes
fpc-res.res | Bin 61560 -> 61560 bytes
fpmath/tpmath.pdf | Bin 426367 -> 426367 bytes
histoform.lfm | 17 +-
histoform.lrs | 30 +-
histoform.pas | 17 +-
html/images/48x36.gif | Bin 1367 -> 1367 bytes
html/images/autocrop.jpg | Bin 23878 -> 23878 bytes
html/images/dcm2niigui.gif | Bin 7622 -> 7622 bytes
html/images/design.gif | Bin 2629 -> 2629 bytes
html/images/draw/3dfill.png | Bin 1163 -> 1163 bytes
html/images/draw/circle.png | Bin 740 -> 740 bytes
html/images/draw/closedpen.png | Bin 884 -> 884 bytes
html/images/draw/fill.png | Bin 1228 -> 1228 bytes
html/images/draw/pen.png | Bin 915 -> 915 bytes
html/images/examplefmri.jpg | Bin 11387 -> 11387 bytes
html/images/examplefmri_multi.jpg | Bin 27321 -> 27321 bytes
html/images/icon.png | Bin 5404 -> 5404 bytes
html/images/layers.gif | Bin 3308 -> 3308 bytes
html/images/lazarus.gif | Bin 6191 -> 6191 bytes
html/images/lesionsum.jpg | Bin 23381 -> 23381 bytes
html/images/lieber.gif | Bin 8251 -> 8251 bytes
html/images/main.jpg | Bin 47870 -> 47870 bytes
html/images/meld.jpg | Bin 15308 -> 15308 bytes
html/images/nifti.jpg | Bin 12607 -> 12607 bytes
html/images/npm.gif | Bin 8069 -> 8069 bytes
html/images/patient9.jpg | Bin 9007 -> 9007 bytes
html/images/prefs.gif | Bin 4893 -> 4893 bytes
html/images/renderAAL.gif | Bin 8535 -> 8535 bytes
html/images/results.jpg | Bin 23732 -> 23732 bytes
html/images/space.gif | Bin 6760 -> 6760 bytes
html/images/splash.jpg | Bin 38280 -> 38280 bytes
html/images/threshold.gif | Bin 22785 -> 22785 bytes
html/images/transparency.gif | Bin 39424 -> 39424 bytes
html/images/val.gif | Bin 4045 -> 4045 bytes
html/images/zhistogram.gif | Bin 4416 -> 4416 bytes
html/peri/images/eventtime.png | Bin 6377 -> 6377 bytes
html/peri/images/icon.png | Bin 5404 -> 5404 bytes
html/peri/images/meld.jpg | Bin 15308 -> 15308 bytes
html/peri/images/periset.png | Bin 2537 -> 2537 bytes
html/peri/images/peristimulusplot.png | Bin 9091 -> 9091 bytes
html/peri/images/perivol.png | Bin 4183 -> 4183 bytes
html/peri/images/timeline.png | Bin 12642 -> 12642 bytes
html/tutorial/images/design.gif | Bin 2820 -> 2820 bytes
html/tutorial/images/icon.png | Bin 5404 -> 5404 bytes
html/tutorial/images/lesionsum.jpg | Bin 23381 -> 23381 bytes
html/tutorial/images/lieber.gif | Bin 8251 -> 8251 bytes
html/tutorial/images/meld.jpg | Bin 15308 -> 15308 bytes
html/tutorial/images/npm.gif | Bin 8069 -> 8069 bytes
html/tutorial/images/patient9.jpg | Bin 9007 -> 9007 bytes
html/tutorial/images/results.jpg | Bin 23732 -> 23732 bytes
html/tutorial/images/threshold.gif | Bin 22785 -> 22785 bytes
html/tutorial/images/val.gif | Bin 4045 -> 4045 bytes
html/tutorial/images/zhistogram.gif | Bin 4416 -> 4416 bytes
iconfinal.ico | Bin 30406 -> 30406 bytes
icons/dcm2niigui.png | Bin 10966 -> 10966 bytes
icons/mricrogl.png | Bin 13216 -> 13216 bytes
icons/mricron.png | Bin 2109 -> 2109 bytes
icons/npm.png | Bin 22904 -> 22904 bytes
lut/16.lut | Bin 768 -> 768 bytes
lut/1hot.lut | Bin 768 -> 768 bytes
lut/2winter.lut | Bin 768 -> 768 bytes
lut/3warm.lut | Bin 768 -> 768 bytes
lut/4cool.lut | Bin 768 -> 768 bytes
lut/5redyell.lut | Bin 768 -> 768 bytes
lut/6bluegrn.lut | Bin 768 -> 768 bytes
lut/GE_color.lut | Bin 768 -> 768 bytes
lut/HOTIRON.lut | Bin 768 -> 768 bytes
lut/NIH.lut | Bin 768 -> 768 bytes
lut/NIH_fire.lut | Bin 768 -> 768 bytes
lut/NIH_ice.lut | Bin 768 -> 768 bytes
lut/Rainramp.lut | Bin 768 -> 768 bytes
lut/actc.lut | Bin 768 -> 768 bytes
lut/blackbdy.lut | Bin 768 -> 768 bytes
lut/bluegray.lut | Bin 768 -> 768 bytes
lut/bone.lut | Bin 768 -> 768 bytes
lut/cardiac.lut | Bin 768 -> 768 bytes
lut/flow.lut | Bin 768 -> 768 bytes
lut/french.lut | Bin 768 -> 768 bytes
lut/gold.lut | Bin 768 -> 768 bytes
lut/gooch.lut | Bin 768 -> 768 bytes
lut/greengray.lut | Bin 768 -> 768 bytes
lut/pink.lut | Bin 768 -> 768 bytes
lut/pink_old.lut | Bin 768 -> 768 bytes
lut/spectrum.lut | Bin 768 -> 768 bytes
lut/x_hot.lut | Bin 768 -> 768 bytes
lut/x_rain.lut | Bin 768 -> 768 bytes
manifest.res | Bin 796 -> 796 bytes
mini.bmp | Bin 70 -> 70 bytes
.../Contents/Info.plist | 8 +-
mricron.app/Contents/MacOS/mricron | 1 +
.../dcm2nii.app => mricron.app}/Contents/PkgInfo | 0
mricron.ico | Bin 30406 -> 30406 bytes
mricron.ini | 8 +-
mricron.lpi | 240 +-
mricron.or | Bin 7392 -> 4396 bytes
mricron.res | Bin 30726 -> 30728 bytes
nifti_hdr_view.lfm | 276 +-
nifti_hdr_view.lrs | 668 ++--
nifti_hdr_view.pas | 16 +-
nifti_img.pas | 46 +-
nifti_img_view.lfm | 16 +-
nifti_img_view.lrs | 378 +--
nifti_img_view.pas | 31 +-
niftiview.ico | Bin 7886 -> 7886 bytes
npm/LesionStatThds.pas | 16 +-
npm/Mat.pas | 4 +-
npm/ReadFloat.dfm | Bin 682 -> 682 bytes
npm/ReadInt.dfm | Bin 644 -> 644 bytes
npm/StatThds.pas | 23 +-
npm/StatThdsUtil.pas | 15 +-
npm/Vector.pas | 4 +-
npm/_npmcl.bat | 6 +
npm/design.dfm | Bin 1714 -> 1714 bytes
npm/dice.ico | Bin 766 -> 766 bytes
npm/firth.pas | 77 +-
npm/firthThds.pas | 37 +-
npm/fpc-res.or | Bin 1236 -> 1236 bytes
npm/fpc-res.res | Bin 1012 -> 1012 bytes
npm/hdr.pas | 69 +-
npm/montecarlo.pas | 2 +-
npm/nifti_img.pas | 47 +-
npm/npm.cfg | 5 +-
npm/npm.dof | 60 +-
npm/npm.dsk | 184 ++
npm/npm.ini | 5 +-
npm/npm.lpi | 560 ++--
npm/npm.or | Bin 7312 -> 4396 bytes
npm/npm.res | Bin 876 -> 876 bytes
npm/npmcl.lpi | 77 +
npm/npmcl.lpr | 187 ++
npm/npmform.dfm | Bin 5693 -> 5083 bytes
npm/npmform.lfm | 39 +-
npm/npmform.lrs | 114 +-
npm/npmform.pas | 3249 ++++----------------
npm/overlap.pas | 78 +-
npm/part.pas | 22 +-
npm/prefs.pas | 102 +-
npm/regression.pas | 374 ++-
npm/roc.pas | 20 +-
npm/spread.dfm | Bin 3365 -> 3349 bytes
npm/spread.lfm | 11 +-
npm/spread.lrs | 130 +-
npm/spread.pas | 20 +-
npm/statcr.pas | 6 +-
npm/stats.pas | 10 +-
npm/tfce_clustering.7z | Bin 0 -> 2105 bytes
npm/tfce_clustering.pas | 273 ++
npm/tfce_clustering.zip | Bin 0 -> 2301 bytes
npm/turbolesion.pas | 131 +-
npm/{turbolesion.pas => turbolesion_cmdLine.pas} | 126 +-
npm/unpm.pas | 1679 ++++++++++
npm/upower.pas | 6 +-
npm/valformat.pas | 19 +-
npm/windowsxp.res | Bin 736 -> 736 bytes
{npm => npm_precl}/Copy of npm.cfg | 0
{npm => npm_precl}/Copy of prefs.pas | 0
{npm => npm_precl}/Copy of turbolesion.pas | 0
{npm => npm_precl}/LesionStatThds.pas | 0
{npm => npm_precl}/Mat.pas | 0
{npm => npm_precl}/ReadFloat.dfm | Bin 682 -> 682 bytes
{npm => npm_precl}/ReadFloat.pas | 0
{npm => npm_precl}/ReadInt.dfm | Bin 644 -> 644 bytes
{npm => npm_precl}/ReadInt.lfm | 0
{npm => npm_precl}/ReadInt.lrs | 0
{npm => npm_precl}/ReadInt.pas | 0
{npm => npm_precl}/StatThds.pas | 0
{npm => npm_precl}/StatThdsUtil.pas | 0
{npm => npm_precl}/Vector.pas | 0
{npm => npm_precl}/anacom.pas | 0
{npm => npm_precl}/associate.pas | 0
{npm => npm_precl}/brunner.pas | 0
{npm => npm_precl}/design.dfm | Bin 1714 -> 1714 bytes
{npm => npm_precl}/design.lfm | 0
{npm => npm_precl}/design.lrs | 0
{npm => npm_precl}/design.pas | 0
{npm => npm_precl}/dice.ico | Bin 766 -> 766 bytes
{npm => npm_precl}/dmath/GraphicsMathLibrary.pas | 0
{npm => npm_precl}/dmath/Matrices.pas | 0
{npm => npm_precl}/dmath/Regress.pas | 0
{npm => npm_precl}/dmath/_clean.bat | 0
{npm => npm_precl}/dmath/eigen.pas | 0
{npm => npm_precl}/dmath/fcomp.pas | 0
{npm => npm_precl}/dmath/fitexlin.pas | 0
{npm => npm_precl}/dmath/fitexpo.pas | 0
{npm => npm_precl}/dmath/fitfrac.pas | 0
{npm => npm_precl}/dmath/fithill.pas | 0
{npm => npm_precl}/dmath/fitiexpo.pas | 0
{npm => npm_precl}/dmath/fitlin.pas | 0
{npm => npm_precl}/dmath/fitlogis.pas | 0
{npm => npm_precl}/dmath/fitmich.pas | 0
{npm => npm_precl}/dmath/fitmult.pas | 0
{npm => npm_precl}/dmath/fitpka.pas | 0
{npm => npm_precl}/dmath/fitpoly.pas | 0
{npm => npm_precl}/dmath/fitpower.pas | 0
{npm => npm_precl}/dmath/fmath.pas | 0
{npm => npm_precl}/dmath/fourier.pas | 0
{npm => npm_precl}/dmath/matcomp.pas | 0
{npm => npm_precl}/dmath/math387.inc | 0
{npm => npm_precl}/dmath/mathp2.inc | 0
{npm => npm_precl}/dmath/mcmc.pas | 0
{npm => npm_precl}/dmath/models.pas | 0
{npm => npm_precl}/dmath/optim.pas | 0
{npm => npm_precl}/dmath/pastring.pas | 0
{npm => npm_precl}/dmath/plot.inc | 0
{npm => npm_precl}/dmath/plot.pas | 0
{npm => npm_precl}/dmath/plotvar.inc | 0
{npm => npm_precl}/dmath/polynom.pas | 0
{npm => npm_precl}/dmath/regmultdelphi.pas | 0
{npm => npm_precl}/dmath/simopt.pas | 0
{npm => npm_precl}/dmath/stat.pas | 0
{npm => npm_precl}/dmath/texplot.pas | 0
{npm => npm_precl}/dmath/winplot.pas | 0
{dcm2nii => npm_precl}/extrafpc.cfg | 0
{npm => npm_precl}/filename.pas | 0
{npm => npm_precl}/firth.pas | 0
{npm => npm_precl}/firthThds.pas | 0
{npm => npm_precl}/fpc-res.or | Bin 1236 -> 1236 bytes
{npm => npm_precl}/fpc-res.res | Bin 1012 -> 1012 bytes
{npm => npm_precl}/hdr.pas | 4 +-
{npm => npm_precl}/lesion_pattern.pas | 0
{npm => npm_precl}/montecarlo.pas | 0
{npm => npm_precl}/nifti_img.pas | 0
{npm => npm_precl}/npm.app/Contents/Info.plist | 0
{npm => npm_precl}/npm.app/Contents/MacOS/npm | 0
.../npm.app}/Contents/PkgInfo | 0
{npm => npm_precl}/npm.cfg | 5 +-
dcm2nii/dcm2niigui.dof => npm_precl/npm.dof | 17 +-
{npm => npm_precl}/npm.dpr | 0
{npm => npm_precl}/npm.ini | 3 +-
{npm => npm_precl}/npm.lpi | 358 ++-
{npm => npm_precl}/npm.lpr | 0
npm_precl/npm.or | Bin 0 -> 4396 bytes
{npm => npm_precl}/npm.res | Bin 876 -> 876 bytes
{npm => npm_precl}/npmform.dfm | Bin 5693 -> 5743 bytes
{npm => npm_precl}/npmform.lfm | 25 +-
npm_precl/npmform.lrs | 86 +
{npm => npm_precl}/npmform.pas | 125 +-
{npm => npm_precl/old}/anacom.pas | 0
{npm => npm_precl}/old/lesion.pas | 0
{npm => npm_precl}/old/montecarlo.pas | 0
{npm => npm_precl}/options.inc | 0
{npm => npm_precl}/overlap.pas | 0
{npm => npm_precl}/part.pas | 0
{npm => npm_precl}/prefs.pas | 0
{npm => npm_precl}/regression.pas | 143 +-
{npm => npm_precl}/results.niiNotesseverity.txt | 0
{npm => npm_precl}/roc.pas | 0
{npm => npm_precl}/spread.dfm | Bin 3365 -> 3349 bytes
{npm => npm_precl}/spread.lfm | 11 +-
npm_precl/spread.lrs | 66 +
{npm => npm_precl}/spread.pas | 20 +-
{npm => npm_precl}/statcr.pas | 0
{npm => npm_precl}/stats.pas | 0
npm_precl/tfce_clustering.7z | Bin 0 -> 2105 bytes
npm_precl/tfce_clustering.pas | 273 ++
npm_precl/tfce_clustering.zip | Bin 0 -> 2301 bytes
{npm => npm_precl}/turbolesion.pas | 0
{npm => npm_precl}/upower.pas | 0
{npm => npm_precl}/valformat.pas | 0
{dcm2nii => npm_precl}/windowsxp.res | Bin 736 -> 736 bytes
{npm => npm_precl}/xLesionStatThds.pas | 0
{npm => npm_precl}/xanacom.pas | 0
{npm => npm_precl}/xmontecarlo.pas | 0
{dcm2nii => npm_precl}/zconf.inc | 0
ortho_reorient.pas | 8 +-
prefs.lfm | 26 +-
prefs.lrs | 30 +-
prefs.pas | 19 +-
reorient.dfm | Bin 1921 -> 1921 bytes
reslice_img.pas | 3 +-
templates/aal.nii.gz | Bin 163652 -> 163652 bytes
templates/aal.nii.lut | Bin 768 -> 768 bytes
templates/brodmann.nii.gz | Bin 174606 -> 174606 bytes
templates/brodmann.nii.lut | Bin 768 -> 768 bytes
templates/ch2bet.nii.gz | Bin 1329166 -> 1329166 bytes
Text.lfm => text.lfm | 9 +-
text.pas | 17 +-
winres.res | Bin 9498 -> 9498 bytes
534 files changed, 12523 insertions(+), 9102 deletions(-)
diff --git a/CarbonOpenDoc.pas b/CarbonOpenDoc.pas
old mode 100644
new mode 100755
diff --git a/MultiSlice.lfm b/MultiSlice.lfm
old mode 100644
new mode 100755
index acf1073..6a6c9c6
--- a/MultiSlice.lfm
+++ b/MultiSlice.lfm
@@ -4,7 +4,7 @@ object MultiSliceForm: TMultiSliceForm
Top = 292
Width = 745
Caption = 'MultiSlice'
- ClientHeight = 223
+ ClientHeight = 242
ClientWidth = 745
Font.Height = -11
Font.Name = 'MS Sans Serif'
@@ -13,15 +13,15 @@ object MultiSliceForm: TMultiSliceForm
OnCreate = FormCreate
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '0.9.29'
+ LCLVersion = '0.9.30.2'
object MultiPanel: TScrollBox
Left = 0
- Height = 223
+ Height = 242
Top = 0
Width = 745
Align = alClient
- ClientHeight = 219
- ClientWidth = 741
+ ClientHeight = 242
+ ClientWidth = 745
TabOrder = 0
object MultiImage: TImage
Tag = 2
@@ -168,4 +168,4 @@ object MultiSliceForm: TMultiSliceForm
left = 97
top = 11
end
-end
+end
\ No newline at end of file
diff --git a/MultiSlice.lrs b/MultiSlice.lrs
old mode 100644
new mode 100755
index e559194..061ffd5
--- a/MultiSlice.lrs
+++ b/MultiSlice.lrs
@@ -3,14 +3,14 @@
LazarusResources.Add('TMultiSliceForm','FORMDATA',[
'TPF0'#15'TMultiSliceForm'#14'MultiSliceForm'#4'Left'#3#237#1#6'Height'#3#242
+#0#3'Top'#3'$'#1#5'Width'#3#233#2#7'Caption'#6#10'MultiSlice'#12'ClientHeigh'
- +'t'#3#223#0#11'ClientWidth'#3#233#2#11'Font.Height'#2#245#9'Font.Name'#6#13
+ +'t'#3#242#0#11'ClientWidth'#3#233#2#11'Font.Height'#2#245#9'Font.Name'#6#13
+'MS Sans Serif'#4'Menu'#7#9'MainMenu1'#7'OnClose'#7#9'FormClose'#8'OnCreate'
+#7#10'FormCreate'#6'OnShow'#7#8'FormShow'#8'Position'#7#14'poScreenCenter'#10
- +'LCLVersion'#6#6'0.9.29'#0#10'TScrollBox'#10'MultiPanel'#4'Left'#2#0#6'Heigh'
- +'t'#3#223#0#3'Top'#2#0#5'Width'#3#233#2#5'Align'#7#8'alClient'#12'ClientHeig'
- +'ht'#3#219#0#11'ClientWidth'#3#229#2#8'TabOrder'#2#0#0#6'TImage'#10'MultiIma'
- +'ge'#3'Tag'#2#2#6'Cursor'#7#7'crCross'#4'Left'#2#2#6'Height'#2#12#3'Top'#2#2
- +#5'Width'#2#12#8'AutoSize'#9#7'Stretch'#9#0#0#0#9'TMainMenu'#9'MainMenu1'#4
+ +'LCLVersion'#6#8'0.9.30.2'#0#10'TScrollBox'#10'MultiPanel'#4'Left'#2#0#6'Hei'
+ +'ght'#3#242#0#3'Top'#2#0#5'Width'#3#233#2#5'Align'#7#8'alClient'#12'ClientHe'
+ +'ight'#3#242#0#11'ClientWidth'#3#233#2#8'TabOrder'#2#0#0#6'TImage'#10'MultiI'
+ +'mage'#3'Tag'#2#2#6'Cursor'#7#7'crCross'#4'Left'#2#2#6'Height'#2#12#3'Top'#2
+ +#2#5'Width'#2#12#8'AutoSize'#9#7'Stretch'#9#0#0#0#9'TMainMenu'#9'MainMenu1'#4
+'left'#2'('#3'top'#2#8#0#9'TMenuItem'#5'File1'#7'Caption'#6#4'File'#0#9'TMen'
+'uItem'#9'Settings1'#7'Caption'#6#13'Open settings'#7'OnClick'#7#14'Settings'
+'1Click'#0#0#9'TMenuItem'#13'Savesettings1'#7'Caption'#6#13'Save settings'#8
@@ -46,4 +46,4 @@ LazarusResources.Add('TMultiSliceForm','FORMDATA',[
+#0#0#0#0#11'TSaveDialog'#15'MultiSaveDialog'#10'DefaultExt'#6#4'.ini'#6'Filt'
+'er'#6#19'Settings file|*.ini'#11'FilterIndex'#2#0#4'left'#2'a'#3'top'#2#11#0
+#0#0
-]);
+]);
\ No newline at end of file
diff --git a/MultiSlice.pas b/MultiSlice.pas
old mode 100644
new mode 100755
index 136e465..561012e
--- a/MultiSlice.pas
+++ b/MultiSlice.pas
@@ -860,6 +860,13 @@ begin
gMulti.SliceLabel := true;
for lSlice := 1 to gMulti.nSlices do
gMulti.SliceList[lSlice] := 62+10*lSlice;
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+ Copy1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ Savesettings1.ShortCut := ShortCut(Word('S'), [ssMeta]);
+ Closewindow1.ShortCut := ShortCut(Word('W'), [ssMeta]);
+ {$ENDIF}
+ {$ENDIF}
end;
{$IFNDEF FPC}
diff --git a/ROIfilt.lfm b/ROIfilt.lfm
old mode 100644
new mode 100755
diff --git a/ROIfilt.lrs b/ROIfilt.lrs
old mode 100644
new mode 100755
diff --git a/ROIfilt.pas b/ROIfilt.pas
old mode 100644
new mode 100755
diff --git a/ReadFloat.lfm b/ReadFloat.lfm
old mode 100644
new mode 100755
diff --git a/ReadFloat.lrs b/ReadFloat.lrs
old mode 100644
new mode 100755
diff --git a/ReadFloat.pas b/ReadFloat.pas
old mode 100644
new mode 100755
diff --git a/ReadInt.lfm b/ReadInt.lfm
old mode 100644
new mode 100755
diff --git a/ReadInt.lrs b/ReadInt.lrs
old mode 100644
new mode 100755
diff --git a/ReadInt.pas b/ReadInt.pas
old mode 100644
new mode 100755
diff --git a/Readme.txt b/Readme.txt
old mode 100644
new mode 100755
diff --git a/RenderThds.pas b/RenderThds.pas
old mode 100644
new mode 100755
diff --git a/Text.lrs b/Text.lrs
old mode 100644
new mode 100755
index 540c125..35588bd
--- a/Text.lrs
+++ b/Text.lrs
@@ -4,14 +4,14 @@ LazarusResources.Add('TTextForm','FORMDATA',[
'TPF0'#9'TTextForm'#8'TextForm'#4'Left'#3#161#1#6'Height'#3#224#1#3'Top'#3#195
+#0#5'Width'#3#184#2#18'HorzScrollBar.Page'#3#183#2#18'VertScrollBar.Page'#3
+#203#1#13'ActiveControl'#7#5'MemoT'#7'Caption'#6#22'Descriptive Statistics'
- +#12'ClientHeight'#3#205#1#11'ClientWidth'#3#184#2#11'Font.Height'#2#245#9'Fo'
- +'nt.Name'#6#13'MS Sans Serif'#4'Menu'#7#9'MainMenu1'#10'LCLVersion'#6#6'0.9.'
- +'29'#0#5'TMemo'#5'MemoT'#4'Left'#2#0#6'Height'#3#205#1#3'Top'#2#0#5'Width'#3
- +#184#2#5'Align'#7#8'alClient'#10'ScrollBars'#7#10'ssVertical'#8'TabOrder'#2#0
- +#0#0#9'TMainMenu'#9'MainMenu1'#4'left'#2'p'#3'top'#2#10#0#9'TMenuItem'#5'Fil'
- +'e1'#7'Caption'#6#4'File'#0#9'TMenuItem'#5'Save1'#7'Caption'#6#4'Save'#7'OnC'
- +'lick'#7#10'Save1Click'#0#0#9'TMenuItem'#12'Closewindow1'#7'Caption'#6#12'Cl'
- +'ose window'#7'OnClick'#7#17'Closewindow1Click'#0#0#0#9'TMenuItem'#5'Copy1'#7
- +'Caption'#6#4'Edit'#0#9'TMenuItem'#5'Copy2'#7'Caption'#6#4'Copy'#7'OnClick'#7
- +#10'Copy2Click'#0#0#0#0#0
-]);
+ +#12'ClientHeight'#3#224#1#11'ClientWidth'#3#184#2#11'Font.Height'#2#245#9'Fo'
+ +'nt.Name'#6#13'MS Sans Serif'#4'Menu'#7#9'MainMenu1'#8'OnCreate'#7#10'FormCr'
+ +'eate'#10'LCLVersion'#6#8'0.9.30.2'#0#5'TMemo'#5'MemoT'#4'Left'#2#0#6'Height'
+ +#3#224#1#3'Top'#2#0#5'Width'#3#184#2#5'Align'#7#8'alClient'#10'ScrollBars'#7
+ +#10'ssVertical'#8'TabOrder'#2#0#0#0#9'TMainMenu'#9'MainMenu1'#4'left'#2'p'#3
+ +'top'#2#10#0#9'TMenuItem'#5'File1'#7'Caption'#6#4'File'#0#9'TMenuItem'#5'Sav'
+ +'e1'#7'Caption'#6#4'Save'#7'OnClick'#7#10'Save1Click'#0#0#9'TMenuItem'#12'Cl'
+ +'osewindow1'#7'Caption'#6#12'Close window'#7'OnClick'#7#17'Closewindow1Click'
+ +#0#0#0#9'TMenuItem'#5'Copy1'#7'Caption'#6#4'Edit'#0#9'TMenuItem'#5'Copy2'#7
+ +'Caption'#6#4'Copy'#7'OnClick'#7#10'Copy2Click'#0#0#0#0#0
+]);
\ No newline at end of file
diff --git a/WINRES.or b/WINRES.or
old mode 100644
new mode 100755
diff --git a/_build.bat b/_build.bat
old mode 100644
new mode 100755
diff --git a/_clean.bat b/_clean.bat
old mode 100644
new mode 100755
index 820c571..9c0921d
--- a/_clean.bat
+++ b/_clean.bat
@@ -1,3 +1,4 @@
+del /S *.a
del /S *.o
del /S *.ppu
del /S *.bak
diff --git a/_dcm2nii.bat b/_dcm2nii.bat
new file mode 100755
index 0000000..22f9025
--- /dev/null
+++ b/_dcm2nii.bat
@@ -0,0 +1,8 @@
+chmod 777 ./_xclean.bat
+./_xclean.bat
+cp ./common/notgui.inc ./common/isgui.inc
+lazbuild ./dcm2nii/dcm2nii.lpr --cpu=x86_64 --compiler="/usr/local/bin/ppcx64"
+mv ./dcm2nii/dcm2nii ../distro/dcm2nii64
+
+./_xclean.bat
+cp ./common/gui.inc ./common/isgui.inc
diff --git a/_delphi.bat b/_delphi.bat
old mode 100644
new mode 100755
diff --git a/_delphizip.bat b/_delphizip.bat
old mode 100644
new mode 100755
index a95ffa3..e4b8308
--- a/_delphizip.bat
+++ b/_delphizip.bat
@@ -3,8 +3,8 @@ call _delphi.bat
REM compress MRIcron
c:\Progra~1\7-Zip\7z a -tzip c:\pas\wincron.zip c:\mricron
-copy /Y c:\pas\wincron.zip \\cocaswwebsrv1.ds.sc.edu\dept\mcbi\MCBI\CRNL\sw\mricron\win.zip
+copy /Y c:\pas\wincron.zip Y:\mcbi\MCBI\CRNL\sw\mricron\win.zip
REM compress Source
c:\Progra~1\7-Zip\7z a -tzip c:\pas\srccron.zip c:\pas\mricron
-copy c:\pas\srccron.zip \\cocaswwebsrv1.ds.sc.edu\dept\mcbi\MCBI\CRNL\sw\mricron\source.zip
\ No newline at end of file
+copy c:\pas\srccron.zip Y:\mcbi\MCBI\CRNL\sw\mricron\source.zip
\ No newline at end of file
diff --git a/_gtall.bat b/_gtall.bat
old mode 100644
new mode 100755
diff --git a/_gtall64.bat b/_gtall64.bat
old mode 100644
new mode 100755
diff --git a/_gtscript.bat b/_gtscript.bat
old mode 100644
new mode 100755
diff --git a/_lxall.bat b/_lxall.bat
old mode 100644
new mode 100755
diff --git a/_maclipo.bat b/_maclipo.bat
old mode 100644
new mode 100755
index 96653f4..5ce1a13
--- a/_maclipo.bat
+++ b/_maclipo.bat
@@ -1,4 +1,5 @@
-lipo -create ../distro/ppc/dcm2nii ../distro/intel/dcm2nii -output ../distro/dcm2nii
+# lipo -create ../distro/ppc/dcm2nii ../distro/intel/dcm2nii -output ../distro/dcm2nii
+cp ../distro/intel/dcm2nii ../distro/dcm2nii
lipo -create ../distro/ppc/mricron ../distro/intel/mricron -output ../distro/mricron.app/Contents/MacOS/mricron
lipo -create ../distro/ppc/dcm2niigui ../distro/intel/dcm2niigui -output ../distro/dcm2niigui.app/Contents/MacOS/dcm2niigui
lipo -create ../distro/ppc/npm ../distro/intel/npm -output ../distro/npm.app/Contents/MacOS/npm
diff --git a/_macscript.bat b/_macscript.bat
old mode 100644
new mode 100755
diff --git a/_macscriptintel.bat b/_macscriptintel.bat
old mode 100644
new mode 100755
index 185d8ad..9b2f8f9
--- a/_macscriptintel.bat
+++ b/_macscriptintel.bat
@@ -1,6 +1,9 @@
chmod 777 ./_xclean.bat
./_xclean.bat
cp ./common/notgui.inc ./common/isgui.inc
+lazbuild ./dcm2nii/dcm2nii.lpr --cpu=x86_64 --compiler="/usr/local/bin/ppcx64"
+mv ./dcm2nii/dcm2nii ../distro/dcm2nii64
+
lazbuild ./dcm2nii/dcm2nii.lpr
cp ./dcm2nii/dcm2nii ../distro/intel/dcm2nii
diff --git a/_macscriptintel104.bat b/_macscriptintel104.bat
old mode 100644
new mode 100755
diff --git a/_macscriptppc.bat b/_macscriptppc.bat
old mode 100644
new mode 100755
diff --git a/_qtscript.bat b/_qtscript.bat
old mode 100644
new mode 100755
diff --git a/_script.bat b/_script.bat
old mode 100644
new mode 100755
diff --git a/_winscript.bat b/_winscript.bat
old mode 100644
new mode 100755
diff --git a/_xcarbon.bat b/_xcarbon.bat
old mode 100644
new mode 100755
diff --git a/_xclean.bat b/_xclean.bat
old mode 100644
new mode 100755
index 06417b4..0a9f434
--- a/_xclean.bat
+++ b/_xclean.bat
@@ -1,15 +1,18 @@
+rm -r *.a
rm -r *.o
rm -r *.ppu
rm -r *.bak
rm mricron
cd ./rgb
+rm -r *.a
rm -r *.o
rm -r *.ppu
rm -r *.bak
cd ..
cd ./common
+rm -r *.a
rm -r *.o
rm -r *.ppu
rm -r *.bak
@@ -19,6 +22,7 @@ cd ..
cd ./dcm2nii
rm ./dcm2niigui
rm ./dcm2nii
+rm -r *.a
rm -r *.o
rm -r *.ppu
rm -r *.bak
diff --git a/about.lfm b/about.lfm
old mode 100644
new mode 100755
index 50ca8b0..1554eb8
--- a/about.lfm
+++ b/about.lfm
@@ -1,7 +1,7 @@
object AboutForm: TAboutForm
- Left = 659
+ Left = 683
Height = 127
- Top = 150
+ Top = 153
Width = 327
ActiveControl = Panel1
BorderIcons = [biSystemMenu]
@@ -16,7 +16,7 @@ object AboutForm: TAboutForm
Font.Name = 'MS Sans Serif'
OnCreate = FormCreate
Position = poScreenCenter
- LCLVersion = '0.9.29'
+ LCLVersion = '1.0.2.0'
object Panel1: TPanel
Left = 0
Height = 48
diff --git a/about.lrs b/about.lrs
old mode 100644
new mode 100755
index aa63a48..6ae14fc
--- a/about.lrs
+++ b/about.lrs
@@ -1,24 +1,24 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TAboutForm','FORMDATA',[
- 'TPF0'#10'TAboutForm'#9'AboutForm'#4'Left'#3#147#2#6'Height'#2#127#3'Top'#3
- +#150#0#5'Width'#3'G'#1#13'ActiveControl'#7#6'Panel1'#11'BorderIcons'#11#12'b'
+ 'TPF0'#10'TAboutForm'#9'AboutForm'#4'Left'#3#171#2#6'Height'#2#127#3'Top'#3
+ +#153#0#5'Width'#3'G'#1#13'ActiveControl'#7#6'Panel1'#11'BorderIcons'#11#12'b'
+'iSystemMenu'#0#11'BorderStyle'#7#8'bsDialog'#7'Caption'#6#8'About...'#12'Cl'
+'ientHeight'#2#127#11'ClientWidth'#3'G'#1#21'Constraints.MaxHeight'#2#127#20
+'Constraints.MaxWidth'#3'G'#1#21'Constraints.MinHeight'#2#127#20'Constraints'
+'.MinWidth'#3'G'#1#9'Font.Name'#6#13'MS Sans Serif'#8'OnCreate'#7#10'FormCre'
- +'ate'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#6'0.9.29'#0#6'TPanel'
- +#6'Panel1'#4'Left'#2#0#6'Height'#2'0'#3'Top'#2#0#5'Width'#3'G'#1#5'Align'#7#5
- +'alTop'#9'Alignment'#7#13'taLeftJustify'#10'BevelOuter'#7#6'bvNone'#7'Captio'
- +'n'#6#8' MRIcron'#10'Font.Color'#7#7'clBlack'#11'Font.Height'#2#237#9'Font.N'
- +'ame'#6#17'helvetica [adobe]'#10'Font.Style'#11#6'fsBold'#0#11'ParentColor'#8
- +#10'ParentFont'#8#8'TabOrder'#2#0#7'OnClick'#7#11'Panel1Click'#10'OnDragDrop'
- +#7#14'Panel1DragDrop'#0#0#6'TPanel'#6'Panel2'#4'Left'#2#8#6'Height'#2'C'#3'T'
- +'op'#2'/'#5'Width'#3'3'#1#12'ClientHeight'#2'C'#11'ClientWidth'#3'3'#1#8'Tab'
- +'Order'#2#1#0#6'TLabel'#13'HomepageLabel'#4'Left'#2#0#6'Height'#2#20#3'Top'#2
- +#10#5'Width'#3'1'#1#9'Alignment'#7#8'taCenter'#8'AutoSize'#8#7'Caption'#6#7
- +'version'#11'ParentColor'#8#7'OnClick'#7#13'HomePageClick'#0#0#6'TLabel'#11
- +'ThreadLabel'#4'Left'#2#1#6'Height'#2#20#3'Top'#2'$'#5'Width'#3'1'#1#9'Align'
- +'ment'#7#8'taCenter'#8'AutoSize'#8#7'Caption'#6#8' Threads'#11'ParentColor'#8
- +#0#0#0#0
+ +'ate'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#7'1.0.2.0'#0#6'TPane'
+ +'l'#6'Panel1'#4'Left'#2#0#6'Height'#2'0'#3'Top'#2#0#5'Width'#3'G'#1#5'Align'
+ +#7#5'alTop'#9'Alignment'#7#13'taLeftJustify'#10'BevelOuter'#7#6'bvNone'#7'Ca'
+ +'ption'#6#8' MRIcron'#10'Font.Color'#7#7'clBlack'#11'Font.Height'#2#237#9'Fo'
+ +'nt.Name'#6#17'helvetica [adobe]'#10'Font.Style'#11#6'fsBold'#0#11'ParentCol'
+ +'or'#8#10'ParentFont'#8#8'TabOrder'#2#0#7'OnClick'#7#11'Panel1Click'#10'OnDr'
+ +'agDrop'#7#14'Panel1DragDrop'#0#0#6'TPanel'#6'Panel2'#4'Left'#2#8#6'Height'#2
+ +'C'#3'Top'#2'/'#5'Width'#3'3'#1#12'ClientHeight'#2'C'#11'ClientWidth'#3'3'#1
+ +#8'TabOrder'#2#1#0#6'TLabel'#13'HomepageLabel'#4'Left'#2#0#6'Height'#2#20#3
+ +'Top'#2#10#5'Width'#3'1'#1#9'Alignment'#7#8'taCenter'#8'AutoSize'#8#7'Captio'
+ +'n'#6#7'version'#11'ParentColor'#8#7'OnClick'#7#13'HomePageClick'#0#0#6'TLab'
+ +'el'#11'ThreadLabel'#4'Left'#2#1#6'Height'#2#20#3'Top'#2'$'#5'Width'#3'1'#1#9
+ +'Alignment'#7#8'taCenter'#8'AutoSize'#8#7'Caption'#6#8' Threads'#11'ParentCo'
+ +'lor'#8#0#0#0#0
]);
diff --git a/about.pas b/about.pas
old mode 100644
new mode 100755
diff --git a/autoroi.lfm b/autoroi.lfm
old mode 100644
new mode 100755
diff --git a/autoroi.lrs b/autoroi.lrs
old mode 100644
new mode 100755
diff --git a/autoroi.pas b/autoroi.pas
old mode 100644
new mode 100755
diff --git a/batch.pas b/batch.pas
old mode 100644
new mode 100755
diff --git a/batchstatselect.pas b/batchstatselect.pas
old mode 100644
new mode 100755
diff --git a/bet.lfm b/bet.lfm
old mode 100644
new mode 100755
diff --git a/bet.lrs b/bet.lrs
old mode 100644
new mode 100755
diff --git a/bet.pas b/bet.pas
old mode 100644
new mode 100755
diff --git a/btn/autocon.bmp b/btn/autocon.bmp
old mode 100644
new mode 100755
diff --git a/btn/autocontrast.png b/btn/autocontrast.png
old mode 100644
new mode 100755
diff --git a/btn/blackbackbround.svg b/btn/blackbackbround.svg
old mode 100644
new mode 100755
diff --git a/btn/bucket24.png b/btn/bucket24.png
old mode 100644
new mode 100755
diff --git a/btn/colorbar.bmp b/btn/colorbar.bmp
old mode 100644
new mode 100755
diff --git a/btn/colorzero.bmp b/btn/colorzero.bmp
old mode 100644
new mode 100755
diff --git a/btn/drawing4z.svg b/btn/drawing4z.svg
old mode 100644
new mode 100755
diff --git a/btn/dti.svg b/btn/dti.svg
old mode 100644
new mode 100755
diff --git a/btn/icon.png b/btn/icon.png
old mode 100644
new mode 100755
diff --git a/btn/info.bmp b/btn/info.bmp
old mode 100644
new mode 100755
diff --git a/btn/magichat.png b/btn/magichat.png
old mode 100644
new mode 100755
diff --git a/btn/mini.svg b/btn/mini.svg
old mode 100644
new mode 100755
diff --git a/btn/new/3dx.png b/btn/new/3dx.png
old mode 100644
new mode 100755
diff --git a/btn/new/autoclose24.png b/btn/new/autoclose24.png
old mode 100644
new mode 100755
diff --git a/btn/new/autocontrast.png b/btn/new/autocontrast.png
old mode 100644
new mode 100755
diff --git a/btn/new/bucket24.png b/btn/new/bucket24.png
old mode 100644
new mode 100755
diff --git a/btn/new/bucket24x.png b/btn/new/bucket24x.png
old mode 100644
new mode 100755
diff --git a/btn/new/colorbar.png b/btn/new/colorbar.png
old mode 100644
new mode 100755
diff --git a/btn/new/colorbarzero.png b/btn/new/colorbarzero.png
old mode 100644
new mode 100755
diff --git a/btn/new/crosshairs.png b/btn/new/crosshairs.png
old mode 100644
new mode 100755
diff --git a/btn/new/ellipse.png b/btn/new/ellipse.png
old mode 100644
new mode 100755
diff --git a/btn/new/hat.png b/btn/new/hat.png
old mode 100644
new mode 100755
diff --git a/btn/new/hires.bmp b/btn/new/hires.bmp
old mode 100644
new mode 100755
diff --git a/btn/new/hires.png b/btn/new/hires.png
old mode 100644
new mode 100755
diff --git a/btn/new/hires16.png b/btn/new/hires16.png
old mode 100644
new mode 100755
diff --git a/btn/new/hires16b.png b/btn/new/hires16b.png
old mode 100644
new mode 100755
diff --git a/btn/new/hires16lx.png b/btn/new/hires16lx.png
old mode 100644
new mode 100755
diff --git a/btn/new/hires16win.PNG b/btn/new/hires16win.PNG
old mode 100644
new mode 100755
diff --git a/btn/new/hires16winz.PNG b/btn/new/hires16winz.PNG
old mode 100644
new mode 100755
diff --git a/btn/new/hires256.png b/btn/new/hires256.png
old mode 100644
new mode 100755
diff --git a/btn/new/hires256b.png b/btn/new/hires256b.png
old mode 100644
new mode 100755
diff --git a/btn/new/magichat.png b/btn/new/magichat.png
old mode 100644
new mode 100755
diff --git a/btn/new/pen24.png b/btn/new/pen24.png
old mode 100644
new mode 100755
diff --git a/btn/new/refresh.png b/btn/new/refresh.png
old mode 100644
new mode 100755
diff --git a/btn/pastedpic_08032008_133503.png b/btn/pastedpic_08032008_133503.png
old mode 100644
new mode 100755
diff --git a/btn/pen.bmp b/btn/pen.bmp
old mode 100644
new mode 100755
diff --git a/btn/penauto.bmp b/btn/penauto.bmp
old mode 100644
new mode 100755
diff --git a/btn/refresh.bmp b/btn/refresh.bmp
old mode 100644
new mode 100755
diff --git a/btn/render.png b/btn/render.png
old mode 100644
new mode 100755
diff --git a/btn/reslicing.svg b/btn/reslicing.svg
old mode 100644
new mode 100755
diff --git a/btn/roi3d.bmp b/btn/roi3d.bmp
old mode 100644
new mode 100755
diff --git a/btn/roiellipse.bmp b/btn/roiellipse.bmp
old mode 100644
new mode 100755
diff --git a/btn/roifill.bmp b/btn/roifill.bmp
old mode 100644
new mode 100755
diff --git a/btn/roihide.bmp b/btn/roihide.bmp
old mode 100644
new mode 100755
diff --git a/btn/xbars.bmp b/btn/xbars.bmp
old mode 100644
new mode 100755
diff --git a/btn/zcolor.png b/btn/zcolor.png
old mode 100644
new mode 100755
diff --git a/btn/zcolorbar.bmp b/btn/zcolorbar.bmp
old mode 100644
new mode 100755
diff --git a/changes.txt b/changes.txt
old mode 100644
new mode 100755
diff --git a/clustering.pas b/clustering.pas
old mode 100644
new mode 100755
diff --git a/common/DiskSpaceKludge.pas b/common/DiskSpaceKludge.pas
old mode 100644
new mode 100755
diff --git a/common/GraphicsMathLibrary.pas b/common/GraphicsMathLibrary.pas
old mode 100644
new mode 100755
diff --git a/common/cpucount.pas b/common/cpucount.pas
old mode 100644
new mode 100755
diff --git a/common/define_types.pas b/common/define_types.pas
old mode 100644
new mode 100755
index badd340..a24a8e0
--- a/common/define_types.pas
+++ b/common/define_types.pas
@@ -16,9 +16,15 @@ interface
{$ENDIF}
SysUtils,classes,IniFiles,
- {$IFDEF GUI} forms,userdir, dialogs;{$ELSE} dialogsx;{$ENDIF}
+ {$IFDEF GUI} forms,userdir, dialogs{$ELSE}dialogsx{$ENDIF};
const
- kMRIcronVers = '7 July 2012';
+ kMRIcronVersDate = '28 August 2013';
+ {$ifdef CPU32}
+ kMRIcronVers = kMRIcronVersDate+' 32bit';
+ {$ELSE}
+ kMRIcronVers = kMRIcronVersDate+' 64bit';
+ {$ENDIF}
+
NaN : double = 1/0;
kMagicDouble : double = -111666222;
kTxtFilter = 'Text (*.txt)|*.txt;*.csv|Comma Separated (*.csv)|*.csv';
@@ -137,7 +143,7 @@ type
// pRGBTripleArray = ^TRGBTripleArray;
// TRGBTripleArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple;
FUNCTION specialsingle (var s:single): boolean; //check if 32-bit float is Not-A-Number, infinity, etc
-function FSize (lFName: String): longint;
+function FSize (lFName: String): Int64;
function FileExistsEX(Name: String): Boolean;
function ParseFileName (lFilewExt:String): string;
function ParseFileFinalDir (lFileName:String): string;
@@ -233,7 +239,7 @@ begin
if not lKey then
exit;
{$IFDEF GUI}
- case MessageDlg(kKey+' down during launch: do you want to reset the default preferences?', mtConfirmation,
+ case MessageDlg(kKey+' down during launch: do you want to reset the default preferences?', mtConfirmation,
[mbYes, mbNo], 0) of { produce the message dialog box }
idYes: result := true;
end; //case
@@ -798,42 +804,30 @@ begin
result :=outguy.Small1;
end;
-
-
+{$IFDEF GUI}
+procedure ShowMsg(s: string);
+begin
+ showmessage(s);
+end;
+{$ENDIF}
procedure fx (a: double); overload; //fx used to help debugging - reports number values
begin
- {$IFDEF GUI}
- showmessage(floattostr(a));
- {$ELSE}
- msg(floattostr(a));
- {$ENDIF}
+ ShowMsg(floattostr(a));
end;
procedure fx (a,b: double); overload; //fx used to help debugging - reports number values
begin
- {$IFDEF GUI}
- showmessage(floattostr(a)+'x'+floattostr(b));
- {$ELSE}
- msg(floattostr(a)+'x'+floattostr(b));
- {$ENDIF}
+ ShowMsg(floattostr(a)+'x'+floattostr(b));
end;
procedure fx (a,b,c: double); overload; //fx used to help debugging - reports number values
begin
- {$IFDEF GUI}
- showmessage(floattostr(a)+'x'+floattostr(b)+'x'+floattostr(c));
- {$ELSE}
- msg(floattostr(a)+'x'+floattostr(b)+'x'+floattostr(c));
- {$ENDIF}
+ ShowMsg(floattostr(a)+'x'+floattostr(b)+'x'+floattostr(c));
end;
procedure fx (a,b,c,d: double); overload; //fx used to help debugging - reports number values
begin
- {$IFDEF GUI}
- showmessage(floattostr(a)+'x'+floattostr(b)+'x'+floattostr(c)+'x'+floattostr(d));
- {$ELSE}
- msg(floattostr(a)+'x'+floattostr(b)+'x'+floattostr(c)+'x'+floattostr(d));
- {$ENDIF}
+ ShowMsg(floattostr(a)+'x'+floattostr(b)+'x'+floattostr(c)+'x'+floattostr(d));
end;
procedure CopyFileEXoverwrite (lInName,lOutName: string);
@@ -910,13 +904,14 @@ end; //proc SortSingle
{$IFDEF FPC}
{$IFDEF UNIX} //FPC and Unix
function DiskFreeEx (DriveStr: String): Int64;
- var
+ var
lOutDisk: Integer;
begin
- //lOutDisk := AddDisk(DriveStr);
- //result := DiskFree(lOutDisk);
- result := maxint;
+ lOutDisk := AddDisk(DriveStr);
+ result := DiskFree(lOutDisk);
+ if result < 0 then
+ result := 9223372036854775807;
end;
{$ELSE} //FPC and Windows
function DiskFreeEx (DriveStr: String): Int64;
@@ -1185,7 +1180,7 @@ begin
result := ChangeFileExt(lFilename,lExt);
end; *)
-function ChangeFileExtX(var lFilename: string; lExt: string): string; overload;
+function ChangeFileExtX(var lFilename: string; lExt: string): string;// overload;
//sees .nii.gz as single extension
var
lPath,lName,lOrigExt: string;
@@ -1290,7 +1285,7 @@ begin
CloseFile(F);
end;
-function FSize (lFName: String): longint;
+function FSize (lFName: String): Int64;
var SearchRec: TSearchRec;
begin
result := 0;
@@ -1336,4 +1331,4 @@ BEGIN
RESULT := false;
END;
-end.
+end.
\ No newline at end of file
diff --git a/common/delphiselectfolder.pas b/common/delphiselectfolder.pas
old mode 100644
new mode 100755
diff --git a/common/dialogsx.pas b/common/dialogsx.pas
old mode 100644
new mode 100755
index fc44e63..d7db548
--- a/common/dialogsx.pas
+++ b/common/dialogsx.pas
@@ -3,15 +3,15 @@ unit dialogsx;
{$H+}
interface
uses
-
-SysUtils,IniFiles;
+ //,IniFiles
+SysUtils;
type
TMsgDlgBtn = (mbYes, mbNo, mbOK, mbCancel, mbAbort, mbRetry, mbIgnore, mbAll, mbNoToAll, mbYesToAll, mbHelp);
TMsgDlgButtons = set of TMsgDlgBtn;
TMsgDlgType = (mtWarning, mtError, mtInformation, mtConfirmation, mtCustom);
-procedure Msg (lStr: string);
+//procedure Msg (lStr: string);
procedure ShowMsg (lStr: string);
procedure msgfx (a,b,c,d: double); overload; //fx used to help debugging - reports number values
function MsgDlg(const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; HelpCtx: Longint): Word;
@@ -25,11 +25,21 @@ const
mrAbort = 1;// idAbort
mrNo = 0;
implementation
-{$IFDEF GUI}uses readint,dialogs,gui; {$ENDIF}
+{$IFDEF GUI}uses readint,dialogs; {$ENDIF}
+
+procedure Msg (lStr: string);
+begin
+{$IFDEF GUI}
+ showmessage(lStr);
+{$ELSE}
+ writeln(lStr)
+{$ENDIF}
+end;
+
procedure vx (a,b,c,d: double); //vx used to help debugging - reports number values
begin
- msg(floattostr(a)+':'+floattostr(b)+':'+floattostr(c)+':'+floattostr(d));
+msg(floattostr(a)+':'+floattostr(b)+':'+floattostr(c)+':'+floattostr(d));
end;
@@ -81,15 +91,7 @@ begin
{$ENDIF}
end;
-procedure Msg (lStr: string);
-begin
-{$IFDEF GUI}
- MainForm.Memo1.Lines.Add(lStr);
- MainForm.refresh;
-{$ELSE}
- writeln(lStr)
-{$ENDIF}
-end;
+
function GetStr(lPrompt: string): string;
{$IFDEF GUI}
@@ -140,4 +142,4 @@ end;
end.
-
+
\ No newline at end of file
diff --git a/common/dicomhdr.pas b/common/dicomhdr.pas
old mode 100644
new mode 100755
diff --git a/common/distr.pas b/common/distr.pas
old mode 100644
new mode 100755
diff --git a/common/gui.inc b/common/gui.inc
old mode 100644
new mode 100755
diff --git a/common/gzio2.pas b/common/gzio2.pas
old mode 100644
new mode 100755
index f724f4f..9a31d96
--- a/common/gzio2.pas
+++ b/common/gzio2.pas
@@ -31,7 +31,7 @@ function Gunzip (var FFileSource,FFileDestination: string): integer;
procedure GZipBuffer(var FGzipFilename,FFileDestination: String;lxInBuffer: byteP;lInSize: Integer; lOverwritewarn: boolean);overload;
procedure GZipBuffer(var FFileDestination: String;lxInBuffer: byteP;lInSize: Integer; lOverwritewarn: boolean);overload;
-procedure UnGZip (var lInFname: string; var lBuf: ByteP{}; lOffset,lMaxSz: integer); //unzip
+procedure UnGZip (var lInFname: string; var lBuf: ByteP; lOffset,lMaxSz: int64); //unzip
procedure UnGZipCore (var infile : gzFile; var lBuf: ByteP; lReadBytes: integer; lWrite: boolean);
procedure UnGZipFile (var lFname,lOUtname: string); //unzip
function gzopen (path:string; mode:string) : gzFile;
@@ -68,7 +68,7 @@ const
implementation
{$include isgui.inc}
-{$IFDEF GUI}uses dialogs;{$ELSE} uses dialogsx;{$ENDIF}
+uses dialogsx;//{$IFDEF GUI}uses dialogs;{$ELSE} uses dialogsx;{$ENDIF}
const
Z_EOF = -1; { same value as in STDIO.H }
Z_BUFSIZE = 16384;
@@ -79,7 +79,7 @@ const
{ gzip flag byte }
- ASCII_FLAG = $01; { bit 0 set: file probably ascii text }
+ //ASCII_FLAG = $01; { bit 0 set: file probably ascii text }
HEAD_CRC = $02; { bit 1 set: header CRC present }
EXTRA_FIELD = $04; { bit 2 set: extra field present }
ORIG_NAME = $08; { bit 3 set: original file name present }
@@ -107,23 +107,14 @@ type gz_streamp = ^gz_stream;
function destroy (var s:gz_streamp) : integer; forward;
procedure check_header(s:gz_streamp); forward;
-procedure showmessagex(lStr: string);
-begin
- {$IFDEF GUI}
- showmessage(lStr);
- {$ELSE}
- msg(lStr);
- {$ENDIF}
-end;
-procedure UnGZip (var lInFname: string; var lBuf: ByteP; lOffset,lMaxSz: integer); //unzip
+procedure UnGZip (var lInFname: string; var lBuf: ByteP; lOffset,lMaxSz: int64); //unzip
const
BUFLEN = 16384;
var
- infile : gzFile;
- lFname : ansistring;
- lbufsz,len,lI : integer;
- written : integer;
+ infile : gzFile;
+ lFname : ansistring;
+ lI,len ,written, lbufsz : int64;
buf : packed array [0..BUFLEN-1] of byte; { Global uses BSS instead of stack }
begin
lFName := lInFName;
@@ -138,9 +129,15 @@ begin
written := 0;
if lOffset > 0 then begin
Len := lOffset div BUFLEN;
- if Len > 0 then
- for lI := 1 to Len do
- gzread (infile, @buf, BUFLEN {1388});
+ if Len > 0 then begin
+ lI := 1;
+ while (lI <= Len) do begin
+ gzread (infile, @buf, BUFLEN {1388});
+ inc(lI);
+ end;
+ //for lI := 1 to Len do
+ // gzread (infile, @buf, BUFLEN {1388});
+ end;
Len := lOffset mod BUFLEN;
gzread (infile, @buf, Len);
end;
@@ -274,12 +271,12 @@ begin
{$I+}
ioerr := IOResult;
if (ioerr <> 0) then begin
- Showmessagex ('GZipFile error: '+inttostr(ioerr));
+ ShowMsg ('GZipFile error: '+inttostr(ioerr));
halt(1);
end;
outfile := gzopen (lDestName, mode);
if (outfile = NIL) then begin
- Showmessagex('unable to create '+lDestName);
+ ShowMsg('unable to create '+lDestName);
exit;
end;
gz_compress(infile, outfile);
@@ -1799,7 +1796,7 @@ begin
lDestName := FFileDestination;
outfile := gzopen (lDestName, mode);
if (outfile = NIL) then begin
- Showmessagex('unable to create '+lDestName);
+ ShowMsg('unable to create '+lDestName);
exit;
end;
errorcode := 0;
@@ -1881,7 +1878,7 @@ var
s : gz_streamp;
begin
errorcode := 0;
- showmessagex('unGZip ' + extractfilename(FFileSource));
+ ShowMsg('unGZip ' + extractfilename(FFileSource));
infile := gzopen (FFileSource, 'r');
if (infile = NIL) then begin
//if FWindowOnError then
@@ -1922,4 +1919,4 @@ begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/common/gziod.pas b/common/gziod.pas
old mode 100644
new mode 100755
diff --git a/common/isgui.inc b/common/isgui.inc
old mode 100644
new mode 100755
diff --git a/common/nifti_hdr.pas b/common/nifti_hdr.pas
old mode 100644
new mode 100755
index b1bf3b7..ecf4ce8
--- a/common/nifti_hdr.pas
+++ b/common/nifti_hdr.pas
@@ -983,7 +983,8 @@ var
lAHdr: TAnalyzeHdrSection;
lHdr2: TNIfTIHdr2;
lCompress: boolean;
- lReportedSz, lSwappedReportedSz,lHdrSz2,lHdrSz1,lFileSz: Longint;
+ lFileSz : int64;
+ lReportedSz, lSwappedReportedSz,lHdrSz2,lHdrSz1: Longint;
lExt: string; //1494
begin
Result := false; //assume error
@@ -999,12 +1000,12 @@ begin
lHdrSz2 := sizeof(TniftiHdr2);
lFileSz := FSize (lFilename);
if lFileSz = 0 then begin
- ShowMessage('Unable to find NIFTI header named '+lFilename);
+ ShowMessage('Unable to find NIFTI header named '+lFilename+'. Possible solution: make sure VAL file and images are in the same folder.');
exit;
end;
if (lFileSz < lHdrSz1) and (not lCompress) then begin
- ShowMessage('Error in reading NIFTI header: NIfTI headers need to be at least '+inttostr(lHdrSz1)+ ' bytes: '+lFilename);
- exit;
+ ShowMessage('Error reading NIFTI header: NIfTI headers need to be at least '+inttostr(lHdrSz1)+ ' bytes: '+lFilename);
+ exit;
end;
FileMode := 0; { Set file access to read only }
if lCompress then begin//1388
@@ -1521,4 +1522,4 @@ begin
end; //with NIFTIhdr
end; //proc NIFTIhdr_SwapBytes
-end.
+end.
\ No newline at end of file
diff --git a/common/notgui.inc b/common/notgui.inc
old mode 100644
new mode 100755
diff --git a/common/userdir.pas b/common/userdir.pas
old mode 100644
new mode 100755
diff --git a/crop.pas b/crop.pas
old mode 100644
new mode 100755
index ac137b8..40ba4bf
--- a/crop.pas
+++ b/crop.pas
@@ -2,12 +2,13 @@ unit crop;
interface
function CropNIfTI(lL,lR,lA,lP,lD,lV: integer):boolean;
-
+function GrowNeck (lFilename: string; lVox: integer): boolean;
implementation
-uses nifti_hdr, nifti_img,define_types, GraphicsMathLibrary,dialogs, nifti_img_view;
+uses nifti_hdr_view, nifti_hdr, nifti_img,define_types, GraphicsMathLibrary,dialogs, nifti_img_view;
+ // nifti_img_view, nifti_img,nifti_hdr, nifti_hdr_view,{ShellAPI,}ShlObj,periutils, reslice_fsl;
procedure NIFTIhdr_SlicesToCoord (var lHdr: TNIFTIhdr; lXslice,lYslice,lZslice: integer; var lXmm,lYmm,lZmm: single);
//ignores origin offset
begin
@@ -25,14 +26,10 @@ var
lOutname,lExt: string;
lXmm,lYmm,lZmm: single;
lMat: TMatrix;
- lOutPos,lSlice,lVol,lVolBytes,lImgSamples,lInc,
+ lOutPos,lSlice,lVol,lOutVolBytes,lInVolBytes,lImgSamples,lInc,
lX,lY,lZ,lBPP, lB,
lInZOffset,lInYOffset,lInSliceSz,lInXSz,lInPos,lImgOffset: integer;
lBuffer: bytep;
- (*lSrcBuffer,lBuffer, lBuffUnaligned: bytep;
- l32Buf,lImgBuffer: singlep;
- l16Buf : SmallIntP;
- l32BufI : LongIntP;*)
lWordX: Word;
lSPM2: boolean;
lOutF,lInF: File;
@@ -51,8 +48,8 @@ begin
lInHdr := gMRIcroOverlay[kBGOverlayNum].NIFTIHdr;
//check orthogonal alignment....
if lInHdr.dim[4] > 1 then begin
- Showmessage('Only able to Crop 3D images (reorienting 4D could disrupt slice timing and diffusion directions.');
- exit;
+ Showmessage('Only Cropping 1st 3D image (reorienting 4D could disrupt slice timing and diffusion directions.');
+ //exit;
end;
//Next create reordered or trimmed image in the correct format
case lInHdr.datatype of
@@ -62,62 +59,9 @@ begin
exit;
end;
end;
-
- //Msg('Cropping NIfTI/Analyze image '+lFileName);
lOutHdr := lInHdr;
lImgSamples := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3];
lBPP := (lInHdr.bitpix div 8); //bytes per pixel
- (*lVolBytes := lImgSamples*lBPP;
-
- //Msg('Automatically Cropping image');
- lBuffer := (@lSrcBuffer^[lImgOffset+1]);
- GetMem(lBuffUnaligned ,(sizeof(single)*lImgSamples) + 16);
- {$IFDEF FPC}
- lImgBuffer := align(lBuffUnaligned,16);
- {$ELSE}
- lImgBuffer := SingleP($fffffff0 and (integer(lBuffUnaligned)+15));
- {$ENDIF}
- case lInHdr.datatype of
- kDT_UNSIGNED_CHAR : begin //8 bit
- for lInc := 1 to lImgSamples do
- lImgBuffer^[lInc] := lBuffer^[lInc];
- end;
- kDT_SIGNED_SHORT{,kDT_UINT16}: begin //16-bit int
- l16Buf := SmallIntP(lBuffer );
- if lByteSwap then begin
- for lInc := 1 to lImgSamples do
- lImgBuffer^[lInc] := Swap(l16Buf^[lInc]);
- end else begin
- for lInc := 1 to lImgSamples do
- lImgBuffer^[lInc] := l16Buf^[lInc];
- end;
- end;//16bit
- kDT_SIGNED_INT: begin
- l32Buf := SingleP(lBuffer );
- if lByteSwap then //unswap and convert integer to float
- for lInc := 1 to lImgSamples do
- lImgBuffer^[lInc] := (Swap4r4i(l32Buf^[lInc]))
- else //convert integer to float
- for lInc := 1 to lImgSamples do
- lImgBuffer^[lInc] := Conv4r4i(l32Buf^[lInc]);
- end; //32-bit int
- kDT_FLOAT: begin
- l32Buf := SingleP(lBuffer);
- for lInc := 1 to lImgSamples do
- lImgBuffer[lInc] := l32Buf[lInc];
- if lByteSwap then
- for lInc := 1 to lImgSamples do
- pswap4r(lImgBuffer^[lInc]); //faster as procedure than function see www.optimalcode.com
- for lInc := 1 to lImgSamples do
- if specialsingle(lImgBuffer^[lInc]) then lImgBuffer^[lInc] := 0.0;
- //invert= for lInc := 1 to lImgSamples do l32Buf[lInc] := -l32Buf[lInc];
- end; //32-bit float
- else begin
- Showmessage('Serious error: format not supported by Crop3D.');
- exit;
- end;
- end; //case *)
-
lDorsalCrop := lD;
lVentralCrop := lV;
lLCrop := lL;
@@ -128,20 +72,21 @@ begin
if (lDorsalCrop = 0) and (lVentralCrop = 0)
and (lLCrop = 0) and (lRCrop = 0)
and (lACrop = 0) and (lPCrop = 0) then begin
- Showmessage('Crop 3D quitting: no need to delete slices.');
+ Showmessage('Grow 3D quitting: no need to add or delete slices.');
//Freemem(lSrcBuffer);
end;
if (lDorsalCrop < 0) or (lVentralCrop < 0)
or (lLCrop < 0) or (lRCrop < 0)
or (lACrop < 0) or (lPCrop < 0) then begin
- Showmessage('Crop 3D quitting: negative values should be impossible.');
+ Showmessage('Grow 3D quitting: negative values should be impossible.');
//Freemem(lSrcBuffer);
end;
//next compute size of cropped volume
+ lInVolBytes := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]*lBPP;
lOutHdr.Dim[1] := lInHdr.Dim[1]-lLCrop-lRCrop;
lOutHdr.Dim[2] := lInHdr.Dim[2]-lACrop-lPCrop;
lOutHdr.Dim[3] := lInHdr.Dim[3]-lDorsalCrop-lVentralCrop;
- lVolBytes := lOutHdr.dim[1]*lOutHdr.dim[2]*lOutHdr.dim[3]*lBPP;
+ lOutVolBytes := lOutHdr.dim[1]*lOutHdr.dim[2]*lOutHdr.dim[3]*lBPP;
//next: readjust origin to take into account removed slices
//REQUIRES images to be aligned to nearest orthogonal to canonical space [1 0 0; 0 1 0; 0 0 1]
NIFTIhdr_SlicesToCoord (lInHdr,lLCrop,lPCrop,lVentralCrop, lXmm,lYmm,lZmm);
@@ -157,31 +102,159 @@ begin
lOutHdr.quatern_b,lOutHdr.quatern_c,lOutHdr.quatern_d,
lOutHdr.qoffset_x,lOutHdr.qoffset_y,lOutHdr.qoffset_z,
lXmm, lYmm, lZmm, lOutHdr.pixdim[0]{QFac});
- //note we write and read to the same buffer - we will always SHRINK output
+ //note we write to a different buffer, as we may need to grow output
//no need to byteswap data - we will save in the save format as stored
lOutPos := 0;
lInSliceSz := lInHdr.dim[1]*lInHdr.dim[2]*lBPP;
lInXSz := lInHdr.dim[1]*lBPP;
- GetMem(lBuffer,lVolBytes);
+ GetMem(lBuffer,lOutVolBytes);
//Move(gMRIcroOverlay[kBGOverlayNum].ImgBuffer^,lTempBuf^,gBGImg.VOIUndoVolItems);
for lZ := 1 to lOutHdr.dim[3] do begin
lInZOffset := (lVentralCrop+lZ-1) * lInSliceSz;
+ if lInZOffset < 0 then
+ lInZOffset := 0;
for lY := 1 to lOutHdr.dim[2] do begin
lInYOffset := ((lPCrop+lY-1) * lInXSz) + lInZOffset + (lLCrop*lBPP);
for lX := 1 to lOutHdr.dim[1] do begin
for lB := 1 to lBPP do begin
inc(lOutPos);
lInPos := ((lX-1) * lBPP) + lInYOffset + lB;
- lBuffer^[lOutPos] := gMRIcroOverlay[kBGOverlayNum].ImgBuffer^[lInPos];
+ if (lInPos < 1) or (lInPos > lInVolBytes) then
+ lBuffer^[lOutPos] := 128
+ else
+ lBuffer^[lOutPos] := gMRIcroOverlay[kBGOverlayNum].ImgBuffer^[lInPos];
end;
end;
end; //for Y
end; //for Z
lOutname := ChangeFilePrefix (gMRIcroOverlay[kBGOverlayNum].HdrFileName,'c');
//result := SaveNIfTICore (lOutName, lSrcBuffer, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
- SaveAsVOIorNIFTI (lBuffer,lOutHdr.dim[1]*lOutHdr.dim[2]*lOutHdr.dim[3], lBPP,1, false, lOutHdr, lOutname);
+ result := gBGImg.UseReorientHdr;
+ gBGImg.UseReorientHdr := false;
+ SaveAsVOIorNIFTI (lBuffer,lOutHdr.dim[1]*lOutHdr.dim[2]*lOutHdr.dim[3], lBPP,1, false, lOutHdr, lOutname);
+ gBGImg.UseReorientHdr := result;
+ result := true;
+ Freemem(lBuffer);
+end;
+
+
+function GrowNeck (lFilename: string; lVox: integer): boolean;
+//to do : data swapping (errors on detection and writing zero in reverse order)
+var
+ lInHdr,lOutHdr: TNIFTIhdr;
+ lOutname,lExt: string;
+ lXmm,lYmm,lZmm: single;
+ lMat: TMatrix;
+ lOutPos,lSlice,lVol,lOutVolBytes,lInVolBytes,lImgSamples,lInc,
+ lX,lY,lZ,lBPP, lB,
+ lVolOffset,lInZOffset,lInYOffset,lInSliceSz,lInXSz,lInPos,lImgOffset: integer;
+ lBuffer: bytep;
+ lWordX: Word;
+ lSPM2: boolean;
+ lOutF,lInF: File;
+ lACrop,lPCrop,lDorsalCrop,lVentralCrop,lLCrop,lRCrop: integer;
+ lByteSwap: boolean;
+begin
+ gBGImg.Prompt4DVolume := false;
+ if not HdrForm.OpenAndDisplayHdr(lFilename,gMRIcroOverlay[kBGOverlayNum]) then exit;
+ gBGImg.Prompt4DVolume := true;
+ if not OpenImg(gBGImg,gMRIcroOverlay[kBGOverlayNum],false,false,false,false,true {4D!}) then exit;
+ lInHdr := gMRIcroOverlay[kBGOverlayNum].NIFTIHdr;
+ result := false;
+ if (gMRIcroOverlay[kBGOverlayNum].ImgBufferItems < 1) or (lInHdr.dim[1] < 2) or (lInHdr.dim[2] < 2) then begin
+ showmessage('Please load a 3D background image for neck removal.');
+ exit;
+ end;
+ if (gBGImg.Resliced) then begin
+ showmessage('You must switch reslicing OFF (Help/Preferences) for image cropping.');
+ exit;
+ end;
+
+ //check orthogonal alignment....
+ lOutHdr := lInHdr;
+ lImgSamples := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3];
+ lBPP := (lInHdr.bitpix div 8); //bytes per pixel
+ lDorsalCrop := 0;
+ lVentralCrop := lVox;
+ lLCrop := 0;
+ lRCrop := 0;
+ lACrop := 0;
+ lPCrop := 0;
+ //FreeMem(lBuffUnaligned);
+ if (lDorsalCrop = 0) and (lVentralCrop = 0)
+ and (lLCrop = 0) and (lRCrop = 0)
+ and (lACrop = 0) and (lPCrop = 0) then begin
+ Showmessage('Grow 3D quitting: no need to add or delete slices.');
+ //Freemem(lSrcBuffer);
+ end;
+ if (lDorsalCrop < 0) or (lVentralCrop < 0)
+ or (lLCrop < 0) or (lRCrop < 0)
+ or (lACrop < 0) or (lPCrop < 0) then begin
+ Showmessage('Grow 3D quitting: negative values should be impossible.');
+ //Freemem(lSrcBuffer);
+ end;
+ //next compute size of cropped volume
+
+ lOutHdr.Dim[1] := lInHdr.Dim[1]-lLCrop-lRCrop;
+ lOutHdr.Dim[2] := lInHdr.Dim[2]-lACrop-lPCrop;
+ lOutHdr.Dim[3] := lInHdr.Dim[3]-lDorsalCrop-lVentralCrop;
+
+ //next: readjust origin to take into account removed slices
+ //REQUIRES images to be aligned to nearest orthogonal to canonical space [1 0 0; 0 1 0; 0 0 1]
+ NIFTIhdr_SlicesToCoord (lInHdr,lLCrop,lPCrop,lVentralCrop, lXmm,lYmm,lZmm);
+ lOutHdr.srow_x[3] := lInHdr.srow_x[3] + lXmm;
+ lOutHdr.srow_y[3] := lInHdr.srow_y[3] + lYmm;
+ lOutHdr.srow_z[3] := lInHdr.srow_z[3] + lZmm;
+ lMat := Matrix3D (
+ lOutHdr.srow_x[0], lOutHdr.srow_x[1], lOutHdr.srow_x[2], lOutHdr.srow_x[3],
+ lOutHdr.srow_y[0], lOutHdr.srow_y[1], lOutHdr.srow_y[2], lOutHdr.srow_y[3],
+ lOutHdr.srow_z[0], lOutHdr.srow_z[1], lOutHdr.srow_z[2], lOutHdr.srow_z[3],
+ 0, 0, 0, 1);
+ nifti_mat44_to_quatern( lMat,
+ lOutHdr.quatern_b,lOutHdr.quatern_c,lOutHdr.quatern_d,
+ lOutHdr.qoffset_x,lOutHdr.qoffset_y,lOutHdr.qoffset_z,
+ lXmm, lYmm, lZmm, lOutHdr.pixdim[0]{QFac});
+ //note we write to a different buffer, as we may need to grow output
+ //no need to byteswap data - we will save in the save format as stored
+ lOutPos := 0;
+ lInSliceSz := lInHdr.dim[1]*lInHdr.dim[2]*lBPP;
+ lInXSz := lInHdr.dim[1]*lBPP;
+ lInVolBytes := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]*lInHdr.dim[4]*lBPP;
+ lOutVolBytes := lOutHdr.dim[1]*lOutHdr.dim[2]*lOutHdr.dim[3]*lOutHdr.dim[4]*lBPP;
+ GetMem(lBuffer,lOutVolBytes);
+ //Move(gMRIcroOverlay[kBGOverlayNum].ImgBuffer^,lTempBuf^,gBGImg.VOIUndoVolItems);
+
+ for lVol := 1 to lOutHdr.dim[4] do begin
+ lVolOffset := (lVol-1) * lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]* lBPP;
+ for lZ := 1 to lOutHdr.dim[3] do begin
+
+ if lZ > -lVentralCrop then
+ lInZOffset := ((lVentralCrop+lZ-1) * lInSliceSz)
+ else
+ lInZOffset := 0;
+ for lY := 1 to lOutHdr.dim[2] do begin
+ lInYOffset := ((lPCrop+lY-1) * lInXSz) + lInZOffset + (lLCrop*lBPP);
+ for lX := 1 to lOutHdr.dim[1] do begin
+ for lB := 1 to lBPP do begin
+ inc(lOutPos);
+ lInPos := ((lX-1) * lBPP) + lInYOffset + lB;
+ if (lInPos < 1) or (lInPos > lInVolBytes) then
+ lBuffer^[lOutPos] := 0
+ else
+ lBuffer^[lOutPos] := gMRIcroOverlay[kBGOverlayNum].ImgBuffer^[lInPos+lVolOffset];
+ end;
+ end;
+ end; //for Y
+ end; //for Z
+ end; //lvol
+ lOutname := ChangeFilePrefix (gMRIcroOverlay[kBGOverlayNum].HdrFileName,'c');
+ //result := SaveNIfTICore (lOutName, lSrcBuffer, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ result := gBGImg.UseReorientHdr;
+ gBGImg.UseReorientHdr := false;
+ SaveAsVOIorNIFTI (lBuffer,lOutHdr.dim[1]*lOutHdr.dim[2]*lOutHdr.dim[3], lBPP,lOutHdr.dim[4], false, lOutHdr, lOutname);
+ gBGImg.UseReorientHdr := result;
result := true;
Freemem(lBuffer);
end;
diff --git a/crop.pas b/crop_old.pas
old mode 100644
new mode 100755
similarity index 100%
copy from crop.pas
copy to crop_old.pas
diff --git a/cropedges.lfm b/cropedges.lfm
old mode 100644
new mode 100755
index f5a7e15..0d74883
--- a/cropedges.lfm
+++ b/cropedges.lfm
@@ -1,29 +1,29 @@
object CropEdgeForm: TCropEdgeForm
- Left = 321
- Height = 139
- Top = 276
+ Left = 562
+ Height = 142
+ Top = 209
Width = 398
ActiveControl = DEdit
BorderIcons = [biSystemMenu]
BorderStyle = bsDialog
Caption = 'Crop Edges'
- ClientHeight = 139
+ ClientHeight = 142
ClientWidth = 398
Constraints.MaxHeight = 321
Constraints.MaxWidth = 398
- Constraints.MinHeight = 321
+ Constraints.MinHeight = 12
Constraints.MinWidth = 398
+ OnCreate = FormCreate
OnHide = FormHide
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '0.9.29'
+ LCLVersion = '1.0.2.0'
object CancelBtn: TSpeedButton
Left = 320
Height = 25
Top = 104
Width = 65
Caption = 'Cancel'
- Color = clBtnFace
NumGlyphs = 0
OnClick = CancelBtnClick
end
@@ -33,7 +33,6 @@ object CropEdgeForm: TCropEdgeForm
Top = 104
Width = 65
Caption = 'Apply'
- Color = clBtnFace
NumGlyphs = 0
OnClick = ApplyBtnClick
end
@@ -43,7 +42,6 @@ object CropEdgeForm: TCropEdgeForm
Top = 104
Width = 105
Caption = 'Save Cropped'
- Color = clBtnFace
NumGlyphs = 0
OnClick = CropFileSzBtnClick
end
diff --git a/cropedges.lrs b/cropedges.lrs
old mode 100644
new mode 100755
index e889718..3e8d5ff
--- a/cropedges.lrs
+++ b/cropedges.lrs
@@ -1,33 +1,33 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TCropEdgeForm','FORMDATA',[
- 'TPF0'#13'TCropEdgeForm'#12'CropEdgeForm'#4'Left'#3'A'#1#6'Height'#3#139#0#3
- +'Top'#3#20#1#5'Width'#3#142#1#13'ActiveControl'#7#5'DEdit'#11'BorderIcons'#11
- +#12'biSystemMenu'#0#11'BorderStyle'#7#8'bsDialog'#7'Caption'#6#10'Crop Edges'
- +#12'ClientHeight'#3#139#0#11'ClientWidth'#3#142#1#21'Constraints.MaxHeight'#3
- +'A'#1#20'Constraints.MaxWidth'#3#142#1#21'Constraints.MinHeight'#3'A'#1#20'C'
- +'onstraints.MinWidth'#3#142#1#6'OnHide'#7#8'FormHide'#6'OnShow'#7#8'FormShow'
- +#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#6'0.9.29'#0#12'TSpeedButt'
- +'on'#9'CancelBtn'#4'Left'#3'@'#1#6'Height'#2#25#3'Top'#2'h'#5'Width'#2'A'#7
- +'Caption'#6#6'Cancel'#5'Color'#7#9'clBtnFace'#9'NumGlyphs'#2#0#7'OnClick'#7
- +#14'CancelBtnClick'#0#0#12'TSpeedButton'#8'ApplyBtn'#4'Left'#3#0#1#6'Height'
- +#2#25#3'Top'#2'h'#5'Width'#2'A'#7'Caption'#6#5'Apply'#5'Color'#7#9'clBtnFace'
- +#9'NumGlyphs'#2#0#7'OnClick'#7#13'ApplyBtnClick'#0#0#12'TSpeedButton'#13'Cro'
- +'pFileSzBtn'#4'Left'#3#136#0#6'Height'#2#25#3'Top'#2'h'#5'Width'#2'i'#7'Capt'
- +'ion'#6#12'Save Cropped'#5'Color'#7#9'clBtnFace'#9'NumGlyphs'#2#0#7'OnClick'
- +#7#18'CropFileSzBtnClick'#0#0#9'TSpinEdit'#5'DEdit'#4'Left'#2'9'#6'Height'#2
- +#21#3'Top'#2#8#5'Width'#2'H'#8'MaxValue'#3#255#0#8'OnChange'#7#14'CropEditCh'
- +'ange'#8'TabOrder'#2#0#5'Value'#2#8#0#0#9'TSpinEdit'#5'PEdit'#4'Left'#2#8#6
- +'Height'#2#21#3'Top'#2')'#5'Width'#2'H'#8'MaxValue'#3#255#0#8'OnChange'#7#14
- +'CropEditChange'#8'TabOrder'#2#1#5'Value'#2#8#0#0#9'TSpinEdit'#5'AEdit'#4'Le'
- +'ft'#2'h'#6'Height'#2#21#3'Top'#2')'#5'Width'#2'H'#8'MaxValue'#3#255#0#8'OnC'
- +'hange'#7#14'CropEditChange'#8'TabOrder'#2#2#5'Value'#2#8#0#0#9'TSpinEdit'#5
- +'VEdit'#4'Left'#2'9'#6'Height'#2#21#3'Top'#2'I'#5'Width'#2'H'#8'MaxValue'#3
- +#255#0#8'OnChange'#7#14'CropEditChange'#8'TabOrder'#2#3#5'Value'#2#8#0#0#9'T'
- +'SpinEdit'#5'REdit'#4'Left'#3'7'#1#6'Height'#2#21#3'Top'#2')'#5'Width'#2'H'#8
- +'MaxValue'#3#255#0#8'OnChange'#7#14'CropEditChange'#8'TabOrder'#2#4#5'Value'
- +#2#8#0#0#9'TSpinEdit'#5'LEdit'#4'Left'#3#224#0#6'Height'#2#21#3'Top'#2')'#5
- +'Width'#2'H'#8'MaxValue'#3#255#0#8'OnChange'#7#14'CropEditChange'#8'TabOrder'
- +#2#5#5'Value'#2#8#0#0#6'TTimer'#6'Timer1'#7'Enabled'#8#8'Interval'#3#150#0#7
- +'OnTimer'#7#11'Timer1Timer'#4'left'#3'H'#1#3'top'#2'H'#0#0#0
+ 'TPF0'#13'TCropEdgeForm'#12'CropEdgeForm'#4'Left'#3'2'#2#6'Height'#3#142#0#3
+ +'Top'#3#209#0#5'Width'#3#142#1#13'ActiveControl'#7#5'DEdit'#11'BorderIcons'
+ +#11#12'biSystemMenu'#0#11'BorderStyle'#7#8'bsDialog'#7'Caption'#6#10'Crop Ed'
+ +'ges'#12'ClientHeight'#3#142#0#11'ClientWidth'#3#142#1#21'Constraints.MaxHei'
+ +'ght'#3'A'#1#20'Constraints.MaxWidth'#3#142#1#21'Constraints.MinHeight'#2#12
+ +#20'Constraints.MinWidth'#3#142#1#8'OnCreate'#7#10'FormCreate'#6'OnHide'#7#8
+ +'FormHide'#6'OnShow'#7#8'FormShow'#8'Position'#7#14'poScreenCenter'#10'LCLVe'
+ +'rsion'#6#7'1.0.2.0'#0#12'TSpeedButton'#9'CancelBtn'#4'Left'#3'@'#1#6'Height'
+ +#2#25#3'Top'#2'h'#5'Width'#2'A'#7'Caption'#6#6'Cancel'#9'NumGlyphs'#2#0#7'On'
+ +'Click'#7#14'CancelBtnClick'#0#0#12'TSpeedButton'#8'ApplyBtn'#4'Left'#3#0#1#6
+ +'Height'#2#25#3'Top'#2'h'#5'Width'#2'A'#7'Caption'#6#5'Apply'#9'NumGlyphs'#2
+ +#0#7'OnClick'#7#13'ApplyBtnClick'#0#0#12'TSpeedButton'#13'CropFileSzBtn'#4'L'
+ +'eft'#3#136#0#6'Height'#2#25#3'Top'#2'h'#5'Width'#2'i'#7'Caption'#6#12'Save '
+ +'Cropped'#9'NumGlyphs'#2#0#7'OnClick'#7#18'CropFileSzBtnClick'#0#0#9'TSpinEd'
+ +'it'#5'DEdit'#4'Left'#2'9'#6'Height'#2#21#3'Top'#2#8#5'Width'#2'H'#8'MaxValu'
+ +'e'#3#255#0#8'OnChange'#7#14'CropEditChange'#8'TabOrder'#2#0#5'Value'#2#8#0#0
+ +#9'TSpinEdit'#5'PEdit'#4'Left'#2#8#6'Height'#2#21#3'Top'#2')'#5'Width'#2'H'#8
+ +'MaxValue'#3#255#0#8'OnChange'#7#14'CropEditChange'#8'TabOrder'#2#1#5'Value'
+ +#2#8#0#0#9'TSpinEdit'#5'AEdit'#4'Left'#2'h'#6'Height'#2#21#3'Top'#2')'#5'Wid'
+ +'th'#2'H'#8'MaxValue'#3#255#0#8'OnChange'#7#14'CropEditChange'#8'TabOrder'#2
+ +#2#5'Value'#2#8#0#0#9'TSpinEdit'#5'VEdit'#4'Left'#2'9'#6'Height'#2#21#3'Top'
+ +#2'I'#5'Width'#2'H'#8'MaxValue'#3#255#0#8'OnChange'#7#14'CropEditChange'#8'T'
+ +'abOrder'#2#3#5'Value'#2#8#0#0#9'TSpinEdit'#5'REdit'#4'Left'#3'7'#1#6'Height'
+ +#2#21#3'Top'#2')'#5'Width'#2'H'#8'MaxValue'#3#255#0#8'OnChange'#7#14'CropEdi'
+ +'tChange'#8'TabOrder'#2#4#5'Value'#2#8#0#0#9'TSpinEdit'#5'LEdit'#4'Left'#3
+ +#224#0#6'Height'#2#21#3'Top'#2')'#5'Width'#2'H'#8'MaxValue'#3#255#0#8'OnChan'
+ +'ge'#7#14'CropEditChange'#8'TabOrder'#2#5#5'Value'#2#8#0#0#6'TTimer'#6'Timer'
+ +'1'#7'Enabled'#8#8'Interval'#3#150#0#7'OnTimer'#7#11'Timer1Timer'#4'left'#3
+ +'H'#1#3'top'#2'H'#0#0#0
]);
diff --git a/cropedges.pas b/cropedges.pas
old mode 100644
new mode 100755
index 1c25960..da39e26
--- a/cropedges.pas
+++ b/cropedges.pas
@@ -29,6 +29,7 @@ type
procedure CancelBtnClick(Sender: TObject);
procedure CropEditChange(Sender: TObject);
procedure CropFileSzBtnClick(Sender: TObject);
+ procedure FormCreate(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
@@ -77,6 +78,11 @@ begin
CropNIfTI(lL,lR,lA,lP,lD,lV);
end;
+procedure TCropEdgeForm.FormCreate(Sender: TObject);
+begin
+
+end;
+
procedure TCropEdgeForm.FormHide(Sender: TObject);
begin
UndoVolVOI;
diff --git a/cutout.lfm b/cutout.lfm
old mode 100644
new mode 100755
diff --git a/cutout.lrs b/cutout.lrs
old mode 100644
new mode 100755
diff --git a/cutout.pas b/cutout.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/LibTar.pas b/dcm2nii/LibTar.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/PARtoNRRD_Philips_RelX.zip b/dcm2nii/PARtoNRRD_Philips_RelX.zip
old mode 100644
new mode 100755
diff --git a/dcm2nii/SelectFolder.pas b/dcm2nii/SelectFolder.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/convert.pas b/dcm2nii/convert.pas
old mode 100644
new mode 100755
index 65c68ec..b0fe4ad
--- a/dcm2nii/convert.pas
+++ b/dcm2nii/convert.pas
@@ -11,12 +11,12 @@ gzio2,
{$ENDIF}
filename,define_types,classes,SysUtils,dicom,dicomtypes,
-niftiutil,GraphicsMathLibrary, userdir,csaread,
+niftiutil,GraphicsMathLibrary, userdir,csaread,dialogs_msg,
nii_4dto3d,nii_orient,nii_crop,prefs,lsjpeg;
function Dicom2NII(var lDICOMra: TDICOMrap; lFirstDICOM, lLastDICOM: integer; var lOutDirOrig: string; var lPrefs: TPrefs; lVols: integer): boolean;
implementation
uses
-sortdicom,dialogsx;
+sortdicom,dialogsx, philips_bvec;
function getDeterminant(r: TMatrix): double;
var
@@ -545,7 +545,7 @@ begin
if (lSlicesPerOrder = 0) then
exit;
nOrders := CompressMultiOrder(lDICOMdata);
- Msg('Swizzling with multiple ComplexImageComponents: '+inttostr(lSlicesPerOrder)+' slices per order, total '+inttostr(lDicomData.XYZdim[3])+' slices');
+ dcmMsg('Swizzling with multiple ComplexImageComponents: '+inttostr(lSlicesPerOrder)+' slices per order, total '+inttostr(lDicomData.XYZdim[3])+' slices');
if not lDICOMdata.file4D then
exit;
lTMax := lDicomData.XYZdim[3] div lDICOMdata.SlicesPer3DVol div nOrders;
@@ -583,14 +583,13 @@ var
lSlice,l4DBytes,lSliceBytes,lZo,lTo,lZmax,lTmax:integer;
lTempBuffer: ByteP;
begin
-
if lDicomData.XYZdim[4] < 2 then
exit;
if MultiOrder(lDICOMdata) <> 0 then begin
SwapTimeMultiOrder (lDICOMdata,lBuffer);
exit;
end;
- Msg('Swizzling: XYTZ -> XYZT');
+ dcmMsg('Swizzling: XYTZ -> XYZT');
if not lDICOMdata.file4D then
exit;
lTMax := lDicomData.XYZdim[3] div lDICOMdata.SlicesPer3DVol;
@@ -709,7 +708,7 @@ begin
lnMos := lSlices;// lDICOMdata.SiemensMosaicX*lDICOMdata.SiemensMosaicY;
if (lmosX < 2) and (lmosY < 2) then exit;
if ((lmosX*lmosY) < lSlices) then begin
- msg('This '+inttostr(lmosx)+'*'+inttostr(lmosy)+' mosaic can not hold '+inttostr(lSlices)+' slices.');
+ dcmMsg('This '+inttostr(lmosx)+'*'+inttostr(lmosy)+' mosaic can not hold '+inttostr(lSlices)+' slices.');
exit;
end;
lMosW := lDICOMdata.XYZdim[1] div lmosX;
@@ -798,179 +797,7 @@ begin
result := result + lFirstDICOM;
end;
-//Next routines for PhilipsBVec
- FUNCTION Vector2D (CONST xValue, yValue, zValue: DOUBLE): TVector;
- BEGIN
- WITH RESULT DO
- BEGIN
- x := xValue;
- y := yValue;
- z := zValue;
- size := size2D
- END
- END; //Vector2D
-
- // Assume vector contains 'extra' homogeneous coordinate -- ignore it.
- procedure NormalizeVector2D(var u: TVector);
- var
- lSum: double;
- BEGIN
- lSum := sqrt((u.x*u.x)+(u.y*u.y)+(u.z*u.z));
- if lSum <> 0 then
- u := Vector2D( u.x/lSum,
- u.y/lSum,
- u.z/lSum)
- END; //NormalizeVector2D
-
-FUNCTION revMat (CONST Input:TMatrix): TMatrix;//Transpose Matrix
-var
- i,j: integer;
-begin
- result.size := Input.size;
- for i := 1 to Input.size do
- for j := 1 to Input.size do
- result.matrix[i,j] := input.matrix[j,i];
-end;
-
-
- FUNCTION VecMatMult (CONST u: TVector; CONST a: TMatrix): TVector;
- VAR
- i,k : TIndex;
- temp: DOUBLE;
- BEGIN
- RESULT.size := a.size;
- IF a.size = u.size
- THEN BEGIN
- FOR i := 1 TO a.size DO
- BEGIN
- temp := 0.0;
- FOR k := 1 TO a.size DO
- BEGIN
- temp := temp + u.vector[k]*a.matrix[i,k];
- END;
- RESULT.vector[i] := Defuzz(temp)
- END;
- END
- ELSE raise EMatrixError.Create('VecMatMult error')
- END;//VecMatMult
-
-(*procedure mx(lstr: string;lm: tmatrix);
-begin
-msg(lStr);
-fx(lm.matrix[1,1],lm.matrix[1,2],lm.matrix[1,3]);
-fx(lm.matrix[2,1],lm.matrix[2,2],lm.matrix[2,3]);
-fx(lm.matrix[3,1],lm.matrix[3,2],lm.matrix[3,3]);
-end;*)
-
-procedure PhilipsCorrectBvecs(var lDICOMdata:dicomdata; var lDTIra: TDTIRA; nVec: integer);
-//Test lIn.x := 0.499997615814209; lIn.y := 0.499997615814209; lIn.z := 0.707110166549683;
-//Philips DICOM data stored in patient (LPH) space, regardless of settings in Philips user interface
-//algorithm inspired by CATNAP http://godzilla.kennedykrieger.org/~jfarrell/software_web.htm
-//http://iacl.ece.jhu.edu/~bennett/catnap/catnap.shtml
-//0018,5100. patient orientation - 'HFS'
-//2001,100B Philips slice orientation (TRANSVERSAL, AXIAL, SAGITTAL)
-//2005,1071. Philips AP angulation : -8.74086
-//2005,1072. Philips RL angulation : -3.53147
-//2005,1073. Philips FH angulation -0.387372
-(* 3/2008: updated to correct for a bug in the Johns Hopkins code:
-% July 20, 2007 | I corrected a small bug with the rotation matrices for
-% slice angulation. I had multiplied 3 matrices in the incorrect order.
-
-% A colleague (Harsh Agarwal) pointed this out while aligning different
-% MRI contrasts using the angulation parameters and the transformation
-% matrices given in the Philips document.
-%I originally had Tang = Tfh*Tap*Trl
-% which is now Tang = Trl*Tap*Tfh;
-%I originally had rev_Tang = rev_Trl*rev_Tap*rev_Tfh;
-%which is now rev_Tang = rev_Tfh*rev_Tap*rev_Trl;
-% I double checked the Philips code and this seems to be correct now.
-% I also double checked the impact on fiber tracking. The fiber tracking
-% looks good in both instances (even though the gradient tables are
-% slightly different). If 2 angulation values are zero (i.e. [AP,FH,RL]
-=
-% [0,0,20], then the old and new equations give the same result. Only
-if
-% two or more elements are non zero is the result different. I did some
-% testing with very large angulations of 20 degrees [20,20,0], [20,0,20]
-
-% and [0,20,20]and found that the fiber tracking results were almost
-% indistinguishable. THIS FIX ONLY affects yes overplus and
-% user-defined gradient tables. No overplus tables are not subject to
-% slice angulation changes
-*)
-var
- lIn,lOut: TVector;
- ltpp,lrev_tpp,ltpom,lrev_tpom,ltpo,lrev_tpo,ltrl,ltap,ltfh,
- lmtemp1,lmtemp2 ,ltang,lrev_tang,
- lrev_trl, lrev_tap, lrev_tfh,
- lrev_tsom,ldtiextra: TMatrix;
- lI: Integer;
- lap,lfh,lrl: double;
-begin
-
- if nVec < 1 then exit;
- //require HFS - head first supine. See Catnap for alternate body orientations
- if (length(lDicomData.PatientPos) >= 3) and (lDicomData.PatientPos[1] = 'H') and (lDicomData.PatientPos[2] = 'F') and (lDicomData.PatientPos[3] = 'S') then
- else begin
- Msg('DTI vector error: Position is not head first supine');
- exit;
- end;
- //Assume supine
- ltpo := Matrix2D (1,0,0, 0,1,0, 0,0,1 );
- lrev_tpo := revMat(ltpo);
- //Assume head first
- ltpp := Matrix2D (0,1,0, -1,0,0, 0,0,-1);
- lrev_tpp := revMat(ltpp);
- ltpom := MultiplyMatrices( ltpo, ltpp);
- lrev_tpom := MultiplyMatrices( lrev_tpp,lrev_tpo );
- lap := lDicomData.AngulationAP * PI /180;
- lfh := lDicomData.AngulationFH * PI /180;
- lrl := lDicomData.AngulationRL * PI /180;
- //lAP:=-0.152557; lFH:=-0.0616358; lRL := -0.00676092;
-
- ltrl := Matrix2D (1,0,0, 0,cos(lrl),-sin(lrl), 0,sin(lrl),cos(lrl));
- ltap := Matrix2D (cos(lap),0,sin(lap), 0,1,0, -sin(lap),0,cos(lap));
- ltfh := Matrix2D (cos(lfh),-sin(lfh),0, sin(lfh),cos(lfh),0, 0,0,1);
- lrev_trl := revMat(ltrl);
- lrev_tap := revMat(ltap);
- lrev_tfh := revMat(ltfh);
- lmtemp1 := MultiplyMatrices( ltrl, ltap );
- ltang := MultiplyMatrices( lmtemp1, ltfh );
- lmtemp1 := MultiplyMatrices( lrev_tfh, lrev_tap );
- lrev_tang := MultiplyMatrices( lmtemp1, lrev_trl );
-
- if (lDicomData.PhilipsSliceOrient[1] = 'S') then //SAGITTAL
- lrev_tsom := Matrix2D (0,0,1, 0,-1,0, -1,0,0 )
- else if (lDicomData.PhilipsSliceOrient[1] = 'C') then //CORONAL
- lrev_tsom := Matrix2D (0,0,1, -1,0,0, 0,1,0 )
- else //TRANSVERSAL = AXIAL
- lrev_tsom := Matrix2D (0,-1,0, -1,0,0, 0,0,1 );
- ldtiextra := Matrix2D (0,-1,0, -1,0,0, 0,0,1 );
- lmtemp2 := MultiplyMatrices( ldtiextra, lrev_tsom );
- lmtemp1 := MultiplyMatrices (lmtemp2, lrev_tang);
-
- for lI := 1 to nVec do begin
-
- if (lDTIra[lI].bval <= 0) or ((lDTIra[lI].v1 = 0) and (lDTIra[lI].v2 = 0) and (lDTIra[lI].v3 = 0)) then begin
- lDTIra[lI].v1 := 0;
- lDTIra[lI].v2 := 0;
- lDTIra[lI].v3 := 0;
- end else begin
- //lIn := Vector2D(0.7071, -0.7071, -0.0000);
- lIn := Vector2D(-lDTIra[lI].v1,-lDTIra[lI].v2,-lDTIra[lI].v3);
- NormalizeVector2D(lIn);
- lout := VecMatMult (lin,lmtemp1);
- NormalizeVector(lout);
- lDTIra[lI].v1 := lOut.x;
- if lOut.y = 0 then
- lDTIra[lI].v2 := lOut.y //people dislike seeing -0
- else
- lDTIra[lI].v2 := -lOut.y; //flip Y component
- lDTIra[lI].v3 := lOut.z;
- end;
- end; //for each vector
-end;
function VV (lLabel: string; var lV: TVector): string;
begin
@@ -985,7 +812,7 @@ begin
lStr := lStr + VV('slice_dir',slice_dir);
lStr := lStr + VV('read_dir',read_dir);
lStr := lStr + VV('phase_dir',phase_dir);
- msg(lStr);
+ dcmMsg(lStr);
end;
@@ -998,7 +825,7 @@ begin
if nVec < 1 then exit;
if (length(lDicomData.PatientPos) >= 3) and (lDicomData.PatientPos[1] = 'H') and (lDicomData.PatientPos[2] = 'F') and (lDicomData.PatientPos[3] = 'S') then
else begin
- Msg('DTI vector error: Position is not head first supine');
+ dcmMsg('DTI vector error: Position is not head first supine');
exit;
end;
//fx(lDTI.v1,lDTI.v2,lDTI.v3);
@@ -1071,7 +898,7 @@ begin
if nVec < 1 then exit;
if (length(lDicomData.PatientPos) >= 3) and (lDicomData.PatientPos[1] = 'H') and (lDicomData.PatientPos[2] = 'F') and (lDicomData.PatientPos[3] = 'S') then
else begin
- Msg('DTI vector error: Position is not head first supine');
+ dcmMsg('DTI vector error: Position is not head first supine');
exit;
end;
if (length(lDicomData.PhaseEncoding) >= 3) and (lDicomData.PhaseEncoding[1] = 'C') and (lDicomData.PatientPos[2] = 'O') and (lDicomData.PatientPos[3] = 'L') then
@@ -1137,7 +964,7 @@ begin
if lName = '' then
exit;
lOutDir := lOutDir +lName;
- Msg('Creating folder '+lOutDir);
+ dcmMsg('Creating folder '+lOutDir);
{$I-}
MkDir(lOutDir);
if IOResult <> 0 then begin
@@ -1152,7 +979,7 @@ end;
procedure afx(lDICOMImgName: string; lDTI:TDTI; Pos: integer);
begin
- msg(extractfilename(lDicomImgName)+':'
+ dcmMsg(extractfilename(lDicomImgName)+':'
+floattostr(lDTI.bval)+': '
+floattostr(lDTI.v1)+': '
+floattostr(lDTI.v2)+': '
@@ -1160,7 +987,96 @@ begin
+inttostr(Pos));
end;
+function ImageScalingOrIntensityVaries(var lDICOMra: TDICOMrap; lFirstDICOM, lLastDICOM: integer): boolean;
+var
+ lIndex: integer;
+begin
+ result := false;
+ if (lFirstDICOM >= lLastDICOM) then exit; //only one image
+ result := true;
+ for lIndex := (lFirstDICOM +1) to lLastDICOM do begin
+ if lDICOMra^[lIndex].IntenIntercept <> lDICOMra^[lFirstDICOM].IntenIntercept then
+ exit; //1492
+ if lDICOMra^[lIndex].IntenScale <> lDICOMra^[lFirstDICOM].IntenScale then
+ exit; //1492
+ if lDICOMra^[lIndex].Allocbits_per_pixel <> lDICOMra^[lFirstDICOM].Allocbits_per_pixel then
+ exit;
+ end;
+ result := false;
+end;
+procedure MakeFloat (var lBuffer: bytep; var lDicomData: DICOMdata; var lSliceBytesOut: integer);
+//data is saved as RGBRGBRGB - convert to RRRR GGGG BBBB
+var
+ lRA: bytep;
+ lPix,lnPix,lnBytes: integer;
+ l8i : byteP;
+ l16ui : WordP;
+ l16i: SmallIntP;
+ l32i: LongIntP;
+ l32fo, l32f: SingleP;
+ lByteSwap: boolean;
+begin
+ if (lDicomData.XYZdim[1] < 1) or (lDicomData.XYZdim[2] < 1) or (lDicomData.XYZdim[3] < 1) then exit;
+ dcmMsg(' Converting data to 32-bit float to correct for differences slope/intercept/precision: '+chr(9)+realtostr(lDicomData.IntenScale,8)+chr(9)+realtostr(lDicomData.IntenIntercept,8)+chr(9)+inttostr(lDicomData.Allocbits_per_pixel));
+ {$IFDEF ENDIAN_BIG}
+ lByteSwap := odd(lDICOMdata.little_endian);
+ {$ELSE}
+ lByteSwap := not odd(lDICOMdata.little_endian);
+ {$ENDIF}
+ lnPix := lDicomData.XYZdim[1]*lDicomData.XYZdim[2]*lDicomData.XYZdim[3];
+ //msg(' '+inttostr(lDicomData.XYZdim[1])+' '+inttostr(lDicomData.XYZdim[2])+' '+inttostr(lDicomData.XYZdim[3]) );
+ lnBytes := lnPix *trunc(((lDicomData.Allocbits_per_pixel)+7)/8);
+ GetMem(lRA,lnBytes );
+ Move(lBuffer^,lRA^,lnBytes); //move(src,dest,sz)
+ Freemem(lBuffer);
+ GetMem(lBuffer,lnPix * 4); //save as 32 bit float: 4 bytes per pixel
+ l32fo := SingleP(@lBuffer^[1]);
+ if lDicomData.Allocbits_per_pixel = 8 then begin //8bit - byte swapping is not a problem...
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := lRA^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //8bit
+ //next 16 bit
+ if (lDicomData.Allocbits_per_pixel = 16) and (lByteSwap) then begin //UNSWAP 16bit
+ l16ui := WordP(@lRA^[1]);
+
+ for lPix := 1 to lnPix do
+ l16ui^[lPix] := swap(l16ui^[lPix]);
+ end; //UNSWAP 16bit
+ if (lDicomData.Allocbits_per_pixel = 16) and (not lDicomData.SignedData) then begin //16bit UNSIGNED
+
+ l16ui := WordP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := l16ui^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //16bit UNSIGNED
+ if (lDicomData.Allocbits_per_pixel = 16) and (lDicomData.SignedData) then begin //16bit SIGNED
+ l16i := SmallIntP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := l16i^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //16bit SIGNED
+ //NEXT 32bit
+ if (lDicomData.Allocbits_per_pixel = 32) and (not lDicomData.FloatData) then begin //UNSWAP 32bit
+ l32i := LongIntP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ pswap4i(l32i^[lPix]);
+ end; //UNSWAP 32bit
+ if (lDicomData.Allocbits_per_pixel = 32) and (not lDicomData.FloatData) then begin //32bit INTEGER
+ l32i := LongIntP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := l32i^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //32bit INTEGER
+ if (lDicomData.Allocbits_per_pixel = 32) and ( lDicomData.FloatData) then begin //32bit FLOAT
+ l32f := SingleP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := l32f^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //32bit FLOAT
+ Freemem(lRA);
+ lDicomData.Allocbits_per_pixel := 32;
+ lDicomData.FloatData := true;
+ lDicomData.IntenScale := 1;
+ lDicomData.IntenIntercept := 0;
+ lSliceBytesOut := lnPix * 4;
+end;
function Dicom2NII(var lDICOMra: TDICOMrap; lFirstDICOM, lLastDICOM: integer; var lOutDirOrig: string; var lPrefs: TPrefs; lVols: integer): boolean;
var
@@ -1170,45 +1086,57 @@ var
lVolGb : double;
lAllocSLiceSz,
lStart,lEnd,lmosX,lmosY,lIndex,lSecondDICOM,lSeries,lnSeries,lSliceBytes,
- lBaseBitDepth,lMosaicSlices,
- lSliceBytesOut,lvolOffset,lvolOffsetInit,lvolBytesOut: integer;
- lBaseIntenScale,lBaseIntenIntercept,lDX: single;
+ //lBaseBitDepth,
+ lMosaicSlices,lSliceBytesOut,lvolOffset,lvolOffsetInit,lvolBytesOut: integer;
+ //lBaseIntenScale,lBaseIntenIntercept,
+ lDX: single;
//lDynStr,
lDicomImgName,lOutHdrName,lOutImgName,lOutImgNameGZ,lOutDir,lOutDTIname:string;
lDICOMData:dicomdata;
- lFlip,lIntenScaleVaries,lInterleaved,lFlipMosaic,lVolSave,lByteSwap : boolean;
+ lReadOK,lFlip,lIntenScaleVaries,lInterleaved,lFlipMosaic,lVolSave,lByteSwap : boolean;
lAHdr: TNIFTIhdr;
lTextF: TextFile;
lOutF,lInF: File;
lvBuffer,lsBuffer: bytep;
begin
- result := false;
if lPrefs.DebugMode2 then begin
- Msg( DICOMstr(1,lDICOMra,OutputFilename(lDicomImgName,lDICOMra^[lFirstDICOM],lPref)));
+
+ dcmMsg( DICOMstr(1,lDICOMra,OutputFilename(lDicomImgName,lDICOMra^[lFirstDICOM],lPref)));
+ dcmMsg(inttostr(lDICOMdata.XYZdim[1])+'x'+inttostr(lDICOMdata.XYZdim[2])+'x'+inttostr(lDICOMdata.XYZdim[3])+'x'+inttostr(lDICOMdata.XYZdim[4]));
result := true;
exit;
- end;
+ end;
+ result := false;
+
lPref := lPrefs;
CorrectPrefs(lPref);
lmosX := 1;
lmosY := 1;
lSecondDICOM := lFirstDICOM+1;
- lIntenScaleVaries := false;
+
lInterleaved := false;
lnSeries := (lLastDICOM+1) -lFirstDICOM; //e.g. first=10, last=10 means 1 image
if lnSeries < 1 then
- exit;
+ exit;
//next if magnitude and phase maps are saved in the same 4D file, extract to separate files...
if (lDICOMra^[lFirstDICOM].file4D) and (MultiOrder(lDICOMra^[lFirstDICOM]) > 0) then
lPref.fourD := false;
lDicomImgName := lDICOMra^[lFirstDICOM].Filename;
lDicomData := lDICOMra^[lFirstDICOM];
+
+
if (lDicomData.SamplesPerPixel = 3) then begin
- Msg('Warning: RGB to NIfTI conversion poorly tested: '+lDicomImgName);
+ dcmMsg('Warning: RGB to NIfTI conversion poorly tested: '+lDicomImgName);
end;
{$IFDEF ENDIAN_BIG}
lByteSwap := odd(lDICOMdata.little_endian);
+ (*if (lDicomData.CSAImageHeaderInfoPos > 0) or (lDicomData.CSAImageHeaderInfoSz >0) then begin
+ lDicomData.CSAImageHeaderInfoPos := 0;
+ lDicomData.CSAImageHeaderInfoSz := 0;
+ Msg('Warning: Modern Siemens CSA headers not supported on obsolete big-endian PowerPC computers. DTI vectors and mosaic slice positioning may be inaccurate.');
+ end; *)
+
{$ELSE}
lByteSwap := not odd(lDICOMdata.little_endian);
{$ENDIF}
@@ -1218,16 +1146,18 @@ begin
lOutDir := ExtractFilePath(lDicomImgName);
end;
if not DirWritePermission(lOutDir) then begin // <- tested with Unix
- Msg('Error: output directory is read-only: '+lOutDir);
+ dcmMsg('Error: output directory is read-only: '+lOutDir);
exit;
end;
if lPref.createoutputfolder then
MkDICOMDir(lDICOMdata,lOutDir);
if not direxists(lOutDir) then begin
- Msg('Unable to find output directory '+lOutDir);
+ dcmMsg('Unable to find output directory '+lOutDir);
lOutDir := ExtractFileDirWithPathDelim2(lDicomImgName)
end; //else directory exists
- //lOutHdrName :=lOutDir+OutputFilename(lDicomImgName,lDicomData,lPrefs.AppendDate,lPrefs.AppendAcqSeries,lPrefs.AppendProtocolName,lPrefs.AppendPatientName,lPrefs.FourD,lPrefs.AppendFilename)+'.hdr';
+
+
+ //lOutHdrName :=lOutDir+OutputFilename(lDicomImgName,lDicomData,lPrefs.AppendDate,lPrefs.AppendAcqSeries,lPrefs.AppendProtocolName,lPrefs.AppendPatientName,lPrefs.FourD,lPrefs.AppendFilename)+'.hdr';
lOutHdrName :=lOutDir+OutputFilename(lDicomImgName,lDicomData,lPref)+'.hdr';
lOutImgName :=changefileext(lOutHdrName,'.img');
if lPref.SingleNIIFile then begin
@@ -1237,7 +1167,7 @@ begin
if (lPref.SingleNIIFile) and (lPref.GZip) then begin
lOutHdrName := lOutHdrName+'.gz';
if (not UniqueFileName(lOutHdrName)) then begin
- Msg('File already exists '+lOutImgName+' '+lOutHdrName);
+ dcmMsg('File already exists '+lOutImgName+' '+lOutHdrName);
exit;
end;
//we now need to remove the .gz - not that unique filename may have appended postfix, e.g. filename.nii.gz -> filenameA.nii.gz
@@ -1245,12 +1175,21 @@ begin
lOutImgName := lOutHdrName;
end else begin
if (not UniqueFileName(lOutHdrName)) or (not UniqueFileName(lOutImgName)) then begin
- Msg('File already exists '+lOutImgName+' '+lOutHdrName);
+ dcmMsg('File already exists '+lOutImgName+' '+lOutHdrName);
exit;
end;
end;
- Msg(extractfilename(lDicomImgName)+'->'+extractfilename(lOutImgName));
+ dcmMsg(extractfilename(lDicomImgName)+'->'+extractfilename(lOutImgName));
DICOM2AnzHdr(lAHdr,lPref.Anonymize,lDicomImgName,lDICOMdata);
+
+ if lPrefs.DebugMode2 then begin
+ dcmMsg('slice/vols/series '+inttostr(lDICOMdata.SlicesPer3DVol )+' '+inttostr(lVols)+' '+inttostr(lnSeries));
+ dcmMsg('x/y/z '+inttostr(lDICOMdata.XYZdim[1])+'x'+inttostr(lDICOMdata.XYZdim[2])+'x'+inttostr(lDICOMdata.XYZdim[3])+'x'+inttostr(lDICOMdata.XYZdim[4]));
+ result := true;
+ exit;
+ end;
+
+
if (lVols > 1) and ((lnSeries mod lVols)=0) then
lDICOMdata.SlicesPer3DVol := round(lnSeries/lVols);
lDTIra[1].bval := -1; //not DTI
@@ -1270,14 +1209,14 @@ begin
lAHdr.dim[3] := lDICOMdata.SiemensMosaicX *lDICOMdata.SiemensMosaicY;
lAHdr.dim[4] := lnSeries;
if ((lmosX*lmosY) < lAHdr.dim[3]) then begin
- msg('Aborted '+lDicomData.Filename+ ' : This '+inttostr(lmosx)+'*'+inttostr(lmosy)+' mosaic can not hold '+inttostr(lAHdr.dim[3])+' slices.');
+ dcmMsg('Aborted '+lDicomData.Filename+ ' : This '+inttostr(lmosx)+'*'+inttostr(lmosy)+' mosaic can not hold '+inttostr(lAHdr.dim[3])+' slices.');
exit;
end;
end else if lDICOMdata.File4D then begin//(lDicomData.XYZdim[3] > 1) and (lnSeries = 1) and (lDICOMdata.SlicesPer3DVol > 1) and ((lAHdr.dim[3] mod lDICOMdata.SlicesPer3DVol)=0) then begin
lAHdr.dim[4] := lAHdr.dim[3] div lDICOMdata.SlicesPer3DVol;
lAHdr.dim[3] := lDICOMdata.SlicesPer3DVol;
- //fx(213,lAHdr.dim[3],lAHdr.dim[4]);
+
end else if (lDicomData.XYZdim[3] > 1) then
lAHdr.dim[4] := lnSeries
else begin
@@ -1289,7 +1228,26 @@ begin
end else
lAHdr.dim[3] := lnSeries;
end;
- lFlip := false;
+
+ if (lDICOMdata.BandwidthPerPixelPhaseEncode > 0) then begin
+ //do this AFTER mosaics have reset dim[1] and dim[2]
+ if (length(lDICOMdata.PhaseEncoding) > 0) and ((lDICOMdata.PhaseEncoding[1]='C') or (lDICOMdata.PhaseEncoding[1]='R')) then begin
+ //fx( lAHdr.dim[1],lAHdr.dim[2]);
+
+ if (lDICOMdata.PhaseEncoding[1]='C') then begin//columns
+ lAHdr.pixdim[6] := 1000/lDICOMdata.BandwidthPerPixelPhaseEncode/lAHdr.dim[2];
+ lAHdr.slice_duration:= lAHdr.pixdim[6] * lAHdr.dim[2];
+ dcmMsg(inttostr(lAHdr.dim[2]));
+ end else begin //rows
+ lAHdr.pixdim[6] := 1000/lDICOMdata.BandwidthPerPixelPhaseEncode/lAHdr.dim[1];
+ lAHdr.slice_duration:= lAHdr.pixdim[6] * lAHdr.dim[1];
+ dcmMsg(inttostr(lAHdr.dim[1]));
+ end;
+ dcmMsg('Effective echo spacing: '+floattostr( lAHdr.pixdim[6])+'ms, BandwidthPerPixelPhaseEncode: '+floattostr(lDICOMdata.BandwidthPerPixelPhaseEncode));
+ end else
+ dcmMsg('Unable to determine echo spacing: not sure of phase encoding direction');
+ end;
+lFlip := false;
if lnSeries > 1 then begin//check slice order
lFlip := CheckSliceDirection(lDICOMra^[lFirstDICOM],lDICOMra^[lLastDICOM]);
if lFlip then begin
@@ -1306,9 +1264,24 @@ begin
end;
end;
dicom_2_nifti(lDICOMdata,lAHdr,lMosaicSlices,lFlipmosaic);
- lBaseIntenScale := lDICOMdata.IntenScale;
+ //all slices in a NIFTI image must be of the same precision and have the same scaling intercept and slope - see if this applies
+ (*lBaseIntenScale := lDICOMdata.IntenScale;
lBaseIntenIntercept := lDICOMdata.IntenIntercept;
lBaseBitDepth := lDicomData.Allocbits_per_pixel;
+ lIntenScaleVaries := false;
+ for lSeries := 1 to lnSeries do begin
+ lIndex := Index (lSeries,lFirstDICOM,lInterleaved,lFlip,lAHdr);
+ if lDICOMra^[lIndex].IntenIntercept <> lBaseIntenIntercept then
+ lIntenscaleVaries := true; //1492
+ if lDICOMra^[lIndex].IntenScale <> lBaseIntenScale then
+ lIntenscaleVaries := true; //1492
+ if lDICOMra^[lIndex].Allocbits_per_pixel <> lBaseBitDepth then
+ lIntenscaleVaries := true;
+ end; //for lnSeries *)
+ lIntenScaleVaries := ImageScalingOrIntensityVaries(lDICOMra, lFirstDICOM, lLastDICOM);
+
+
+
(* for lSeries := 1 to lnSeries do begin
@@ -1320,15 +1293,26 @@ begin
//exit;//get out of here - crucial critical -- last chance before data saved to disk
if (lAHdr.bitpix = 8) and (lDicomData.SamplesPerPixel = 3) then begin
+ if (lIntenScaleVaries) then begin
+ dcmMsg('RGB files can not have varying intensity scales!');
+ lIntenScaleVaries := false;
+ end;
lRGB := 3;
lAHdr.datatype := kDT_RGB;
lAHdr.bitpix := 24;
end else
lRGB := 1;
+ if (lIntenScaleVaries) then begin
+ lAHdr.datatype := kDT_FLOAT;
+ lAHdr.bitpix := 32;
+ dcmMsg('Warning: images have different precision or intensity scaling - saving as 32-bit float');
+ end;
lSliceBytes := lDicomData.XYZdim[1]*lDicomData.XYZdim[2]*lDicomData.XYZdim[3]*trunc(((lDicomData.Allocbits_per_pixel)+7)/8)*lRGB;
GetMem(lsBuffer,lSliceBytes);
- //showmessage(inttostr(lSliceBytes));
- lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc(((lDicomData.Allocbits_per_pixel)+7)/8)*lRGB;
+
+ lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc((lAHdr.bitpix+7)/8)*lRGB;
+ if lPrefs.DebugMode2 then
+ dcmMsg(' bytes/bitPix '+inttostr( lSliceBytesOut)+' '+inttostr(lAHdr.bitpix) );
lVolBytesOut := lSliceBytesOut * lAHdr.dim[4];
lVolOffset := 1;
lVolGB := (lSliceBytesOut/ 1073741824) * lAHdr.dim[4]; //bytes *1024 (kB) *1024 (Mb) * 1024 (Gb)
@@ -1337,25 +1321,25 @@ begin
if lVolGb < 0.95 then
lVolSave := true
else begin
- Msg('Very large volume: '+floattostr(lVolGb)+' Gb: slice-by-slice conversion required.');
+ dcmMsg('Very large volume: '+floattostr(lVolGb)+' Gb: slice-by-slice conversion required.');
if lPref.GZip then begin
lPref.GZip := false;
- Msg('Unable to automatically GZip such a large file.');
+ dcmMsg('Unable to automatically GZip such a large file.');
end;
lVolSave := false;
end;
- if lVolSave then begin //save entire volume
- if lPref.SingleNIIFile then begin
+ if lVolSave then begin //save entire volume
+ if lPref.SingleNIIFile then begin
lVolOffset := kNIIImgOffset+1;// 353; //first 352 bytes empty
lVolBytesOut := lVolBytesOut + lVolOffset -1;
- end else lVolOffset := 1;
- GetMem(lvBuffer,lVolBytesOut);
- //showmessage(inttostr(lVolBytesOut));
- //we could copy NIfTI header to Buffer, but this would need to be changed for
- //4D->3D images or images where we swap 3rd and 4th dimension....
- end else begin //save slice by slice - slower but low RAM usage...
+ end else lVolOffset := 1;
+ GetMem(lvBuffer,lVolBytesOut);
+ //showmessage(inttostr(lVolBytesOut));
+ //we could copy NIfTI header to Buffer, but this would need to be changed for
+ //4D->3D images or images where we swap 3rd and 4th dimension....
+ end else begin //save slice by slice - slower but low RAM usage...
if not SaveHdr (lOutHdrName,lAHdr, false,lPref.SPM2) then begin
- Msg('Error saving data - do you have permission and space for '+lOutHdrName+'?');
+ dcmMsg('Error saving data - do you have permission and space for '+lOutHdrName+'?');
exit;
end;
Filemode := 2;
@@ -1374,7 +1358,7 @@ begin
lDicomImgName := lDICOMra^[lIndex].Filename;
lDicomData := lDICOMra^[lIndex];
if (lDICOMdata.ManufacturerID = kPhilipsID) and (lDICOMdata.nDTIdir > 1) and (lAHdr.dim[4] < kMaxDTIDir) and (lDICOMdata.nDTIdir >= lAHdr.dim[4]) then begin //
- Msg('4D Philips DTI data '+inttostr(lDICOMdata.nDTIdir));
+ dcmMsg('4D Philips DTI data '+inttostr(lDICOMdata.nDTIdir));
for lDTIdir := 1 to lAHdr.dim[4] do begin
lDTIra[lDTIdir].bval := lDICOMdata.DTI[lDTIdir].bval;
lDTIra[lDTIdir].v1 := lDICOMdata.DTI[lDTIdir].v1;
@@ -1385,11 +1369,7 @@ begin
end else if (lDICOMdata.ManufacturerID = kSiemensID) and (lDTIra[1].Bval >= 0) and (lDTIdir < kMaxDTIDir) and ( ((lSeries mod lAHdr.dim[3]) = 1) or((lMosX > 1) or (lMosY > 1))) then begin //
inc(lDTIdir);
IsSiemensDTI(lDicomData,lDTIra[lDTIdir], lDicomImgName,lPrefs);
- // msgfx(lSeries, lDTIra[lDTIdir].v1,lDTIra[lDTIdir].v2,lDTIra[lDTIdir].v3);
-
- //fx(lDTI.v1,lDTI.v2,lDTI.v3,666);
- //afx(lDicomImgName, lDTIra[lDTIdir],lDTIdir);
end else if (lDICOMdata.nDTIdir = 1) and (lDICOMdata.DTI[1].Bval >= 0) and (lDTIdir < kMaxDTIDir) and ( (lSeries mod lAHdr.dim[3]) = 1) then begin //
inc(lDTIdir);
lDTIra[lDTIdir].bval := lDICOMdata.DTI[1].bval;
@@ -1397,74 +1377,94 @@ begin
lDTIra[lDTIdir].v2 := lDICOMdata.DTI[1].v2;
lDTIra[lDTIdir].v3 := lDICOMdata.DTI[1].v3;
end;
-
- if lDICOMdata.IntenIntercept <> lBaseIntenIntercept then
- lIntenscaleVaries := true; //1492
- if lDICOMdata.IntenScale <> lBaseIntenScale then
- lIntenscaleVaries := true;
- if lDicomData.Allocbits_per_pixel <> lBaseBitDepth then
- lIntenscaleVaries := true;
+ lReadOK := true;
if (lDicomData.JPEGLosslessCpt) then begin
AssignFile(lInF, lDicomImgName);
- Reset(lInF,1);
- Filemode := 0; //ReadONly
- lSliceBytesOut := lSliceBytes;
- lAllocSLiceSz := (lDICOMdata.XYZdim[1]*lDICOMdata.XYZdim[2]{height * width} * lDICOMdata.Allocbits_per_pixel+7) div 8 ;
- //fx('name='+lDicomImgName+' allocsz='+inttostr(lAllocSLiceSz)+' offset='+inttostr(lDicomData.CompressOffset)+' sz='+inttostr(lDicomData.CompressSz));
- //fx(lAllocSLiceSz,lDicomData.CompressOffset,lDICOMdata.CompressSz);
- DecodeJPEG(lInF,SmallIntP0(lsBuffer),ByteP0(lsBuffer),lAllocSliceSz,lDicomData.CompressOffset,lDICOMdata.CompressSz,false);
+ Reset(lInF,1);
+ //lDICOMdata.CompressSz := FileSize(lInF)-lDicomData.CompressOffset;
+ Filemode := 0; //ReadONly
+ //lSliceBytesOut := lSliceBytes;
+ dcmMsg('Decoding lossless '+inttostr(lDICOMdata.XYZdim[1])+'x'+inttostr(lDICOMdata.XYZdim[2])+' JPEG starting from byte '+ inttostr(lDicomData.CompressOffset)+' with '+inttostr(lDICOMdata.CompressSz)+' bytes');
+ if ( lDicomData.XYZdim[3] > 1) or ( lDicomData.XYZdim[4] > 1) then
+ dcmMsg('*Warning: this software will only convert the first slice of this multislice lossless compressed JPEG');
+ lAllocSLiceSz := (lDICOMdata.XYZdim[1]*lDICOMdata.XYZdim[2] * lDICOMdata.Allocbits_per_pixel+7) div 8 ;
+ DecodeJPEG(lInF,SmallIntP0(lsBuffer),ByteP0(lsBuffer),lAllocSliceSz,lDicomData.CompressOffset,lDICOMdata.CompressSz,false);
CloseFile(lInF);
- FlipTB(lDICOMdata,lsBuffer);
+ (*FlipTB(lDICOMdata,lsBuffer);
if lVolSave then begin{save entire volume}
Move(lsBuffer^,lvBuffer^[lvolOffset],lSliceBytesOut);
//Msg(inttostr(lSeries));
lVolOffset := lVolOffset + lSliceBytesOut;
end else begin //save slice-by-slice
Filemode := 2; //read and write
- BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
- end;
+ BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
+ end;*)
end else if (FSize(lDicomImgName) >= (lSliceBytes+lDicomData.imagestart)) then begin
- Filemode := 0; //ReadONly
- AssignFile(lInF, lDicomImgName);
- Reset(lInF,1);
- Seek(lInF,lDicomData.imagestart);
- Filemode := 0; //ReadONly
- BlockRead(lInF, lsBuffer^, lSliceBytes);
- if (lDICOMdata.file4D) and (lPrefs.Swizzle4D) then
- SwapTime(lDICOMdata,lsBuffer);//data is stored X,Y,T,Z - swap to X,Y,Z,T
- lSliceBytesOut := lSliceBytes;
- if (lDICOMdata.PlanarConfig = 0) and (lDicomData.SamplesPerPixel = 3) then
+ Filemode := 0; //ReadONly
+ AssignFile(lInF, lDicomImgName);
+ Reset(lInF,1);
+ Seek(lInF,lDicomData.imagestart);
+ Filemode := 0; //ReadONly
+ BlockRead(lInF, lsBuffer^, lSliceBytes);
+ CloseFile(lInF);
+ (*if (lDICOMdata.file4D) and (lPrefs.Swizzle4D) then
+ SwapTime(lDICOMdata,lsBuffer);//data is stored X,Y,T,Z - swap to X,Y,Z,T
+ lSliceBytesOut := lSliceBytes;
+ if (lDICOMdata.PlanarConfig = 0) and (lDicomData.SamplesPerPixel = 3) then
MakePlanar(lsBuffer,lDICOMdata);
- if (lMosX > 1) or (lMosY > 1) then begin
- //lBuffer: bytep;lmosX,lmosY,lSlices: integer; lFlip: boolean; var lDicomData: DICOMdata);
- DeMosaic(lsBuffer,lmosX,lmosY,lMosaicSlices,lFlipMosaic,lDICOMdata);
+ if (lMosX > 1) or (lMosY > 1) then begin
+ DeMosaic(lsBuffer,lmosX,lmosY,lMosaicSlices,lFlipMosaic,lDICOMdata);
lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc(((lDicomData.Allocbits_per_pixel)+7)/8);
- end else
- FlipTB(lDICOMdata,lsBuffer);
- CloseFile(lInF);
+ end else
+ FlipTB(lDICOMdata,lsBuffer);
+
if lVolSave then begin{save entire volume}
-//showmessage('volsave'+lDicomImgName+ inttostr(lvolOffset)+':'+inttostr(lSliceBytesOut));
Move(lsBuffer^,lvBuffer^[lvolOffset],lSliceBytesOut);
lVolOffset := lVolOffset + lSliceBytesOut;
end else begin //save slice-by-slice
Filemode := 2; //read and write
- BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
- end;
+ BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
+ end; *)
end else begin
- Msg('Serious error with file '+ extractfilename(lDicomImgName));
- (*Msg('Error: file ' + extractfilename(lDicomImgName)+' is '+inttostr(FSize(lDicomImgName))+
- ' with an offset of '+inttostr(lDicomData.imagestart) +' should have '+inttostr(lSliceBytes)+' bytes image data!');
- Msg(inttostr(lDicomData.XYZdim[1])+' '+inttostr(lDicomData.XYZdim[2])+' '+inttostr(lDicomData.XYZdim[3]));
- readln;*)
- end;
- end;
- freemem(lsBuffer);
- Filemode := 2; //read and write
- lOutImgNameGZ := lOutImgName;
- if lVolSave then begin{save slice-by-slice}
+ dcmMsg('Serious error with file '+ extractfilename(lDicomImgName));
+ lReadOK := false;
+ end; //if JPEG else if UNCOMPRESSED else ERROR
+ if lReadOK then begin
+ lDicomData.XYZdim[4] := lAHdr.dim[4]; //do this now - depending on slice order DicomData can be first or last volume
+ if (lDICOMdata.file4D) and (lPrefs.Swizzle4D) then
+ SwapTime(lDICOMdata,lsBuffer);//data is stored X,Y,T,Z - swap to X,Y,Z,T
+ lSliceBytesOut := lSliceBytes;
+ if (lIntenScaleVaries) then begin
+
+ MakeFloat(lsBuffer,lDICOMdata, lSliceBytesOut);
+ lByteSwap := false; //Un-swapped during conversion
+ end;
+ if (lDICOMdata.PlanarConfig = 0) and (lDicomData.SamplesPerPixel = 3) then
+ MakePlanar(lsBuffer,lDICOMdata);
+ if (lMosX > 1) or (lMosY > 1) then begin
+ DeMosaic(lsBuffer,lmosX,lmosY,lMosaicSlices,lFlipMosaic,lDICOMdata);
+ lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc((lAHdr.bitpix+7)/8);
+ end else
+ FlipTB(lDICOMdata,lsBuffer);
+
+ //msg(inttostr(lSliceBytesOut)+ ' '+inttostr(lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc((lAHdr.bitpix+7)/8)));
+ //lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc((lAHdr.bitpix+7)/8);
+ if lVolSave then begin{save entire volume}
+ Move(lsBuffer^,lvBuffer^[lvolOffset],lSliceBytesOut);
+ lVolOffset := lVolOffset + lSliceBytesOut;
+ end else begin //save slice-by-slice
+ Filemode := 2; //read and write
+ BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
+ end;
+ end; //if lReadOK
+ end;
+ freemem(lsBuffer);
+ Filemode := 2; //read and write
+ lOutImgNameGZ := lOutImgName;
+ if lVolSave then begin{save slice-by-slice}
lOutImgNameGZ := SaveNIfTICore (lOutImgName, lvBuffer, lVolOffsetInit, lAHdr, lPref,lByteSwap)
- end else //data saved slice by slice
- CloseFile(lOutF);
+ end else //data saved slice by slice
+ CloseFile(lOutF);
//if (lPref.StartClip > 0) or (lPref.EndClip > 0) then
// Clip4D(lOutHdrName, lAHdr, false,lPref.SPM2,lPref.SingleNIIFile,lPref.GZip, true, lPref.StartClip,lPref.EndClip);
@@ -1475,7 +1475,7 @@ begin
if lDTIra[lIndex].bval = 0 then
lStart := lIndex;
if lStart < 1 then begin
- Msg('* Warning: diffusion acquisition does not have b-0 image');
+ dcmMsg('* Warning: diffusion acquisition does not have b-0 image');
PartialAcquisitionError;
end;
lStart := -1;//ensure this is a DTI image - some scans must have a bvalue > 1
@@ -1487,15 +1487,15 @@ begin
lStart := 1;
lEnd := lDTIdir;
lOutDTIname := lOutImgName;
- Msg('Number of diffusion directions = '+inttostr(lDTIdir));
+ dcmMsg('Number of diffusion directions = '+inttostr(lDTIdir));
if lDicomData.ManufacturerID = kSiemensID then begin
- Msg('Note: detected Siemens Software version [0018:1020] = '+inttostr(lDicomData.Vers0018_1020) );
- Msg(' -Will use 0019:000E or 0019:100E instead of 0029:1020 if version >= ' +inttostr(lPrefs.SiemensDTIUse0019If00181020atleast));
- Msg(' -Will stack across Acquisitions if version >=' +inttostr(lPrefs.SiemensDTIStackIf00181020atleast));
- Msg(' -No slice angulation correction of vectors if version >=' +inttostr(lPRefs.SiemensDTINoAngulationCorrectionIf00181020atleast));
- Msg(' To adjust, edit '+IniName );
+ dcmMsg('Note: detected Siemens Software version [0018:1020] = '+inttostr(lDicomData.Vers0018_1020) );
+ dcmMsg(' -Will use 0019:000E or 0019:100E instead of 0029:1020 if version >= ' +inttostr(lPrefs.SiemensDTIUse0019If00181020atleast));
+ dcmMsg(' -Will stack across Acquisitions if version >=' +inttostr(lPrefs.SiemensDTIStackIf00181020atleast));
+ dcmMsg(' -No slice angulation correction of vectors if version >=' +inttostr(lPRefs.SiemensDTINoAngulationCorrectionIf00181020atleast));
+ dcmMsg(' To adjust, edit '+IniName );
if lDicomData.Vers0018_1020 = 13 then
- Msg(' *Warning: some Siemens VB13 set DiffusionGradientDirection incorrectly. Please check manually validate');
+ dcmMsg(' *Warning: some Siemens VB13 set DiffusionGradientDirection incorrectly. Please check manually validate');
if lDicomData.Vers0018_1020 >= lPrefs.SiemensDTINoAngulationCorrectionIf00181020atleast then
SiemensFlipYBvecs(lDTIra,lDTIdir)
else
@@ -1503,6 +1503,8 @@ begin
end else if lDicomData.ManufacturerID = kPhilipsID then begin
PhilipsCorrectBvecs(lDicomData,lDTIra,lDTIdir);
//next: philips scans can include DWI images with bval>0 and v1=0,v2=0,v3=0 - we want to exclude these
+ //for lIndex := lDTIdir downto 1 do
+ // msg(inttostr(lIndex)+ kTab+floattostr(lDTIra[lIndex].bval)+kTab+floattostr(lDTIra[lIndex].v1)+kTab+floattostr(lDTIra[lIndex].v2)+kTab+floattostr(lDTIra[lIndex].v3));
for lIndex := lDTIdir downto 1 do
if (lDTIra[lIndex].bval = 0) or (lDTIra[lIndex].v1 <> 0) or (lDTIra[lIndex].v2 <> 0) or (lDTIra[lIndex].v3 <> 0) then
lStart := lIndex;
@@ -1516,12 +1518,12 @@ begin
lOutDTIname := Clip4D(lOutHdrName, lAHdr, false,lPref, lStart-1,lDTIdir-lEnd);
//lOutDTIname := Clip4D(lOutHdrName, lAHdr, false,lPref.SPM2,lPref.SingleNIIFile,lPref.GZip, false, lStart-1,lDTIdir-lEnd);
//Msg(lOutDTIName);
- Msg('Removed DWI from DTI scan - saving volumes '+inttostr(lStart)+'..'+inttostr(lEnd));
+ dcmMsg('Removed DWI from DTI scan - saving volumes '+inttostr(lStart)+'..'+inttostr(lEnd));
end;//exclude scans
end else if lDicomData.ManufacturerID = kGEID then
GECorrectBvecs(lDicomData,lDTIra,lDTIdir)
else
- Msg('WARNING: Unkown manufacturer - DTI BVecs are probably incorrect.');//beta software
+ dcmMsg('WARNING: Unkown manufacturer - DTI BVecs are probably incorrect.');//beta software
if lStart <= lEnd then begin
//create output vectors
if lOutDTIname <> '' then begin //image file created
@@ -1560,10 +1562,10 @@ begin
ChangeNIfTISubformat(lOutHdrName, lAHdr,lPref) ;
end;
end; //slice-by-slice
- if lIntenscaleVaries then begin
+ (*if lIntenscaleVaries then begin
beep;
Msg('Intensity scale/slope or bit-depth varies across slices: perhaps convert with MRIcro.');
- end;
+ end;*)
if (lPref.enablereorient) and (lDicomData.XYZdim[2] > lPref.MinReorientMatrix) and (lDicomData.XYZdim[1] > lPref.MinReorientMatrix) and (lAHdr.dim[3] > 64) and (lAHdr.dim[4] < 2) then begin
lOutImgName := Reorient(lOutImgNameGZ,lAHdr,lPref,false,false);
if (lOutImgName <> '') and (lDicomData.TE < 25) and (lDicomData.TE > 0) then //T1 image
@@ -1574,4 +1576,4 @@ begin
ExitCode := 0;
end;
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/convertsimple.pas b/dcm2nii/convertsimple.pas
old mode 100644
new mode 100755
index 619b2bb..9a2c454
--- a/dcm2nii/convertsimple.pas
+++ b/dcm2nii/convertsimple.pas
@@ -8,7 +8,7 @@ define_types,SysUtils,dicomtypes,filename,nii_4dto3d,niftiutil,nii_orient, nii_c
function FDF( lFName: string; var lDcm: DicomData {; var lByteSwap: boolean}): boolean;
implementation
-uses dialogsx;
+uses dialogsx,dialogs_msg;
procedure ReadlnX (var F: TextFile; var lResult: string);
//Replicates Readln, but works for Unix files... Delphi 4's readln fails for non-MSDOS EOLs
@@ -95,7 +95,7 @@ begin
V1 := round(F1);
V2 := round(F2);
V3 := round(F3);
- //Msg(inttostr(V1)+','+inttostr(V2)+','+inttostr(V3));
+ //dcmMsg(inttostr(V1)+','+inttostr(V2)+','+inttostr(V3));
end;
@@ -103,7 +103,7 @@ procedure ReportHeader (lFormatName: string; var lDicomData: dicomdata);
const
kCR = '; ';
begin
- Msg (lFormatName
+ dcmMsg (lFormatName
+kCR+ ' Slice Number:'+inttostr(lDicomData.ImageNum)
+kCR+ 'XYZ dim: ' +inttostr(lDicomData.XYZdim[1])+'/'+inttostr(lDicomData.XYZdim[2])+'/'+inttostr(lDicomData.XYZdim[3])
+kCR+ 'XYZ position: ' +floattostr(lDicomData.PatientPosX)+'/'+floattostr(lDicomData.PatientPosY)+'/'+floattostr(lDicomData.PatientPosZ)
@@ -160,7 +160,7 @@ begin
result := false;
lFileSz := FSize(lFName);
if lFileSz < 1{not fileexists (lFName)} then begin
- MSG('Can not find file '+lFName);
+ dcmMsg('Can not find file '+lFName);
exit;
end;
FileMode := 0; { Set file access to read only }
@@ -173,7 +173,7 @@ begin
readlnx(ltextfile,lLine);
//lLine := trim(lLine);//remove leading/following characters
lLine := deblank(lLine);//remove leading/following characters
- //msg(lLine);
+ //dcmdcmdcmdcmMsg(lLine);
if ParseStr('floatbits=', lLine) > 0 then
ExtractInts(lLine, lDcm.Allocbits_per_pixel ,junk1,junk2);
if ParseStr('intslice_no', lLine) > 0 then begin
@@ -198,9 +198,9 @@ begin
until lDone;
if lDcm.Allocbits_per_pixel = 32 then begin
result := true;
- lDcm.float := true;
+ lDcm.FloatData := true;
end else begin
- Msg('Unsupported datatype: '+inttostr( lDcm.Allocbits_per_pixel)+ 'bits per pixel '+lFName);
+ dcmMsg('Unsupported datatype: '+inttostr( lDcm.Allocbits_per_pixel)+ 'bits per pixel '+lFName);
end;
if not lSliceNum then begin
ExtractInts(lFName, lDcm.ImageNum ,junk1,junk2);
@@ -229,7 +229,7 @@ var
begin
result := false;
if not NIFTIhdr_LoadImgRaw (false,lHdrName, lHdr, lImgBuffer, lImgOffset,lByteSwap) then exit;
- Msg('Converting to NIfTI '+lHdrName);
+ dcmMsg('Converting to NIfTI '+lHdrName);
lOutImgName := ChangeFilePrefix (lHdrName,'c');
if lPrefs.CustomRename then
CustomFilename(lOutImgName);
@@ -249,10 +249,10 @@ var
begin
result := false;
NIFTIhdr_ClearHdr(lHdr);
- Msg('WARNING: no image orientation matrix for '+lInFilename);
+ dcmMsg('WARNING: no image orientation matrix for '+lInFilename);
if not FDF (lInFilename,lDcm) then exit;
DICOM2AnzHdr (lHdr, false,lInFilename,lDcm);
//Raw2NIfTI(lInFilename,lHdr,lPrefs,true);
end; *)
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/csaread.pas b/dcm2nii/csaread.pas
old mode 100644
new mode 100755
index 03b23fe..19ebd42
--- a/dcm2nii/csaread.pas
+++ b/dcm2nii/csaread.pas
@@ -5,12 +5,13 @@ interface
// These values are crucial converting 2D mosaics to 3D images and computing DTI vectors
//see http://nipy.sourceforge.net/nibabel/dicom/siemens_csa.html
// This is a port of John Ashburners' spm_dicom_headers.m Matlab code
-uses SysUtils, dialogsx, define_types;
-
+uses SysUtils, dialogsx, define_types,dialogs_msg;
+{DEFINE verbose}
type
TBytearray = array of byte;
TCSA = record
Slices,MosaicX,MosaicY: longword;
+ BandwidthPerPixelPhaseEncode,
Bvalue,DTIv1,DTIv2,DTIv3, SliceNormV1, SliceNormV2,SliceNormV3: double;
end;
@@ -33,6 +34,9 @@ begin
ldti1 := lCSA.DTIv1;
ldti2 := lCSA.DTIv2;
ldti3 := lCSA.DTIv3;
+ if (abs(ldti1) > 0.9) and (abs(ldti2) > 0.9) and (abs(ldti3) > 0.9) then
+ lBval := 0; //syngo MR 2004A 4VA25A CSA header reports Bval=1000 for B0 images, use vectors to detect if this is a B0 image
+
end;
function GetCSAImageHeaderInfo (lFilename: string; lStart,lLength: integer; var lMosaicSlices,lMosaicX,lMosaicY: integer; var lv1,lv2,lv3: double): boolean;
@@ -47,7 +51,7 @@ begin
lMosaicY := lCSA.MosaicY;
lv1 := lCSA.SliceNormV1;
lv2 := lCSA.SliceNormV2;
- lv3 := lCSA.SliceNormV2;
+ lv3 := lCSA.SliceNormV3; //5/5/2013
end;
function DecodeCSA2 (lFilename: string; lCSAImageHeaderInfoPos, lCSAImageHeaderInfoSz: integer; var lCSA: TCSA): boolean;
@@ -199,14 +203,16 @@ begin //main function DecodeCSA2
lPos := lPos + 4; //skip 8 bytes of data, spm_dicom_headers refers to these as unused1 and unused2
lnTag := freaduint32;
if (lnTag < 1) or (lnTag > 1024) then begin
- showmsg('Error reading CSA header');
+ dcmMsg('Error reading CSA header');
exit;
end;
if (lData[lPos] <> 77) then showmsg('warning: strange CSA2 header');
lPos := lPos + 4; // skip the four bytes 77 00 00 00
//read tags
for lT := 1 to lnTag do begin
+
lTag := freadTag;
+
if lTag.nitems > 0 then begin
for lI := 1 to lTag.nitems do begin //read items
if lI > kMaxItem then
@@ -232,16 +238,38 @@ begin //main function DecodeCSA2
lCSA.SliceNormV1 := strtofloat(lItem[1].value);
lCSA.SliceNormV2 := strtofloat(lItem[2].value);
lCSA.SliceNormV3 := strtofloat(lItem[3].value);
+ //fx( lCSA.SliceNormV3,1234);
+ end;
+
+ if (lTag.name = 'SliceMeasurementDuration') and (SafeStr2Num(lItem[1].value)) then begin
+ lCSA.BandwidthPerPixelPhaseEncode := strtofloat(lItem[1].value);
+ {$IFDEF verbose} msg('SliceMeasurementDuration: '+floattostr(lCSA.BandwidthPerPixelPhaseEncode)); {$ENDIF}
end;
+
+ if (lTag.name = 'BandwidthPerPixelPhaseEncode') and (SafeStr2Num(lItem[1].value)) then begin
+ lCSA.BandwidthPerPixelPhaseEncode := strtofloat(lItem[1].value);
+ {$IFDEF verbose} msg('BandwidthPerPixelPhaseEncode: '+floattostr(lCSA.BandwidthPerPixelPhaseEncode)); {$ENDIF}
+ end;
+
+
+ (*if (lTag.name = 'EchoLinePosition') and (SafeStr2Num(lItem[1].value)) then begin
+ lCSA.BandwidthPerPixelPhaseEncode := strtofloat(lItem[1].value);
+ msg('EchoLinePosition: '+floattostr(lCSA.BandwidthPerPixelPhaseEncode));
+ end;*)
+ if (SafeStr2Num(lItem[1].value)) then begin
+ lCSA.BandwidthPerPixelPhaseEncode := strtofloat(lItem[1].value);
+ {$IFDEF verbose} msg(lTag.name+' '+inttostr(lTag.nitems)+' '+floattostr(lCSA.BandwidthPerPixelPhaseEncode)); {$ENDIF}
+ end;
+
end;//at least one item
end; //for each tag
result := true;
//showmsg('Success DecodeCSA2');
end else begin
- showmsg('CSAread Warning: only CSA2 format is supported: image is either corruprted, very old or new. See if a new version of this software is available.');
+ dcmMsg('CSAread Warning: '+ lFilename +' at byte '+inttostr(lCSAImageHeaderInfoPos)+' reports version "'+lVers+'": only "SV10" format is supported: image is either corruprted, very old or new. See if a new version of this software is available.');
end;
lData := nil;
end;// func DecodeCSA2
end.
-
+
\ No newline at end of file
diff --git a/dcm2nii/dcm2nii.app/Contents/Info.plist b/dcm2nii/dcm2nii.app/Contents/Info.plist
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2nii.app/Contents/MacOS/dcm2nii b/dcm2nii/dcm2nii.app/Contents/MacOS/dcm2nii
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2nii.app/Contents/PkgInfo b/dcm2nii/dcm2nii.app/Contents/PkgInfo
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2nii.cfg b/dcm2nii/dcm2nii.cfg
old mode 100644
new mode 100755
index b8dce01..5d9b456
--- a/dcm2nii/dcm2nii.cfg
+++ b/dcm2nii/dcm2nii.cfg
@@ -1,4 +1,4 @@
--$A+
+-$A8
-$B-
-$C+
-$D+
@@ -31,7 +31,8 @@
-M
-$M16384,1048576
-K$00400000
--LN"c:\program files\borland\delphi4\Lib"
+-LE"c:\program files (x86)\borland\delphi7\Projects\Bpl"
+-LN"c:\program files (x86)\borland\delphi7\Projects\Bpl"
-U"..\common\;..\delphionly\"
-O"..\common\;..\delphionly\"
-I"..\common\;..\delphionly\"
diff --git a/dcm2nii/dcm2nii.dof b/dcm2nii/dcm2nii.dof
old mode 100644
new mode 100755
index 35e6585..1026d73
--- a/dcm2nii/dcm2nii.dof
+++ b/dcm2nii/dcm2nii.dof
@@ -1,5 +1,7 @@
+[FileVersion]
+Version=7.0
[Compiler]
-A=1
+A=8
B=0
C=1
D=1
@@ -28,6 +30,55 @@ Z=1
ShowHints=1
ShowWarnings=1
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+NamespacePrefix=
+SymbolDeprecated=1
+SymbolLibrary=1
+SymbolPlatform=1
+UnitLibrary=1
+UnitPlatform=1
+UnitDeprecated=1
+HResultCompat=1
+HidingMember=1
+HiddenVirtual=1
+Garbage=1
+BoundsError=1
+ZeroNilCompat=1
+StringConstTruncated=1
+ForLoopVarVarPar=1
+TypedConstVarPar=1
+AsgToTypedConst=1
+CaseLabelRange=1
+ForVariable=1
+ConstructingAbstract=1
+ComparisonFalse=1
+ComparisonTrue=1
+ComparingSignedUnsigned=1
+CombiningSignedUnsigned=1
+UnsupportedConstruct=1
+FileOpen=1
+FileOpenUnitSrc=1
+BadGlobalSymbol=1
+DuplicateConstructorDestructor=1
+InvalidDirective=1
+PackageNoLink=1
+PackageThreadVar=1
+ImplicitImport=1
+HPPEMITIgnored=1
+NoRetVal=1
+UseBeforeDef=1
+ForLoopVarUndef=1
+UnitNameMismatch=1
+NoCFGFileFound=1
+MessageDirective=1
+ImplicitVariants=1
+UnicodeToLocale=1
+LocaleToUnicode=1
+ImagebaseMultiple=1
+SuspiciousTypecast=1
+PrivatePropAccessor=1
+UnsafeType=1
+UnsafeCode=1
+UnsafeCast=1
[Linker]
MapFile=0
OutputObjs=0
@@ -51,6 +102,13 @@ UsePackages=0
[Parameters]
RunParams=
HostApplication=
+Launcher=
+UseLauncher=0
+DebugCWD=
+[Language]
+ActiveLang=
+ProjectLang=
+RootDir=
[Version Info]
IncludeVerInfo=1
AutoIncBuild=0
@@ -74,7 +132,7 @@ LegalCopyright=Copyright
LegalTrademarks=
OriginalFilename=dcm2nii.exe
ProductName=dcm2nii
-ProductVersion=0.0
+ProductVersion=0.0
Comments=
[HistoryLists\hlUnitAliases]
Count=1
diff --git a/dcm2nii/dcm2nii.dpr b/dcm2nii/dcm2nii.dpr
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2nii.ico b/dcm2nii/dcm2nii.ico
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2nii.ini b/dcm2nii/dcm2nii.ini
old mode 100644
new mode 100755
index 4ff9c8c..65f634a
--- a/dcm2nii/dcm2nii.ini
+++ b/dcm2nii/dcm2nii.ini
@@ -28,6 +28,7 @@ UseGE_0021_104F=0
DebugMode=0
UntestedFeatures=0
OrthoFlipXDim=0
+UINT16toFLOAT32=1
[INT]
BeginClip=0
@@ -41,6 +42,7 @@ IgnoreDTIRotationsIf_0018_1020_atleast=15
SiemensDTIUse0019If00181020atleast=15
SiemensDTINoAngulationCorrectionIf00181020atleast=1000
SiemensDTIStackIf00181020atleast=15
+usePigz=0
[STR]
BackupDir=
diff --git a/dcm2nii/dcm2nii.lpi b/dcm2nii/dcm2nii.lpi
old mode 100644
new mode 100755
index 87cedcc..60beb96
--- a/dcm2nii/dcm2nii.lpi
+++ b/dcm2nii/dcm2nii.lpi
@@ -1,431 +1,402 @@
-<?xml version="1.0"?>
-<CONFIG>
- <ProjectOptions>
- <Version Value="9"/>
- <PathDelim Value="\"/>
- <General>
- <Flags>
- <LRSInOutputDirectory Value="False"/>
- </Flags>
- <MainUnit Value="0"/>
- <ActiveWindowIndexAtStart Value="0"/>
- </General>
- <BuildModes Count="1">
- <Item1 Name="default" Default="True"/>
- </BuildModes>
- <PublishOptions>
- <Version Value="2"/>
- <IgnoreBinaries Value="False"/>
- <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
- <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
- </PublishOptions>
- <RunParams>
- <local>
- <FormatVersion Value="1"/>
- <LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
- </local>
- </RunParams>
- <Units Count="30">
- <Unit0>
- <Filename Value="dcm2nii.lpr"/>
- <IsPartOfProject Value="True"/>
- <UnitName Value="dcm2nii"/>
- <EditorIndex Value="0"/>
- <WindowIndex Value="0"/>
- <TopLine Value="19"/>
- <CursorPos X="3" Y="32"/>
- <UsageCount Value="118"/>
- <Loaded Value="True"/>
- <LoadedDesigner Value="True"/>
- </Unit0>
- <Unit1>
- <Filename Value="convert.pas"/>
- <UnitName Value="convert"/>
- <EditorIndex Value="6"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="10"/>
- <UsageCount Value="57"/>
- <Loaded Value="True"/>
- </Unit1>
- <Unit2>
- <Filename Value="define_types.pas"/>
- <UnitName Value="define_types"/>
- <TopLine Value="317"/>
- <CursorPos X="1" Y="330"/>
- <UsageCount Value="57"/>
- </Unit2>
- <Unit3>
- <Filename Value="gzio2.pas"/>
- <UnitName Value="gzio2"/>
- <TopLine Value="1765"/>
- <CursorPos X="7" Y="1784"/>
- <UsageCount Value="57"/>
- </Unit3>
- <Unit4>
- <Filename Value="dicom.pas"/>
- <UnitName Value="dicom"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="1"/>
- <UsageCount Value="57"/>
- </Unit4>
- <Unit5>
- <Filename Value="nodialogs.pas"/>
- <UnitName Value="nodialogs"/>
- <TopLine Value="1"/>
- <CursorPos X="10" Y="5"/>
- <UsageCount Value="54"/>
- </Unit5>
- <Unit6>
- <Filename Value="lsjpeg.pas"/>
- <UnitName Value="lsjpeg"/>
- <EditorIndex Value="8"/>
- <WindowIndex Value="0"/>
- <TopLine Value="711"/>
- <CursorPos X="30" Y="741"/>
- <UsageCount Value="56"/>
- <Loaded Value="True"/>
- </Unit6>
- <Unit7>
- <Filename Value="GraphicsMathLibrary.pas"/>
- <UnitName Value="GraphicsMathLibrary"/>
- <TopLine Value="61"/>
- <CursorPos X="1" Y="66"/>
- <UsageCount Value="54"/>
- </Unit7>
- <Unit8>
- <Filename Value="sortdicom.pas"/>
- <UnitName Value="sortdicom"/>
- <TopLine Value="172"/>
- <CursorPos X="24" Y="188"/>
- <UsageCount Value="57"/>
- </Unit8>
- <Unit9>
- <Filename Value="filename.pas"/>
- <IsPartOfProject Value="True"/>
- <UnitName Value="filename"/>
- <EditorIndex Value="1"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="49" Y="5"/>
- <UsageCount Value="118"/>
- <Loaded Value="True"/>
- </Unit9>
- <Unit10>
- <Filename Value="dicomtypes.pas"/>
- <IsPartOfProject Value="True"/>
- <UnitName Value="dicomtypes"/>
- <TopLine Value="307"/>
- <CursorPos X="42" Y="320"/>
- <UsageCount Value="118"/>
- </Unit10>
- <Unit11>
- <Filename Value="parconvert.pas"/>
- <UnitName Value="parconvert"/>
- <TopLine Value="1188"/>
- <CursorPos X="44" Y="1199"/>
- <UsageCount Value="57"/>
- </Unit11>
- <Unit12>
- <Filename Value="..\..\junk\unit1.pas"/>
- <ComponentName Value="Form1"/>
- <HasResources Value="True"/>
- <UnitName Value="Unit1"/>
- <TopLine Value="1"/>
- <CursorPos X="36" Y="7"/>
- <UsageCount Value="3"/>
- </Unit12>
- <Unit13>
- <Filename Value="nii4Dto3D.pas"/>
- <UnitName Value="nii4dto3d"/>
- <TopLine Value="114"/>
- <CursorPos X="53" Y="125"/>
- <UsageCount Value="11"/>
- </Unit13>
- <Unit14>
- <Filename Value="dicomfast.pas"/>
- <UnitName Value="dicomfast"/>
- <WindowIndex Value="0"/>
- <TopLine Value="4"/>
- <CursorPos X="6" Y="14"/>
- <UsageCount Value="11"/>
- </Unit14>
- <Unit15>
- <Filename Value="dicomcompat.pas"/>
- <UnitName Value="dicomcompat"/>
- <TopLine Value="5888"/>
- <CursorPos X="31" Y="5918"/>
- <UsageCount Value="11"/>
- </Unit15>
- <Unit16>
- <Filename Value="dialogsx.pas"/>
- <UnitName Value="dialogsx"/>
- <TopLine Value="1"/>
- <CursorPos X="10" Y="2"/>
- <UsageCount Value="11"/>
- </Unit16>
- <Unit17>
- <Filename Value="nii_4dto3d.pas"/>
- <UnitName Value="nii_4dto3d"/>
- <TopLine Value="113"/>
- <CursorPos X="53" Y="124"/>
- <UsageCount Value="11"/>
- </Unit17>
- <Unit18>
- <Filename Value="nii_orient.pas"/>
- <UnitName Value="nii_orient"/>
- <EditorIndex Value="2"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="65" Y="4"/>
- <UsageCount Value="11"/>
- <Loaded Value="True"/>
- </Unit18>
- <Unit19>
- <Filename Value="nii_crop.pas"/>
- <UnitName Value="nii_crop"/>
- <TopLine Value="1"/>
- <CursorPos X="6" Y="2"/>
- <UsageCount Value="11"/>
- </Unit19>
- <Unit20>
- <Filename Value="paramstrs.pas"/>
- <UnitName Value="paramstrs"/>
- <IsVisibleTab Value="True"/>
- <EditorIndex Value="7"/>
- <WindowIndex Value="0"/>
- <TopLine Value="169"/>
- <CursorPos X="29" Y="17"/>
- <UsageCount Value="11"/>
- <Loaded Value="True"/>
- </Unit20>
- <Unit21>
- <Filename Value="readint.pas"/>
- <UnitName Value="readint"/>
- <TopLine Value="1"/>
- <CursorPos X="13" Y="6"/>
- <UsageCount Value="10"/>
- </Unit21>
- <Unit22>
- <Filename Value="userdir.pas"/>
- <UnitName Value="userdir"/>
- <TopLine Value="1"/>
- <CursorPos X="31" Y="13"/>
- <UsageCount Value="10"/>
- </Unit22>
- <Unit23>
- <Filename Value="..\common\isgui.inc"/>
- <EditorIndex Value="9"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="13" Y="1"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
- </Unit23>
- <Unit24>
- <Filename Value="..\common\define_types.pas"/>
- <UnitName Value="define_types"/>
- <EditorIndex Value="5"/>
- <WindowIndex Value="0"/>
- <TopLine Value="2"/>
- <CursorPos X="7" Y="11"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
- </Unit24>
- <Unit25>
- <Filename Value="..\common\gzio2.pas"/>
- <UnitName Value="gzio2"/>
- <TopLine Value="1809"/>
- <CursorPos X="35" Y="1849"/>
- <UsageCount Value="10"/>
- </Unit25>
- <Unit26>
- <Filename Value="..\common\GraphicsMathLibrary.pas"/>
- <UnitName Value="GraphicsMathLibrary"/>
- <TopLine Value="547"/>
- <CursorPos X="35" Y="552"/>
- <UsageCount Value="10"/>
- </Unit26>
- <Unit27>
- <Filename Value="..\common\dialogsx.pas"/>
- <UnitName Value="dialogsx"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="1"/>
- <UsageCount Value="10"/>
- </Unit27>
- <Unit28>
- <Filename Value="prefs.pas"/>
- <UnitName Value="prefs"/>
- <EditorIndex Value="3"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="24" Y="3"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
- </Unit28>
- <Unit29>
- <Filename Value="..\common\userdir.pas"/>
- <UnitName Value="userdir"/>
- <EditorIndex Value="4"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="1"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
- </Unit29>
- </Units>
- <JumpHistory Count="30" HistoryIndex="29">
- <Position1>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="228" Column="25" TopLine="203"/>
- </Position1>
- <Position2>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="231" Column="20" TopLine="217"/>
- </Position2>
- <Position3>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="253" Column="32" TopLine="239"/>
- </Position3>
- <Position4>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="259" Column="21" TopLine="239"/>
- </Position4>
- <Position5>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="266" Column="33" TopLine="239"/>
- </Position5>
- <Position6>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="280" Column="20" TopLine="266"/>
- </Position6>
- <Position7>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="9" Column="118" TopLine="1"/>
- </Position7>
- <Position8>
- <Filename Value="prefs.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position8>
- <Position9>
- <Filename Value="prefs.pas"/>
- <Caret Line="6" Column="5" TopLine="1"/>
- </Position9>
- <Position10>
- <Filename Value="prefs.pas"/>
- <Caret Line="7" Column="26" TopLine="1"/>
- </Position10>
- <Position11>
- <Filename Value="..\common\userdir.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position11>
- <Position12>
- <Filename Value="filename.pas"/>
- <Caret Line="202" Column="54" TopLine="163"/>
- </Position12>
- <Position13>
- <Filename Value="filename.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position13>
- <Position14>
- <Filename Value="prefs.pas"/>
- <Caret Line="3" Column="2" TopLine="1"/>
- </Position14>
- <Position15>
- <Filename Value="..\common\userdir.pas"/>
- <Caret Line="10" Column="39" TopLine="1"/>
- </Position15>
- <Position16>
- <Filename Value="..\common\userdir.pas"/>
- <Caret Line="35" Column="58" TopLine="1"/>
- </Position16>
- <Position17>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="11" Column="21" TopLine="1"/>
- </Position17>
- <Position18>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="20" Column="45" TopLine="1"/>
- </Position18>
- <Position19>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="2" Column="25" TopLine="1"/>
- </Position19>
- <Position20>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="10" Column="29" TopLine="1"/>
- </Position20>
- <Position21>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position21>
- <Position22>
- <Filename Value="dcm2nii.lpr"/>
- <Caret Line="16" Column="31" TopLine="1"/>
- </Position22>
- <Position23>
- <Filename Value="paramstrs.pas"/>
- <Caret Line="13" Column="1" TopLine="4"/>
- </Position23>
- <Position24>
- <Filename Value="dcm2nii.lpr"/>
- <Caret Line="66" Column="1" TopLine="40"/>
- </Position24>
- <Position25>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="9" Column="45" TopLine="1"/>
- </Position25>
- <Position26>
- <Filename Value="filename.pas"/>
- <Caret Line="11" Column="22" TopLine="1"/>
- </Position26>
- <Position27>
- <Filename Value="filename.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position27>
- <Position28>
- <Filename Value="prefs.pas"/>
- <Caret Line="3" Column="24" TopLine="1"/>
- </Position28>
- <Position29>
- <Filename Value="filename.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position29>
- <Position30>
- <Filename Value="paramstrs.pas"/>
- <Caret Line="18" Column="28" TopLine="1"/>
- </Position30>
- </JumpHistory>
- </ProjectOptions>
- <CompilerOptions>
- <Version Value="9"/>
- <PathDelim Value="\"/>
- <SearchPaths>
- <OtherUnitFiles Value="..\common"/>
- </SearchPaths>
- <Parsing>
- <SyntaxOptions>
- <UseAnsiStrings Value="False"/>
- </SyntaxOptions>
- </Parsing>
- <CodeGeneration>
- <Optimizations>
- <OptimizationLevel Value="2"/>
- </Optimizations>
- </CodeGeneration>
- <Linking>
- <Debugging>
- <UseLineInfoUnit Value="False"/>
- <StripSymbols Value="True"/>
- </Debugging>
- <LinkSmart Value="True"/>
- </Linking>
- <Other>
- <ConfigFile>
- <CustomConfigFile Value="True"/>
- </ConfigFile>
- <CompilerPath Value="$(CompPath)"/>
- </Other>
- </CompilerOptions>
-</CONFIG>
\ No newline at end of file
+<?xml version="1.0"?>
+<CONFIG>
+ <ProjectOptions>
+ <Version Value="9"/>
+ <PathDelim Value="\"/>
+ <General>
+ <Flags>
+ <LRSInOutputDirectory Value="False"/>
+ </Flags>
+ <MainUnit Value="0"/>
+ <ActiveWindowIndexAtStart Value="0"/>
+ </General>
+ <BuildModes Count="1">
+ <Item1 Name="default" Default="True"/>
+ </BuildModes>
+ <PublishOptions>
+ <Version Value="2"/>
+ <IgnoreBinaries Value="False"/>
+ <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+ <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ <LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+ </local>
+ </RunParams>
+ <Units Count="32">
+ <Unit0>
+ <Filename Value="dcm2nii.lpr"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="dcm2nii"/>
+ <EditorIndex Value="0"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="75" Y="1"/>
+ <UsageCount Value="120"/>
+ <Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
+ </Unit0>
+ <Unit1>
+ <Filename Value="convert.pas"/>
+ <UnitName Value="convert"/>
+ <EditorIndex Value="6"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1286"/>
+ <CursorPos X="18" Y="1315"/>
+ <UsageCount Value="57"/>
+ <Loaded Value="True"/>
+ </Unit1>
+ <Unit2>
+ <Filename Value="define_types.pas"/>
+ <UnitName Value="define_types"/>
+ <TopLine Value="317"/>
+ <CursorPos X="1" Y="330"/>
+ <UsageCount Value="57"/>
+ </Unit2>
+ <Unit3>
+ <Filename Value="gzio2.pas"/>
+ <UnitName Value="gzio2"/>
+ <TopLine Value="1765"/>
+ <CursorPos X="7" Y="1784"/>
+ <UsageCount Value="57"/>
+ </Unit3>
+ <Unit4>
+ <Filename Value="dicom.pas"/>
+ <UnitName Value="dicom"/>
+ <EditorIndex Value="2"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="15" Y="6"/>
+ <UsageCount Value="57"/>
+ <Loaded Value="True"/>
+ </Unit4>
+ <Unit5>
+ <Filename Value="nodialogs.pas"/>
+ <UnitName Value="nodialogs"/>
+ <TopLine Value="1"/>
+ <CursorPos X="10" Y="5"/>
+ <UsageCount Value="54"/>
+ </Unit5>
+ <Unit6>
+ <Filename Value="lsjpeg.pas"/>
+ <UnitName Value="lsjpeg"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="393"/>
+ <CursorPos X="20" Y="518"/>
+ <UsageCount Value="56"/>
+ </Unit6>
+ <Unit7>
+ <Filename Value="GraphicsMathLibrary.pas"/>
+ <UnitName Value="GraphicsMathLibrary"/>
+ <TopLine Value="61"/>
+ <CursorPos X="1" Y="66"/>
+ <UsageCount Value="54"/>
+ </Unit7>
+ <Unit8>
+ <Filename Value="sortdicom.pas"/>
+ <UnitName Value="sortdicom"/>
+ <TopLine Value="172"/>
+ <CursorPos X="24" Y="188"/>
+ <UsageCount Value="57"/>
+ </Unit8>
+ <Unit9>
+ <Filename Value="filename.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="filename"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="1" Y="1"/>
+ <UsageCount Value="120"/>
+ </Unit9>
+ <Unit10>
+ <Filename Value="dicomtypes.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="dicomtypes"/>
+ <EditorIndex Value="7"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="19"/>
+ <CursorPos X="74" Y="28"/>
+ <UsageCount Value="120"/>
+ <Loaded Value="True"/>
+ </Unit10>
+ <Unit11>
+ <Filename Value="parconvert.pas"/>
+ <UnitName Value="parconvert"/>
+ <TopLine Value="1188"/>
+ <CursorPos X="44" Y="1199"/>
+ <UsageCount Value="57"/>
+ </Unit11>
+ <Unit12>
+ <Filename Value="..\..\junk\unit1.pas"/>
+ <ComponentName Value="Form1"/>
+ <HasResources Value="True"/>
+ <UnitName Value="Unit1"/>
+ <TopLine Value="1"/>
+ <CursorPos X="36" Y="7"/>
+ <UsageCount Value="3"/>
+ </Unit12>
+ <Unit13>
+ <Filename Value="nii4Dto3D.pas"/>
+ <UnitName Value="nii4dto3d"/>
+ <TopLine Value="114"/>
+ <CursorPos X="53" Y="125"/>
+ <UsageCount Value="11"/>
+ </Unit13>
+ <Unit14>
+ <Filename Value="dicomfast.pas"/>
+ <UnitName Value="dicomfast"/>
+ <TopLine Value="4"/>
+ <CursorPos X="6" Y="14"/>
+ <UsageCount Value="11"/>
+ </Unit14>
+ <Unit15>
+ <Filename Value="dicomcompat.pas"/>
+ <UnitName Value="dicomcompat"/>
+ <TopLine Value="5888"/>
+ <CursorPos X="31" Y="5918"/>
+ <UsageCount Value="11"/>
+ </Unit15>
+ <Unit16>
+ <Filename Value="dialogsx.pas"/>
+ <UnitName Value="dialogsx"/>
+ <TopLine Value="1"/>
+ <CursorPos X="10" Y="2"/>
+ <UsageCount Value="11"/>
+ </Unit16>
+ <Unit17>
+ <Filename Value="nii_4dto3d.pas"/>
+ <UnitName Value="nii_4dto3d"/>
+ <TopLine Value="113"/>
+ <CursorPos X="53" Y="124"/>
+ <UsageCount Value="11"/>
+ </Unit17>
+ <Unit18>
+ <Filename Value="nii_orient.pas"/>
+ <UnitName Value="nii_orient"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="39" Y="2"/>
+ <UsageCount Value="11"/>
+ </Unit18>
+ <Unit19>
+ <Filename Value="nii_crop.pas"/>
+ <UnitName Value="nii_crop"/>
+ <TopLine Value="1"/>
+ <CursorPos X="6" Y="2"/>
+ <UsageCount Value="11"/>
+ </Unit19>
+ <Unit20>
+ <Filename Value="paramstrs.pas"/>
+ <UnitName Value="paramstrs"/>
+ <IsVisibleTab Value="True"/>
+ <EditorIndex Value="5"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="37" Y="14"/>
+ <UsageCount Value="11"/>
+ <Loaded Value="True"/>
+ </Unit20>
+ <Unit21>
+ <Filename Value="readint.pas"/>
+ <UnitName Value="readint"/>
+ <TopLine Value="1"/>
+ <CursorPos X="13" Y="6"/>
+ <UsageCount Value="10"/>
+ </Unit21>
+ <Unit22>
+ <Filename Value="userdir.pas"/>
+ <UnitName Value="userdir"/>
+ <TopLine Value="1"/>
+ <CursorPos X="31" Y="13"/>
+ <UsageCount Value="10"/>
+ </Unit22>
+ <Unit23>
+ <Filename Value="..\common\isgui.inc"/>
+ <EditorIndex Value="1"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="13" Y="1"/>
+ <UsageCount Value="10"/>
+ <Loaded Value="True"/>
+ </Unit23>
+ <Unit24>
+ <Filename Value="..\common\define_types.pas"/>
+ <UnitName Value="define_types"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="1" Y="1"/>
+ <UsageCount Value="10"/>
+ </Unit24>
+ <Unit25>
+ <Filename Value="..\common\gzio2.pas"/>
+ <UnitName Value="gzio2"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="12" Y="1881"/>
+ <UsageCount Value="10"/>
+ </Unit25>
+ <Unit26>
+ <Filename Value="..\common\GraphicsMathLibrary.pas"/>
+ <UnitName Value="GraphicsMathLibrary"/>
+ <TopLine Value="547"/>
+ <CursorPos X="35" Y="552"/>
+ <UsageCount Value="10"/>
+ </Unit26>
+ <Unit27>
+ <Filename Value="..\common\dialogsx.pas"/>
+ <UnitName Value="dialogsx"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="53"/>
+ <CursorPos X="18" Y="77"/>
+ <UsageCount Value="10"/>
+ </Unit27>
+ <Unit28>
+ <Filename Value="prefs.pas"/>
+ <UnitName Value="prefs"/>
+ <EditorIndex Value="3"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="25" Y="8"/>
+ <UsageCount Value="10"/>
+ <Loaded Value="True"/>
+ </Unit28>
+ <Unit29>
+ <Filename Value="..\common\userdir.pas"/>
+ <UnitName Value="userdir"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="1" Y="1"/>
+ <UsageCount Value="10"/>
+ </Unit29>
+ <Unit30>
+ <Filename Value="niftiutil.pas"/>
+ <UnitName Value="niftiutil"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="250"/>
+ <CursorPos X="1" Y="279"/>
+ <UsageCount Value="10"/>
+ </Unit30>
+ <Unit31>
+ <Filename Value="gui.pas"/>
+ <ComponentName Value="MainForm"/>
+ <HasResources Value="True"/>
+ <ResourceBaseClass Value="Form"/>
+ <UnitName Value="gui"/>
+ <EditorIndex Value="4"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="13" Y="8"/>
+ <UsageCount Value="10"/>
+ <Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
+ </Unit31>
+ </Units>
+ <JumpHistory Count="19" HistoryIndex="18">
+ <Position1>
+ <Filename Value="dcm2nii.lpr"/>
+ <Caret Line="3" Column="48" TopLine="1"/>
+ </Position1>
+ <Position2>
+ <Filename Value="dcm2nii.lpr"/>
+ <Caret Line="65" Column="27" TopLine="38"/>
+ </Position2>
+ <Position3>
+ <Filename Value="dcm2nii.lpr"/>
+ <Caret Line="29" Column="21" TopLine="1"/>
+ </Position3>
+ <Position4>
+ <Filename Value="dcm2nii.lpr"/>
+ <Caret Line="29" Column="21" TopLine="11"/>
+ </Position4>
+ <Position5>
+ <Filename Value="dcm2nii.lpr"/>
+ <Caret Line="67" Column="16" TopLine="40"/>
+ </Position5>
+ <Position6>
+ <Filename Value="convert.pas"/>
+ <Caret Line="4" Column="85" TopLine="1"/>
+ </Position6>
+ <Position7>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1128" Column="35" TopLine="1114"/>
+ </Position7>
+ <Position8>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1129" Column="33" TopLine="1114"/>
+ </Position8>
+ <Position9>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1294" Column="58" TopLine="1273"/>
+ </Position9>
+ <Position10>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1411" Column="83" TopLine="1383"/>
+ </Position10>
+ <Position11>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1440" Column="83" TopLine="1413"/>
+ </Position11>
+ <Position12>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1441" Column="31" TopLine="1413"/>
+ </Position12>
+ <Position13>
+ <Filename Value="convert.pas"/>
+ <Caret Line="682" Column="6" TopLine="670"/>
+ </Position13>
+ <Position14>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1185" Column="34" TopLine="1176"/>
+ </Position14>
+ <Position15>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1310" Column="13" TopLine="1282"/>
+ </Position15>
+ <Position16>
+ <Filename Value="dicom.pas"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
+ </Position16>
+ <Position17>
+ <Filename Value="dicom.pas"/>
+ <Caret Line="6" Column="15" TopLine="1"/>
+ </Position17>
+ <Position18>
+ <Filename Value="gui.pas"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
+ </Position18>
+ <Position19>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="235" Column="6" TopLine="219"/>
+ </Position19>
+ </JumpHistory>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="9"/>
+ <PathDelim Value="\"/>
+ <SearchPaths>
+ <OtherUnitFiles Value="..\common"/>
+ </SearchPaths>
+ <Parsing>
+ <SyntaxOptions>
+ <UseAnsiStrings Value="False"/>
+ </SyntaxOptions>
+ </Parsing>
+ <CodeGeneration>
+ <Optimizations>
+ <OptimizationLevel Value="2"/>
+ </Optimizations>
+ </CodeGeneration>
+ <Linking>
+ <Debugging>
+ <UseLineInfoUnit Value="False"/>
+ <StripSymbols Value="True"/>
+ </Debugging>
+ <LinkSmart Value="True"/>
+ </Linking>
+ <Other>
+ <CompilerPath Value="$(CompPath)"/>
+ </Other>
+ </CompilerOptions>
+</CONFIG>
diff --git a/dcm2nii/dcm2nii.lpr b/dcm2nii/dcm2nii.lpr
old mode 100644
new mode 100755
index 374e69a..b4f6ff4
--- a/dcm2nii/dcm2nii.lpr
+++ b/dcm2nii/dcm2nii.lpr
@@ -60,7 +60,7 @@ Msg('Finished. Elapsed time: '+inttostr(GetTickCount-Start));
end. *)
begin
- Msg(kVers);
+ ShowMsg(kVers);
kUseDateTimeForID := true;
ProcessParamStrs;
end.
diff --git a/dcm2nii/dcm2nii.or b/dcm2nii/dcm2nii.or
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2nii.rci b/dcm2nii/dcm2nii.rci
deleted file mode 100644
index c008e6b..0000000
--- a/dcm2nii/dcm2nii.rci
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<CONFIG>
- <MainIcon Enabled="True" Filename="C:\lazarus\dcm2nii\dcm2nii.ico"/>
- <XPManifest Enabled="False"/>
- <VersionInfo Enabled="True" CompanyName="Chris Rorden" OrigFilename="dcm2nii.exe" FVMajor="0" FVMinor="9" FVBuildMajor="0" FVBuildMinor="0" ProductName="dcm2nii" FileDescription="DICOM and PAR/REC converter" PVMajor="0" PVMinor="0" PVExtra="" Copyright="Copyright �" AutoIncrement="False"/>
-</CONFIG>
diff --git a/dcm2nii/dcm2nii.res b/dcm2nii/dcm2nii.res
old mode 100644
new mode 100755
index 081f349..c7fb1f5
Binary files a/dcm2nii/dcm2nii.res and b/dcm2nii/dcm2nii.res differ
diff --git a/dcm2nii/dcm2nii48.ico b/dcm2nii/dcm2nii48.ico
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2niigui.app/Contents/MacOS/dcm2niigui b/dcm2nii/dcm2niigui.app/Contents/MacOS/dcm2niigui
deleted file mode 100644
index eb6cf9b..0000000
--- a/dcm2nii/dcm2niigui.app/Contents/MacOS/dcm2niigui
+++ /dev/null
@@ -1 +0,0 @@
-../../../dcm2niigui
\ No newline at end of file
diff --git a/dcm2nii/dcm2niigui.cfg b/dcm2nii/dcm2niigui.cfg
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2niigui.dof b/dcm2nii/dcm2niigui.dof
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2niigui.dpr b/dcm2nii/dcm2niigui.dpr
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2niigui.ico b/dcm2nii/dcm2niigui.ico
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2niigui.ini b/dcm2nii/dcm2niigui.ini
old mode 100644
new mode 100755
index cf8f638..99e6b8a
--- a/dcm2nii/dcm2niigui.ini
+++ b/dcm2nii/dcm2niigui.ini
@@ -18,7 +18,7 @@ enablereorient=1
OrthoFlipXDim=0
EveryFile=1
fourD=1
-Gzip=0
+Gzip=1
ManualNIfTIConv=1
PhilipsPrecise=0
RecursiveUseNameAppend=0
@@ -29,6 +29,9 @@ Swizzle4D=1
UseGE_0021_104F=0
[INT]
+BeginClip=0
+LastClip=0
+usePigz=1
MaxReorientMatrix=1023
MinReorientMatrix=200
RecursiveFolderDepth=5
@@ -39,3 +42,4 @@ SiemensDTIStackIf00181020atleast=15
[STR]
OutDir=C:\Users\neuropsych\Documents
+
diff --git a/dcm2nii/dcm2niigui.lpi b/dcm2nii/dcm2niigui.lpi
old mode 100644
new mode 100755
index 8f3b0a2..ba35aaa
--- a/dcm2nii/dcm2niigui.lpi
+++ b/dcm2nii/dcm2niigui.lpi
@@ -13,9 +13,6 @@
<Icon Value="0"/>
<ActiveWindowIndexAtStart Value="0"/>
</General>
- <VersionInfo>
- <StringTable ProductVersion=""/>
- </VersionInfo>
<BuildModes Count="1">
<Item1 Name="default" Default="True"/>
</BuildModes>
@@ -36,45 +33,45 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
- <Units Count="44">
+ <Units Count="50">
<Unit0>
<Filename Value="dcm2niigui.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="dcm2niigui"/>
- <WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="2" Y="1"/>
- <UsageCount Value="58"/>
+ <UsageCount Value="104"/>
</Unit0>
<Unit1>
<Filename Value="gui.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
+ <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="gui"/>
- <EditorIndex Value="0"/>
<WindowIndex Value="0"/>
- <TopLine Value="1115"/>
- <CursorPos X="7" Y="1122"/>
- <UsageCount Value="58"/>
- <Loaded Value="True"/>
- <LoadedDesigner Value="True"/>
+ <TopLine Value="41"/>
+ <CursorPos X="18" Y="486"/>
+ <UsageCount Value="104"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
<Filename Value="dcm2niigui.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="5"/>
</Unit2>
<Unit3>
<Filename Value="nifti_form.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="NIfTIForm"/>
+ <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="nifti_form"/>
- <TopLine Value="1"/>
- <CursorPos X="102" Y="2"/>
- <UsageCount Value="58"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="65"/>
+ <CursorPos X="37" Y="10"/>
+ <UsageCount Value="104"/>
</Unit3>
<Unit4>
<Filename Value="pref_form.pas"/>
@@ -84,269 +81,312 @@
<UnitName Value="pref_form"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="101" Y="146"/>
- <UsageCount Value="58"/>
+ <CursorPos X="1" Y="10"/>
+ <UsageCount Value="104"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
<Filename Value="parconvert.pas"/>
<UnitName Value="parconvert"/>
- <TopLine Value="91"/>
- <CursorPos X="13" Y="93"/>
- <UsageCount Value="16"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="128" Y="6"/>
+ <UsageCount Value="21"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
<Filename Value="pref_form.lrs"/>
<TopLine Value="1"/>
<CursorPos X="4" Y="36"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="6"/>
</Unit6>
<Unit7>
<Filename Value="..\..\lcl\lresources.pp"/>
<UnitName Value="LResources"/>
<TopLine Value="2628"/>
<CursorPos X="21" Y="2642"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="5"/>
</Unit7>
<Unit8>
<Filename Value="dialogsx.pas"/>
<UnitName Value="dialogsx"/>
<TopLine Value="1"/>
<CursorPos X="33" Y="9"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="6"/>
</Unit8>
<Unit9>
<Filename Value="readint.pas"/>
<UnitName Value="readint"/>
<TopLine Value="1"/>
<CursorPos X="15" Y="7"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="6"/>
</Unit9>
<Unit10>
<Filename Value="readint.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="6"/>
</Unit10>
<Unit11>
<Filename Value="usr\local\share\lazarus\lcl\nonwin32\messages.pp"/>
<UnitName Value="Messages"/>
<TopLine Value="1"/>
<CursorPos X="90" Y="12"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="5"/>
</Unit11>
<Unit12>
<Filename Value="define_types.pas"/>
<UnitName Value="define_types"/>
<TopLine Value="1"/>
<CursorPos X="40" Y="2"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="6"/>
</Unit12>
<Unit13>
<Filename Value="paramstrs.pas"/>
<UnitName Value="paramstrs"/>
+ <EditorIndex Value="7"/>
<WindowIndex Value="0"/>
- <TopLine Value="75"/>
- <CursorPos X="99" Y="92"/>
- <UsageCount Value="20"/>
+ <TopLine Value="181"/>
+ <CursorPos X="33" Y="194"/>
+ <UsageCount Value="17"/>
+ <Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit13>
<Unit14>
<Filename Value="niftiutil.pas"/>
<UnitName Value="niftiutil"/>
<WindowIndex Value="0"/>
- <TopLine Value="162"/>
- <CursorPos X="1" Y="155"/>
- <UsageCount Value="19"/>
+ <TopLine Value="260"/>
+ <CursorPos X="10" Y="274"/>
+ <UsageCount Value="16"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit14>
<Unit15>
<Filename Value="prefs.pas"/>
<UnitName Value="prefs"/>
<WindowIndex Value="0"/>
- <TopLine Value="184"/>
- <CursorPos X="66" Y="210"/>
- <UsageCount Value="20"/>
+ <TopLine Value="186"/>
+ <CursorPos X="9" Y="199"/>
+ <UsageCount Value="21"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit15>
<Unit16>
<Filename Value="dicom.pas"/>
<UnitName Value="dicom"/>
+ <EditorIndex Value="9"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="13"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="12"/>
+ <Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit16>
<Unit17>
<Filename Value="dicomtypes.pas"/>
<UnitName Value="dicomtypes"/>
- <EditorIndex Value="8"/>
+ <EditorIndex Value="4"/>
<WindowIndex Value="0"/>
- <TopLine Value="623"/>
- <CursorPos X="26" Y="653"/>
- <UsageCount Value="13"/>
+ <TopLine Value="7"/>
+ <CursorPos X="15" Y="638"/>
+ <UsageCount Value="32"/>
<Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit17>
<Unit18>
<Filename Value="filename.pas"/>
<UnitName Value="filename"/>
- <WindowIndex Value="0"/>
<TopLine Value="118"/>
<CursorPos X="55" Y="131"/>
- <UsageCount Value="14"/>
+ <UsageCount Value="11"/>
</Unit18>
<Unit19>
<Filename Value="userdir.pas"/>
<UnitName Value="userdir"/>
- <EditorIndex Value="6"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="21" Y="11"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <CursorPos X="1" Y="3"/>
+ <UsageCount Value="7"/>
</Unit19>
<Unit20>
<Filename Value="gzio2.pas"/>
<UnitName Value="gzio2"/>
<TopLine Value="762"/>
<CursorPos X="26" Y="788"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="5"/>
</Unit20>
<Unit21>
<Filename Value="nii_crop.pas"/>
<UnitName Value="nii_crop"/>
- <TopLine Value="36"/>
- <CursorPos X="1" Y="1"/>
- <UsageCount Value="8"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="31" Y="26"/>
+ <UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit21>
<Unit22>
<Filename Value="..\common\userdir.pas"/>
<UnitName Value="userdir"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="15"/>
- <UsageCount Value="14"/>
+ <UsageCount Value="11"/>
</Unit22>
<Unit23>
<Filename Value="..\common\define_types.pas"/>
<UnitName Value="define_types"/>
- <EditorIndex Value="7"/>
+ <IsVisibleTab Value="True"/>
+ <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="23" Y="21"/>
- <UsageCount Value="18"/>
+ <TopLine Value="6"/>
+ <CursorPos X="28" Y="21"/>
+ <UsageCount Value="35"/>
<Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit23>
<Unit24>
<Filename Value="..\common\gziod.pas"/>
<UnitName Value="gziod"/>
<TopLine Value="311"/>
<CursorPos X="98" Y="322"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="5"/>
</Unit24>
<Unit25>
<Filename Value="convert.pas"/>
<UnitName Value="convert"/>
- <EditorIndex Value="4"/>
+ <EditorIndex Value="5"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="49" Y="14"/>
- <UsageCount Value="17"/>
+ <TopLine Value="899"/>
+ <CursorPos X="154" Y="904"/>
+ <UsageCount Value="38"/>
<Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit25>
<Unit26>
<Filename Value="..\common\gzio2.pas"/>
<UnitName Value="gzio2"/>
+ <EditorIndex Value="0"/>
<WindowIndex Value="0"/>
- <TopLine Value="647"/>
- <CursorPos X="8" Y="667"/>
- <UsageCount Value="11"/>
+ <TopLine Value="53"/>
+ <CursorPos X="1" Y="71"/>
+ <UsageCount Value="12"/>
+ <Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit26>
<Unit27>
<Filename Value="nii_asl.pas"/>
<UnitName Value="nii_asl"/>
- <TopLine Value="96"/>
- <CursorPos X="7" Y="212"/>
- <UsageCount Value="8"/>
+ <EditorIndex Value="8"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="525"/>
+ <CursorPos X="42" Y="539"/>
+ <UsageCount Value="10"/>
+ <Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit27>
<Unit28>
<Filename Value="..\common\GraphicsMathLibrary.pas"/>
<UnitName Value="GraphicsMathLibrary"/>
+ <WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="10" Y="27"/>
- <UsageCount Value="8"/>
+ <CursorPos X="25" Y="9"/>
+ <UsageCount Value="13"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit28>
<Unit29>
<Filename Value="..\common\dialogsx.pas"/>
<UnitName Value="dialogsx"/>
- <TopLine Value="1"/>
- <CursorPos X="33" Y="2"/>
- <UsageCount Value="16"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="53"/>
+ <CursorPos X="52" Y="60"/>
+ <UsageCount Value="32"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit29>
<Unit30>
<Filename Value="LibTar.pas"/>
<UnitName Value="LibTar"/>
<TopLine Value="246"/>
<CursorPos X="35" Y="272"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="5"/>
</Unit30>
<Unit31>
<Filename Value="untar.pas"/>
<UnitName Value="untar"/>
- <TopLine Value="8"/>
- <CursorPos X="38" Y="12"/>
- <UsageCount Value="8"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="44" Y="11"/>
+ <UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit31>
<Unit32>
<Filename Value="dicomfastread.pas"/>
<UnitName Value="dicomfastread"/>
- <TopLine Value="427"/>
- <CursorPos X="15" Y="435"/>
- <UsageCount Value="8"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="27" Y="26"/>
+ <UsageCount Value="19"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit32>
<Unit33>
<Filename Value="dicomcompat.pas"/>
<UnitName Value="dicomcompat"/>
- <EditorIndex Value="3"/>
+ <EditorIndex Value="1"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="95" Y="11"/>
- <UsageCount Value="19"/>
+ <TopLine Value="3104"/>
+ <CursorPos X="24" Y="3104"/>
+ <UsageCount Value="41"/>
<Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit33>
<Unit34>
<Filename Value="lsjpeg.pas"/>
<UnitName Value="lsjpeg"/>
- <TopLine Value="4"/>
- <CursorPos X="92" Y="13"/>
- <UsageCount Value="16"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="22" Y="10"/>
+ <UsageCount Value="13"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit34>
<Unit35>
<Filename Value="sortdicom.pas"/>
<UnitName Value="sortdicom"/>
- <TopLine Value="399"/>
- <CursorPos X="6" Y="411"/>
- <UsageCount Value="16"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="93" Y="7"/>
+ <UsageCount Value="13"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit35>
<Unit36>
- <Filename Value=""/>
- <UsageCount Value="10"/>
- <DefaultSyntaxHighlighter Value="None"/>
+ <Filename Value="philips_bvec.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="philips_bvec"/>
+ <EditorIndex Value="6"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="153"/>
+ <CursorPos X="80" Y="167"/>
+ <UsageCount Value="59"/>
+ <Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit36>
<Unit37>
<Filename Value="nii_orient.pas"/>
<UnitName Value="nii_orient"/>
- <TopLine Value="6"/>
- <CursorPos X="36" Y="9"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="83" Y="9"/>
<UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit37>
<Unit38>
<Filename Value="gui.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="3"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="7"/>
</Unit38>
<Unit39>
<Filename Value="nii_math.pas"/>
<UnitName Value="nii_math"/>
<TopLine Value="576"/>
<CursorPos X="78" Y="592"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="7"/>
</Unit39>
<Unit40>
<Filename Value="C:\Documents and Settings\chris\Desktop\scripter\unit1.pas"/>
@@ -355,175 +395,230 @@
<UnitName Value="Unit1"/>
<TopLine Value="34"/>
<CursorPos X="1" Y="35"/>
- <UsageCount Value="20"/>
+ <UsageCount Value="17"/>
</Unit40>
<Unit41>
<Filename Value="..\common\nifti_hdr.pas"/>
<UnitName Value="nifti_hdr"/>
- <EditorIndex Value="1"/>
<WindowIndex Value="0"/>
- <TopLine Value="299"/>
+ <TopLine Value="1"/>
<CursorPos X="25" Y="310"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <UsageCount Value="7"/>
</Unit41>
<Unit42>
<Filename Value="..\common\isgui.inc"/>
- <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="10" Y="1"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <UsageCount Value="27"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit42>
<Unit43>
<Filename Value="csaread.pas"/>
<UnitName Value="csaread"/>
- <IsVisibleTab Value="True"/>
- <EditorIndex Value="5"/>
+ <EditorIndex Value="3"/>
<WindowIndex Value="0"/>
- <TopLine Value="211"/>
- <CursorPos X="32" Y="236"/>
- <UsageCount Value="10"/>
+ <TopLine Value="22"/>
+ <CursorPos X="61" Y="35"/>
+ <UsageCount Value="27"/>
<Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit43>
+ <Unit44>
+ <Filename Value="dialogs_msg.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="dialogs_msg"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="17" Y="1"/>
+ <UsageCount Value="23"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit44>
+ <Unit45>
+ <Filename Value="nii_4dto3d.pas"/>
+ <UnitName Value="nii_4dto3d"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="26" Y="19"/>
+ <UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit45>
+ <Unit46>
+ <Filename Value="convertsimple.pas"/>
+ <UnitName Value="convertsimple"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="26" Y="11"/>
+ <UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit46>
+ <Unit47>
+ <Filename Value="dicomfast.pas"/>
+ <UnitName Value="dicomfast"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="56" Y="21"/>
+ <UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit47>
+ <Unit48>
+ <Filename Value="nii_reslice.pas"/>
+ <UnitName Value="nii_reslice"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="65" Y="5"/>
+ <UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit48>
+ <Unit49>
+ <Filename Value="nii_3dto4d.pas"/>
+ <UnitName Value="nii_3dto4d"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="71" Y="9"/>
+ <UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit49>
</Units>
- <JumpHistory Count="29" HistoryIndex="28">
+ <JumpHistory Count="30" HistoryIndex="29">
<Position1>
- <Filename Value="gui.pas"/>
- <Caret Line="433" Column="3" TopLine="412"/>
+ <Filename Value="dicomcompat.pas"/>
+ <Caret Line="3209" Column="39" TopLine="3178"/>
</Position1>
<Position2>
- <Filename Value="gui.pas"/>
- <Caret Line="779" Column="25" TopLine="767"/>
+ <Filename Value="dicomcompat.pas"/>
+ <Caret Line="3220" Column="42" TopLine="3189"/>
</Position2>
<Position3>
- <Filename Value="gui.pas"/>
- <Caret Line="784" Column="22" TopLine="775"/>
+ <Filename Value="dicomcompat.pas"/>
+ <Caret Line="3892" Column="73" TopLine="3862"/>
</Position3>
<Position4>
- <Filename Value="..\common\nifti_hdr.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="dicomcompat.pas"/>
+ <Caret Line="3902" Column="53" TopLine="3872"/>
</Position4>
<Position5>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="203" Column="75" TopLine="193"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="264" Column="78" TopLine="263"/>
</Position5>
<Position6>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="1510" Column="22" TopLine="1493"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1360" Column="57" TopLine="1330"/>
</Position6>
<Position7>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="1543" Column="89" TopLine="1535"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1" Column="142" TopLine="1"/>
</Position7>
<Position8>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="1548" Column="95" TopLine="1535"/>
+ <Caret Line="3874" Column="107" TopLine="3873"/>
</Position8>
<Position9>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="1637" Column="59" TopLine="1621"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="825" Column="46" TopLine="797"/>
</Position9>
<Position10>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="3181" Column="39" TopLine="3174"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="826" Column="146" TopLine="797"/>
</Position10>
<Position11>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="3191" Column="42" TopLine="3180"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="899" Column="146" TopLine="868"/>
</Position11>
<Position12>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="3870" Column="11" TopLine="3853"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="133" Column="16" TopLine="122"/>
</Position12>
<Position13>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="3871" Column="25" TopLine="3853"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="6" Column="12" TopLine="1"/>
</Position13>
<Position14>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="4769" Column="40" TopLine="4745"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="127" Column="47" TopLine="112"/>
</Position14>
<Position15>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="4773" Column="40" TopLine="4745"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="161" Column="57" TopLine="132"/>
</Position15>
<Position16>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="4774" Column="55" TopLine="4746"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="142" Column="10" TopLine="128"/>
</Position16>
<Position17>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="5272" Column="41" TopLine="5244"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="135" Column="25" TopLine="113"/>
</Position17>
<Position18>
- <Filename Value="gui.pas"/>
- <Caret Line="4" Column="33" TopLine="1"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="126" Column="6" TopLine="112"/>
</Position18>
<Position19>
- <Filename Value="gui.pas"/>
- <Caret Line="12" Column="34" TopLine="1"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="129" Column="9" TopLine="115"/>
</Position19>
<Position20>
- <Filename Value="gui.pas"/>
- <Caret Line="809" Column="70" TopLine="776"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="6" Column="5" TopLine="1"/>
</Position20>
<Position21>
- <Filename Value="gui.pas"/>
- <Caret Line="840" Column="46" TopLine="810"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="149" Column="39" TopLine="134"/>
</Position21>
<Position22>
- <Filename Value="gui.pas"/>
- <Caret Line="841" Column="38" TopLine="811"/>
+ <Filename Value="philips_bvec.pas"/>
+ <Caret Line="167" Column="132" TopLine="148"/>
</Position22>
<Position23>
- <Filename Value="userdir.pas"/>
- <Caret Line="45" Column="64" TopLine="32"/>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="238" Column="1" TopLine="231"/>
</Position23>
<Position24>
- <Filename Value="dicomtypes.pas"/>
- <Caret Line="618" Column="9" TopLine="605"/>
+ <Filename Value="nii_asl.pas"/>
+ <Caret Line="9" Column="3" TopLine="3"/>
</Position24>
<Position25>
- <Filename Value="dicomtypes.pas"/>
- <Caret Line="626" Column="26" TopLine="605"/>
+ <Filename Value="nii_asl.pas"/>
+ <Caret Line="535" Column="49" TopLine="521"/>
</Position25>
<Position26>
- <Filename Value="dicomtypes.pas"/>
- <Caret Line="627" Column="26" TopLine="605"/>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="193" Column="9" TopLine="174"/>
</Position26>
<Position27>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="5277" Column="26" TopLine="5266"/>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="14" Column="1" TopLine="2"/>
</Position27>
<Position28>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="6293" Column="30" TopLine="6275"/>
+ <Caret Line="3" Column="116" TopLine="1"/>
</Position28>
<Position29>
- <Filename Value="csaread.pas"/>
- <Caret Line="16" Column="19" TopLine="1"/>
+ <Filename Value="dicomcompat.pas"/>
+ <Caret Line="5067" Column="76" TopLine="5052"/>
</Position29>
+ <Position30>
+ <Filename Value="csaread.pas"/>
+ <Caret Line="38" Column="131" TopLine="24"/>
+ </Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
- <Version Value="9"/>
+ <Version Value="11"/>
<PathDelim Value="\"/>
- <Target>
- <Filename ApplyConventions="False"/>
- </Target>
<SearchPaths>
<OtherUnitFiles Value="..\common"/>
- <SrcPath Value="C:\lazarus\ideintf\"/>
+ <SrcPath Value="C:\lazarus\ideintf"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
+ <SyntaxMode Value="Delphi"/>
<UseAnsiStrings Value="False"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Debugging>
+ <GenerateDebugInfo Value="False"/>
<UseLineInfoUnit Value="False"/>
<StripSymbols Value="True"/>
</Debugging>
diff --git a/dcm2nii/dcm2niigui.lpr b/dcm2nii/dcm2niigui.lpr
old mode 100644
new mode 100755
index 5c96ba0..9d3edd5
--- a/dcm2nii/dcm2niigui.lpr
+++ b/dcm2nii/dcm2niigui.lpr
@@ -7,7 +7,7 @@ uses
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
- Forms, gui, nifti_form, pref_form;
+ Forms, gui, nifti_form, pref_form, dialogs_msg;
diff --git a/dcm2nii/dcm2niigui.lrs b/dcm2nii/dcm2niigui.lrs
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2niigui.manifest b/dcm2nii/dcm2niigui.manifest
new file mode 100755
index 0000000..07fb624
--- /dev/null
+++ b/dcm2nii/dcm2niigui.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="CompanyName.ProductName.YourApp" type="win32"/>
+ <description>Your application description here.</description>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
+ </dependentAssembly>
+ </dependency>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
\ No newline at end of file
diff --git a/dcm2nii/dcm2niigui.or b/dcm2nii/dcm2niigui.or
old mode 100644
new mode 100755
index e4e0f9e..4a3628d
Binary files a/dcm2nii/dcm2niigui.or and b/dcm2nii/dcm2niigui.or differ
diff --git a/dcm2nii/dcm2niigui.rc b/dcm2nii/dcm2niigui.rc
old mode 100644
new mode 100755
index eb3c4f5..71b1938
--- a/dcm2nii/dcm2niigui.rc
+++ b/dcm2nii/dcm2niigui.rc
@@ -1 +1,7 @@
+#define RT_MANIFEST 24
+#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
+#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2
+#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3
+
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "dcm2niigui.manifest"
MAINICON ICON "dcm2niigui.ico"
diff --git a/dcm2nii/dcm2niigui.res b/dcm2nii/dcm2niigui.res
old mode 100644
new mode 100755
diff --git a/dcm2nii/dialogs_msg.pas b/dcm2nii/dialogs_msg.pas
new file mode 100755
index 0000000..03656ce
--- /dev/null
+++ b/dcm2nii/dialogs_msg.pas
@@ -0,0 +1,27 @@
+unit dialogs_msg;
+{$ifdef fpc}{$mode delphi}{$endif}
+{$Include ..\common\isgui.inc}
+interface
+ //this wrapper sends text to the main form memo for GUI applications and to the terminal for console applications
+uses
+ Classes, SysUtils;
+
+procedure dcmMsg (lStr: string);
+
+implementation
+{$IFDEF GUI}
+uses gui;
+{$ENDIF}
+
+procedure dcmMsg (lStr: string);
+begin
+{$IFDEF GUI}
+ MainForm.Memo1.Lines.Add(lStr);
+ MainForm.refresh;
+{$ELSE}
+ writeln(lStr)
+{$ENDIF}
+end;
+
+end.
+
diff --git a/dcm2nii/dicom.pas b/dcm2nii/dicom.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/dicomcompat.pas b/dcm2nii/dicomcompat.pas
old mode 100644
new mode 100755
index 2f3a5f6..9233356
--- a/dcm2nii/dicomcompat.pas
+++ b/dcm2nii/dicomcompat.pas
@@ -1,14 +1,17 @@
unit dicomcompat;
interface
uses
-{$Define NoTroubleshoot}
+//{$Define Troubleshoot}
+{$DEFINE read00189117} //Support Philips shameful DTI usage
+{$DEFINE read20011003} //Support Philips Shameful DTI usage
+
{$IFDEF FPC}
gzio2,
{$ELSE}
gziod,
{$ENDIF}
- SysUtils,Classes,define_types,filename,dicomtypes,dicomfastread,prefs,convertsimple, csaread;
+ SysUtils,Classes,define_types,filename,dicomtypes,dicomfastread,prefs,convertsimple, csaread,dialogs_msg;
{$H+}
var
kUseDateTimeForID: boolean = false;
@@ -82,6 +85,16 @@ begin
result := sec;
end;
+function AddIndent(lIndent: integer): string;
+var
+ i: integer;
+begin
+ result := '';
+ if lIndent < 1 then
+ exit;
+ for i := 1 to lIndent do
+ result := result +'|';
+end;
procedure read_ecat_data(var lDICOMdata: DICOMdata;lVerboseRead,lReadECAToffsetTables:boolean; var lHdrOK, lImageFormatOK: boolean; var lDynStr: string;lFileName: string);
label
@@ -213,7 +226,7 @@ begin
lImageFormatOK := false;
lVolume := 1;
if not fileexists(lFileName) then begin
- Msg('Unable to find the image '+lFileName);
+ dcmMsg('Unable to find the image '+lFileName);
exit;
end;
FileMode := 0; //set to readonly
@@ -221,7 +234,7 @@ begin
Reset(fp, 1);
FileSz := FileSize(fp);
if filesz < (2048) then begin
- Msg('This file is to small to be a ECAT format image.');
+ dcmMsg('This file is to small to be a ECAT format image.');
goto 539;
end;
seek(fp, 0);
@@ -301,7 +314,7 @@ begin
end; //lECAT7
if lFiletype = 9 then lFiletype := 7; //1364: treat projections as Volume16's
if not (lFileType in [1,2,3,4,7]) then begin
- Msg('This software does not recognize the ECAT file type. Selected filetype: '+inttostr(lFileType));
+ dcmMsg('This software does not recognize the ECAT file type. Selected filetype: '+inttostr(lFileType));
goto 539;
end;
lVoxelType := 2;
@@ -329,7 +342,7 @@ if lVerboseRead then begin
end; //verbose read
if ((lECAT6) and (lFiletype =2)) or ({(not lECAT6) and} (lFileType=7)) then //Kludge
else begin
- Msg('Unusual ECAT filetype. Please contact the author.');
+ dcmMsg('Unusual ECAT filetype. Please contact the author.');
goto 539;
end;
lHdrOK:= true;
@@ -404,13 +417,13 @@ lPass := 0;
lDICOMdata.XYZmm[3] := lZmm;
case lVoxelType of
1: begin
- Msg('Error: 8-bit data not supported [yet]. Please contact the author.');
+ dcmMsg('Error: 8-bit data not supported [yet]. Please contact the author.');
lDicomData.Allocbits_per_pixel := 8;
lHdrOK := false;
goto 539;
end;
4: begin
- Msg('Error: 32-bit data not supported [yet]. Please contact the author.');
+ dcmMsg('Error: 32-bit data not supported [yet]. Please contact the author.');
lHdrOK := false;
goto 539;
end;
@@ -420,7 +433,7 @@ lPass := 0;
end; {case lVoxelType}
end else begin //if lECAT6
if (lDICOMdata.XYZdim[1] <> lX) or (lDICOMdata.XYZdim[2] <> lY) or (lDICOMdata.XYZdim[3] <> lZ) then begin
- Msg('Error: different slices in this volume have different slice sizes. Please contact the author.');
+ dcmMsg('Error: different slices in this volume have different slice sizes. Please contact the author.');
lHdrOK := false;
goto 539;
end; //dimensions have changed
@@ -587,7 +600,7 @@ begin
result := strtofloat(lStr);
except
on EConvertError do begin
- Msg('Unable to convert the string '+lStr+' to a number');
+ dcmMsg('Unable to convert the string '+lStr+' to a number');
result := 1;
exit;
end;
@@ -622,7 +635,7 @@ begin
//lDicomData.ImageStart := FileSz;
GetMem( lCharRA, FileSz+1 );
BlockRead(fp, lCharRA^, FileSz, linpos);
- if lInPos <> FileSz then Msg('Disk error: Unable to read full input file.');
+ if lInPos <> FileSz then dcmMsg('Disk error: Unable to read full input file.');
linPos := 1;
CloseFile(fp);
FileMode := 2; //set to read/write
@@ -660,7 +673,7 @@ repeat
lTmpStr := readInterStr;
if (lTmpStr = 'ASCII') or (lTmpStr='BIT') then begin
lHdrOK := false;
- Msg('This software can not convert '+lTmpStr+' data type.');
+ dcmMsg('This software can not convert '+lTmpStr+' data type.');
goto 333;
end;
if lTmpStr = 'UNSIGNEDINTEGER' then lUnsigned := true;
@@ -684,14 +697,14 @@ until (linPos >= FileSz) or (lHdrEnd){EOF(fp)};
//xlDicomData.Storedbits_per_pixel := lDicomData.Allocbits_per_pixel;
lImageFormatOK := true;
if (not lFLoat) and (lUnsigned) and ((lDicomData.Allocbits_per_pixel = 16)) then begin
- Msg('Warning: this Interfile image uses UNSIGNED 16-bit data [values 0..65535]. Analyze specifies SIGNED 16-bit data [-32768..32767]. Some images may not transfer well. [Future versions of MRIcro should fix this].');
+ dcmMsg('Warning: this Interfile image uses UNSIGNED 16-bit data [values 0..65535]. Analyze specifies SIGNED 16-bit data [-32768..32767]. Some images may not transfer well. [Future versions of MRIcro should fix this].');
lImageFormatOK := false;
end else if (not lFLoat) and (lDicomData.Allocbits_per_pixel > 16) then begin
- Msg('WARNING: The image '+lFileName+' is a '+inttostr(lDicomData.Allocbits_per_pixel)+'-bit integer data type. This software may display this as SIGNED data. Bits per voxel: '+inttostr(lDicomData.Allocbits_per_pixel));
+ dcmMsg('WARNING: The image '+lFileName+' is a '+inttostr(lDicomData.Allocbits_per_pixel)+'-bit integer data type. This software may display this as SIGNED data. Bits per voxel: '+inttostr(lDicomData.Allocbits_per_pixel));
lImageFormatOK := false;
end else if (lFloat) then begin //zebra change float check
- //Msg('WARNING: The image '+lFileName+' uses floating point [real] numbers. The current software can only read integer data type Interfile images.');
- lDicomData.Float := true;
+ //dcmMsg('WARNING: The image '+lFileName+' uses floating point [real] numbers. The current software can only read integer data type Interfile images.');
+ lDicomData.FloatData := true;
//lImageFormatOK := false;
end;
333:
@@ -755,7 +768,7 @@ begin
result := strtofloat(lStr);
except
on EConvertError do begin
- Msg('Unable to convert the string '+lStr+' to a number');
+ dcmMsg('Unable to convert the string '+lStr+' to a number');
result := 1;
exit;
end;
@@ -778,7 +791,7 @@ begin
//lDicomData.ImageStart := FileSz;
GetMem( lCharRA, FileSz+1 );
BlockRead(fp, lCharRA^, FileSz, linpos);
- if lInPos <> FileSz then Msg('Disk error: Unable to read full input file.');
+ if lInPos <> FileSz then dcmMsg('Disk error: Unable to read full input file.');
linPos := 1;
CloseFile(fp);
FileMode := 2; //set to read/write
@@ -829,11 +842,11 @@ repeat
end;
3:begin
lDicomData.Allocbits_per_pixel := 32;
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
end;
else begin
lHdrEnd := true;
- Msg('Unsupported AFNI BRICK_TYPES: '+inttostr(lTmpInt));
+ dcmMsg('Unsupported AFNI BRICK_TYPES: '+inttostr(lTmpInt));
end;
end; //case
@@ -931,7 +944,7 @@ begin
end;
except
on EConvertError do begin
- Msg('Unable to convert the string '+lfStr+' to a real number');
+ dcmMsg('Unable to convert the string '+lfStr+' to a real number');
exit;
end;
end; {except}
@@ -974,7 +987,7 @@ begin
//lDicomData.ImageStart := FileSz;
GetMem( lCharRA, FileSz+1 );
BlockRead(fp, lCharRA^, FileSz, linpos);
- if lInPos <> FileSz then Msg('Disk error: Unable to read full input file.');
+ if lInPos <> FileSz then dcmMsg('Disk error: Unable to read full input file.');
linPos := 1;
CloseFile(fp);
FileMode := 2; //set to read/write
@@ -999,7 +1012,7 @@ repeat
if (lHdrOK) and (not lFileTypeKnown) and (lUpCaseStr = 'CUB1') then
lFileTypeKnown := true;
if (lHdrOK) and (not lFileTypeKnown) then begin
- Msg('This software can not read this kind of VoxBo image. (Type:"'+lUpCaseStr+'")');
+ dcmMsg('This software can not read this kind of VoxBo image. (Type:"'+lUpCaseStr+'")');
lHdrEnd := true;
lHdrOK := false;
end;
@@ -1016,7 +1029,7 @@ repeat
inc(linPos);
end;
if lFileTypeKnown then begin //end of file character not found: abort!
- Msg('Unable to find the end of the VoxBo header.');
+ dcmMsg('Unable to find the end of the VoxBo header.');
lHdrEnd := true
end else
lHdrOK := true;
@@ -1040,7 +1053,7 @@ repeat
lFloat := true;
lDicomData.Allocbits_per_pixel := 64;
end else begin
- Msg('Unknown VoxBo data format: '+lTmpStr);
+ dcmMsg('Unknown VoxBo data format: '+lTmpStr);
end;
end;
if lUpCaseStr ='VOXDIMS(XYZ)'then readVBints(lDicomData.XYZdim[1],lDicomData.XYZdim[2],lDicomData.XYZdim[3]);
@@ -1059,7 +1072,7 @@ until (linPos >= FileSz) or (lHdrEnd){EOF(fp)};
//xlDicomData.Rotate180deg := true;
lImageFormatOK := true;
if (lFloat) then begin //zebra change float check
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
//lImageFormatOK := false;
end;
333:
@@ -1096,7 +1109,7 @@ begin
lDouble := strtofloat(lStr);
except
on EConvertError do begin
- Msg('Unable to convert the string '+lStr+' to a number');
+ dcmMsg('Unable to convert the string '+lStr+' to a number');
exit;
end;
end; {except}
@@ -1121,7 +1134,7 @@ begin
if FileSz > 2047 then FileSz := 2047;
GetMem( lCharRA, FileSz+1 );
BlockRead(fp, lCharRA^, FileSz, linpos);
- if lInPos <> FileSz then Msg('Disk error: Unable to read full input file.');
+ if lInPos <> FileSz then dcmMsg('Disk error: Unable to read full input file.');
lInPos := 1;
while (lCharRA^[lInPos] <> 12) and (lInPos < FileSz) do begin
inc(lInPos);
@@ -1322,7 +1335,7 @@ begin
result := strtofloat(lStr);
except
on EConvertError do begin
- Msg('read_PAR_data: Unable to convert the string '+lStr+' to a number');
+ dcmMsg('read_PAR_data: Unable to convert the string '+lStr+' to a number');
result := 1;
exit;
end;
@@ -1350,7 +1363,7 @@ begin
GetMem (lSliceSequenceRA, kMaxnSLices*sizeof(longint)); //note: must free dynamic memory: goto 333 if any error
BlockRead(fp, lCharRA^, lFileSz, lInpos);
if lInPos <> lFileSz then begin
- Msg('read_PAR_data: Disk error, unable to read full input file.');
+ dcmMsg('read_PAR_data: Disk error, unable to read full input file.');
goto 333;
end;
linPos := 1;
@@ -1420,7 +1433,7 @@ begin
MinMaxTRange(lRangeRA[kBitsPerVoxel],readParFloat);
end;
if not lHdrOK then begin
- Msg('read_PAR_data: Error reading header');
+ dcmMsg('read_PAR_data: Error reading header');
goto 333;
end;
end else begin //SliceInfo: IMAGE_INFORMATION (line does NOT start with '.' or '#')
@@ -1473,7 +1486,7 @@ begin
lDicomData.XYZdim[2] := round(lRangeRA[kYdim].Val);
lDicomData.XYZdim[3] := 1+round(lRangeRA[kSlice].Max-lRangeRA[kSlice].Min);
if (lSliceInfoCount mod lDicomData.XYZdim[3]) <> 0 then
- Msg('read_PAR_data: Total number of slices not divisible by number of slices per volume. Reconstruction error?');
+ dcmMsg('read_PAR_data: Total number of slices not divisible by number of slices per volume. Reconstruction error?');
if lDicomData.XYZdim[3] > 0 then
lDicomData.XYZdim[4] := lSliceInfoCount div lDicomData.XYZdim[3] //nVolumes = nSlices/nSlicePerVol
else
@@ -1487,7 +1500,7 @@ begin
lDicomData.IntenIntercept := lRangeRA[kIntercept].Val;
if gPARprecise then begin
if (lDicomData.IntenIntercept <> 0) or (lRangeRA[kCalibratedSlope].val = 0) then
- Msg('Warning: Unable to save calibrated Philips image intensity (non-zero scaling intercept). Turn off Etc/Options/CalibratedScaling to hide warning.');
+ dcmMsg('Warning: Unable to save calibrated Philips image intensity (non-zero scaling intercept). Turn off Etc/Options/CalibratedScaling to hide warning.');
if (lRangeRA[kSlope].min = lRangeRA[kSlope].max)
and (lRangeRA[kIntercept].min = lRangeRA[kIntercept].max)
and (lRangeRA[kCalibratedSlope].min = lRangeRA[kCalibratedSlope].max)
@@ -1558,7 +1571,7 @@ end; //if PARprecise
lErrorStr := lErrorStr + ' Multiple/varying slice dimensions'+kCR;
//if any errors were encountered, report them....
if lErrorStr <> '' then begin
- Msg('read_PAR_data: This software can not convert this Philips data:'+kCR+lErrorStr);
+ dcmMsg('read_PAR_data: This software can not convert this Philips data:'+kCR+lErrorStr);
goto 333;
end;
//Next sort image indexes here...
@@ -1569,7 +1582,7 @@ end; //if PARprecise
lOffset_pos_table^[lInc] := lInc;
ShellSortItems (1, lSliceInfoCount,lOffset_pos_table,lSliceSequenceRA, lRepeatedValues);
if lRepeatedValues then begin
- Msg('read_PAR_data: fatal error, slices do not appear to have unique indexes [multiple copies of same slice]');
+ dcmMsg('read_PAR_data: fatal error, slices do not appear to have unique indexes [multiple copies of same slice]');
FreeMem (lOffset_pos_table);
goto 333;
end;
@@ -1588,7 +1601,7 @@ end; //if PARprecise
lVaryingIntercept_table^[lInc] := lSliceInterceptRA[lOffset_pos_table^[lInc]];
if gPARprecise then begin
if (lVaryingIntercept_table^[lInc] <> 0) or (lCalibratedSliceSlopeRA[lOffset_pos_table^[lInc]]=0) then
- Msg('Warning: Unable to save calibrated Philips image intensity (non-zero scaling intercept). Turn off Etc/Options/CalibratedScaling to hide warning.')
+ dcmMsg('Warning: Unable to save calibrated Philips image intensity (non-zero scaling intercept). Turn off Etc/Options/CalibratedScaling to hide warning.')
else begin
lVaryingScaleFactors_table^[lInc] := 1 / lCalibratedSliceSlopeRA[lOffset_pos_table^[lInc]];
end;
@@ -1602,7 +1615,7 @@ end; //if PARprecise
lVaryingIntercept_table^[lInc] := lSliceInterceptRA[lInc];
if gPARprecise then begin
if (lVaryingIntercept_table^[lInc] <> 0) or (lCalibratedSliceSlopeRA[lInc]=0) then
- Msg('Warning: Unable to save calibrated Philips image intensity (non-zero scaling intercept). Turn off Etc/Options/CalibratedScaling to hide warning.')
+ dcmMsg('Warning: Unable to save calibrated Philips image intensity (non-zero scaling intercept). Turn off Etc/Options/CalibratedScaling to hide warning.')
else
lVaryingScaleFactors_table^[lInc] := 1 / lCalibratedSliceSlopeRA[lInc];
end; //if PARprecise
@@ -1620,7 +1633,7 @@ end; //if PARprecise
or (lRangeRA[kEcho].min <> lRangeRA[kEcho].max) //5D file space+time+echo
or (lRangeRA[kType].min <> lRangeRA[kType].max) //5D file space+time+echo
or (lRangeRA[kSequence].min <> lRangeRA[kSequence].max) then //5D file space+time+echo
- Msg('Warning: note that this image has more than 4 dimensions (multiple Cardiac/Echo/Type/Sequence)');
+ dcmMsg('Warning: note that this image has more than 4 dimensions (multiple Cardiac/Echo/Type/Sequence)');
//if we get here, the Image Format is OK
lImageFormatOK := true;
lFileName := changefileextX(lFilename,'.rec'); //for Linux: case sensitive extension search '.rec' <> '.REC'
@@ -1714,7 +1727,7 @@ begin
lDATFormatOffset := 0;
Clear_Dicom_Data(lDicomData);
if filesz < (3240) then begin
- Msg('This file is too small to be a Genesis DAT format image.');
+ dcmMsg('This file is too small to be a Genesis DAT format image.');
goto 539;
end;
lDynStr:= '';
@@ -1762,7 +1775,7 @@ begin
else if (tx[0] = 'C') and(tx[1] = 'T') then
lMR := false
else begin
- Msg('Is this a Genesis DAT image? The modality is '+tx[0]+tx[1]+tx[3]
+ dcmMsg('Is this a Genesis DAT image? The modality is '+tx[0]+tx[1]+tx[3]
+'. Expected ''MR'' or ''CT''.');
goto 539;
end;
@@ -1773,7 +1786,7 @@ begin
seek(fp, lInitialOffset);
BlockRead(fp, tx, 4*SizeOf(Char), n);
if (tx[0] <> 'I') OR (tx[1] <> 'M') OR (tx[2] <> 'G') OR (tx[3] <> 'F') then begin
- Msg('This image does not have the required label ''IMGF''. This is not a Genesis DAT image.');
+ dcmMsg('This image does not have the required label ''IMGF''. This is not a Genesis DAT image.');
goto 539;
end else
lDicomData.ImageNum := swap16i(2158+12);
@@ -1986,13 +1999,13 @@ begin
FIleSz := FileSize(fp);
Clear_Dicom_Data(lDicomData);
if filesz < (6144) then begin
- Msg('This file is to small to be a Siemens Magnetom Vision image.');
+ dcmMsg('This file is to small to be a Siemens Magnetom Vision image.');
goto 567;
end;
seek(fp, 96);
BlockRead(fp, tx, 7*SizeOf(Char), n);
if (tx[0] <> 'S') OR (tx[1] <> 'I') OR (tx[2] <> 'E') OR (tx[3] <> 'M') then begin {manufacturer is not SIEMENS}
- Msg('Is this a Siemens Magnetom Vision image [Manufacturer tag should be ''SIEMENS''].');
+ dcmMsg('Is this a Siemens Magnetom Vision image [Manufacturer tag should be ''SIEMENS''].');
goto 567;
end; {manufacturer not siemens}
seek(fp, 105);
@@ -2153,13 +2166,13 @@ begin
FIleSz := FileSize(fp);
Clear_Dicom_Data(lDicomData);
if filesz < (3240) then begin
- Msg('This file is too small to be a Elscint format image.');
+ dcmMsg('This file is too small to be a Elscint format image.');
goto 539;
end;
lDynStr:= '';
read16i(0, lI);
if (lI <> 64206) then begin
- Msg('Unable to read this file: it does start with the Elscint signature.');
+ dcmMsg('Unable to read this file: it does start with the Elscint signature.');
goto 539;
end;
lDicomdata.little_endian := 1;
@@ -2325,7 +2338,7 @@ begin
FIleSz := FileSize(fp);
Clear_Dicom_Data(lDicomData);
if filesz < (kPickerHeader) then begin
- Msg('This file is to small to be a Picker image: '+lFileName );
+ dcmMsg('This file is to small to be a Picker image: '+lFileName );
CloseFile(fp);
FileMode := 2; //set to read/write
exit;
@@ -2333,7 +2346,7 @@ begin
seek(fp, 0);
BlockRead(fp, tx, 4*SizeOf(Char), n);
if (tx[0] <> '*') OR (tx[1] <> '*') OR (tx[2] <> '*') OR (tx[3] <> ' ') then begin {manufacturer is not SIEMENS}
- Msg('Is this a Picker image? Expected ''***'' at the start of the file.'+ lFileName);
+ dcmMsg('Is this a Picker image? Expected ''***'' at the start of the file.'+ lFileName);
CloseFile(fp);
FileMode := 2; //set to read/write
exit;
@@ -2356,7 +2369,7 @@ begin
lDICOMdata.XYZdim[3] := 1;
lDICOMdata.ImageStart := 8192;
end else begin
- Msg('This file is the incorrect size to be a Picker image.');
+ dcmMsg('This file is the incorrect size to be a Picker image.');
CloseFile(fp);
FileMode := 2; //set to read/write
exit;
@@ -2460,7 +2473,7 @@ var
begin
result := 1;
if lDataType <> 6 then begin
- Msg('Unknown data type: MRIcro is unable to determine the voxel size.');
+ dcmMsg('Unknown data type: MRIcro is unable to determine the voxel size.');
exit;
end;
seek(fp,lFilePosition);
@@ -2485,7 +2498,7 @@ begin
seek(fp,lFilePosition);
lLen := read32i;
if lLen < 1 then begin
- Msg('Terminal error reading netCDF/MINC header (String length < 1)');
+ dcmMsg('Terminal error reading netCDF/MINC header (String length < 1)');
exit; //problem
end;
for lI := 1 to lLen do begin
@@ -2518,7 +2531,7 @@ begin
if not (lSignature=1128547841) then begin
CloseFile(fp);
FileMode := 2; //set to read/write
- Msg('Problem with MINC signature: '+ inttostr(lSignature));
+ dcmMsg('Problem with MINC signature: '+ inttostr(lSignature));
exit;
end;
//xlDicomData.Rotate180deg := true;
@@ -2581,7 +2594,7 @@ begin
6: lDicomData.Allocbits_per_pixel := 64; //double
end;
if (lDT0 = 5) or (lDT0 = 6) then
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
//xlDicomData.Storedbits_per_pixel := lDicomData.Allocbits_per_pixel;
//lImgNC_Type := lDT0;
end;
@@ -2831,7 +2844,7 @@ begin
end;
259: begin
if lVal <> 1 then begin
- Msg('TIFF Read Error: Image data is compressed. Currently only uncompressed data is supported.');
+ dcmMsg('TIFF Read Error: Image data is compressed. Currently only uncompressed data is supported.');
goto 566; //compressed data
end;
end;
@@ -2897,7 +2910,7 @@ begin
//SAMPLEFORMAT = 339
//JPEGTABLES = 347
// lDicomData.ImageStart := lVal
- //else if lImage_File_Directory = 1 then Msg(inttostr(lTag)+'@'+inttostr(lTagPointer)+' value: '+inttostr(lVal));
+ //else if lImage_File_Directory = 1 then dcmMsg(inttostr(lTag)+'@'+inttostr(lTagPointer)+' value: '+inttostr(lVal));
end; //case lTag
end; //For Each Directory in Image_File_Directory
lOffset := read32i(lOffset+2+(12*lnDirectories));
@@ -2913,13 +2926,13 @@ begin
//xif lDicomData.SamplesPerPixel <> l1stDicomData.SamplesPerPixel then lStackSameDim := false;
//xif lDicomData.PlanarConfig <> l1stDicomData.PlanarConfig then lStackSameDim := false;
if not lStackSameDim then begin
- //Msg(inttostr(lDicomData.XYZdim[1])+'x'+inttostr(l1stDicomData.XYZdim[1]));
+ //dcmMsg(inttostr(lDicomData.XYZdim[1])+'x'+inttostr(l1stDicomData.XYZdim[1]));
if (lDicomData.XYZdim[1]*lDicomData.XYZdim[2]) > (l1stDicomData.XYZdim[1]*l1stDicomData.XYZdim[2]) then begin
l1stDicomData := lDICOMdata;
lnSlices := 1;
lStackSameDim := true;
end;
- //Msg('TIFF Read Error: Different 2D slices in this 3D stack have different dimensions.');
+ //dcmMsg('TIFF Read Error: Different 2D slices in this 3D stack have different dimensions.');
//goto 566;
end else
inc(lnSlices); //if not samedim
@@ -2932,7 +2945,7 @@ begin
lVal := readItem(lItem,lStripPositionType,lStripPositionOffset);
if (lVal <> lImageDataEndPosition) then
lContiguous := false;
- //Msg(inttostr(lImage_File_Directory)+'@'+inttostr(lItem));
+ //dcmMsg(inttostr(lImage_File_Directory)+'@'+inttostr(lItem));
lImageDataEndPosition := lImageDataEndPosition+readItem(lItem,lStripCountType,lStripCountOffset);
if not lcontiguous then begin
if (lReadOffsets) and (lStackSameDim) then begin
@@ -2940,7 +2953,7 @@ begin
end else if (lReadOffsets) then
//not correct size, but do not generate an error as we will read non-contiguous files
else begin
- Msg('TIFF Read Error: Image data is not stored contiguously. '+
+ dcmMsg('TIFF Read Error: Image data is not stored contiguously. '+
'Solution: convert this image using MRIcro''s ''Convert TIFF/Zeiss to Analyze...'' command [Import menu].');
goto 564;
end;
@@ -3088,6 +3101,7 @@ end; //biorad
function SiemensVersion (lStr: string): integer;
//Convert tag 0018,1020 from DICOM header to Siemens version number
(*Returned value: system is in 1000s, last two digits are version
+ syngo MR 2004A 4VA25A //->0011
Siemens syngo MR 2006T 4VB12T //-> 0012
MR B13 4VB13A //->0013
MR.VB15A123 //->0015
@@ -3107,6 +3121,10 @@ begin
goto 999;
exit; //not Siemens format
999:
+ if ( upcase(lStr[i]) = 'A') then begin //A25
+ result := 10;
+ exit;
+ end;
result := strtoint(lStr[i+1]);
if lStr[i+2] in ['0'..'9'] then
result := (result*10) + strtoint(lStr[i+2]);
@@ -3160,11 +3178,26 @@ begin
result := strtoint(S);
end; *)
+function ExpectedDicomBytes (var lDICOMdata: DICOMdata): integer;
+begin
+ if lDicomData.JPEGLosslessCpt then begin
+ result := 0; //actual compressed size unknown
+ exit;
+ end;
+ result := lDicomdata.XYZdim[1]*lDicomdata.XYZdim[2]*lDicomdata.XYZdim[3]*(lDicomData.Allocbits_per_pixel DIV 8);
+end;
+
+const
+ kNo =0;
+ kYes = 1;
+ kUndefined = 2;
+
procedure read_dicom_data_compat(lReadJPEGtables,lVerboseRead,lAutoDECAT7,lReadECAToffsetTables,lAutoDetectInterfile,lAutoDetectGenesis,lReadColorTables: boolean; var lDICOMdata: DICOMdata; var lHdrOK, lImageFormatOK: boolean; var lDynStr: string;var lFileName: string; var lPrefs: TPrefs);
label 666,777;
const
-kMaxTextBuf = 50000; //maximum for screen output
-kDiskCache = 16384; //size of disk buffer
+ kMaxTextBuf = 50000; //maximum for screen output
+ kDiskCache = 16384; //size of disk buffer
+ kNaNsingle : single = 1/0;
type
dicom_types = (unknown, i8, i16, i32, ui8, ui16, ui32, _string{,_float} );
@@ -3178,12 +3211,13 @@ var
FP: file;
lT0,lT1,lT2,lT3:byte;
lImagePositionPatientRead,
- lResearchMode,lManufacturerIsPhilips,lManufacturerIsBruker,lMediface0002_0013,lSiemensMosaic0008_0008,lDICM_at_128, lTextOverFlow,lGenesis,lFirstPass,lrOK,lBig,lBigSet,lGrp,explicitVR,first_one : Boolean;
+ lResearchMode,lManufacturerIsPhilips,lManufacturerIsBruker,lOsirix0002_0013,lMediface0002_0013,lSiemensMosaic0008_0008,lDICM_at_128, lTextOverFlow,lGenesis,lFirstPass,lrOK,lBig,lBigSet,lGrp,explicitVR,first_one : Boolean;
lSwitchToImplicitAfterGroup0002, lTestError,lByteSwap,lGELX,time_to_quit,lProprietaryImageThumbnail,lFirstFragment,lOldSiemens_IncorrectMosaicMM : Boolean;
group, element, e_len, remaining, tmp : uint32;
tmpstr : kDICOMstr;
lgrpstr,lStr,info,lDummyStr : string;
t : dicom_types;
+ lUse00189117 : integer;
lfloat1,lfloat2,lfloat3,lThickness: double;
lTempInt,lEchoNum,lnVol,lnSlicePerVol,lJPEGentries,lErr,liPos,lCacheStart,lCachePos,lDiskCacheSz,n, i,value, Ht,Width,
max16,min16,filesz,where,lMatrixSz,lPhaseEncodingSteps,lJunk,lJunk2,lJunk3 : LongInt;
@@ -3195,6 +3229,9 @@ var
lSingleRA,lInterceptRA: Singlep;
//lPapyrusnSlices,lPapyrusSlice : integer;
//lPapyrusZero,lPapyrus : boolean;
+ {$IFDEF Troubleshoot}
+ myFile : TextFile;
+{$ENDIF Troubleshoot}
procedure ByteSwap (var lInOut: integer);
var lWord: word;
begin
@@ -3304,7 +3341,7 @@ begin
lf1 := strtofloat(lfStr);
except
on EConvertError do begin
- Msg('Unable to convert the string '+lfStr+' to a real number');
+ dcmMsg('Unable to convert the string '+lfStr+' to a real number');
lf1 := 1;
exit;
end;
@@ -3326,7 +3363,7 @@ begin
lf2 := strtofloat(lfStr);
except
on EConvertError do begin
- Msg('Unable to convert the string '+lfStr+' to a real number');
+ dcmMsg('Unable to convert the string '+lfStr+' to a real number');
exit;
end;
end;
@@ -3389,7 +3426,7 @@ begin
lftemp := strtofloat(lfStr);
except
on EConvertError do begin
- Msg('Unable to convert the string '+lfStr+' to a real number');
+ dcmMsg('Unable to convert the string '+lfStr+' to a real number');
//lftemp := 0;
exit;
end;
@@ -3412,8 +3449,12 @@ begin
remaining := 0;
//compute Distance between current slice and 1st slice...
lDx := sqrt( sqr(lX-lDicomData.PatientPosX)+sqr(lY-lDicomData.PatientPosY)+sqr(lZ-lDicomData.PatientPosZ));
- if (lDx > 0) and (lDx < lMinDistance) then //if 0 then this is a repeat, not a new slice
- lMinDistance := lDx;
+ if (lDx > 0) and (lMinDistance = kNaNsingle) then //first value
+ lMinDistance := lDx
+ else if (lDx > 0) and (lDx < lMinDistance) then //if 0 then this is a repeat, not a new slice
+ lMinDistance := lDx
+ else
+ exit;
end;
procedure readfloats6 (var fp: file; remaining: integer; var lOutStr: string; var lf1, lf2,lf3,lf4,lf5,lf6: double; var lReadOK: boolean);
@@ -3476,7 +3517,7 @@ begin
lftemp := strtofloat(lfStr);
except
on EConvertError do begin
- Msg('Unable to convert the string '+lfStr+' to a real number');
+ dcmMsg('Unable to convert the string '+lfStr+' to a real number');
//lftemp := 0;
exit;
end;
@@ -3850,12 +3891,26 @@ begin
FreeMem( buff);
dseek(fp, lStartPos);
end;
-var lPrev0020: boolean;
+label 1234;
+var lIndent: integer;
+ lprevGroup, lprevElement: uint32;
+var lInside00209113, lInside2005140F, lPhilipsWarning: boolean;//philips can list two DIFFERENT spatial positions per slice - ignore the one hidden inside 2005,140FlPrev0020: boolean;
begin
//Init
//for lnVol := 1 to kMaxOrderVal do
// lDICOMdata.OrderSlope[lDICOMdata.nOrder] := 0; //show this was not set
- lPrev0020 := false;
+ {$IFDEF Troubleshoot}
+ AssignFile(myFile, '/Users/rorden/Test.txt');
+ ReWrite(myFile);
+{$ENDIF Troubleshoot}
+
+ lUse00189117 := kUndefined; //Warning each Philips 2D slice can save DTI data once or twice - 0018:9087/0018:9089 and 2001:1003/2001:10B0,10B1,10B2 - this is tricky since Philips files can be 4D
+ lInside00209113 := false;
+ lprevGroup := 0;
+ lprevElement := 0;
+ lPhilipsWarning := false;
+ lIndent := 0;
+ lInside2005140F := false;
lSwitchToImplicitAfterGroup0002 := false;
lGELX := false;
lByteSwap := false;
@@ -3863,7 +3918,7 @@ begin
Clear_Dicom_Data(lDICOMdataBackUp);
lDicomData.XYZdim[1] := 1;
lImagePositionPatientRead := false;// for 4D files, we need first volume
- l4DDistanceBetweenSliceCenters := maxint;
+ l4DDistanceBetweenSliceCenters := kNaNsingle;
lEchoNum := 0;
lThickness := 0;
lTestError := false;
@@ -3877,6 +3932,7 @@ begin
lPhaseEncodingSteps := 0;
lSiemensMosaic0008_0008 := false;
lMediface0002_0013 := false;//false wblate
+ lOsirix0002_0013 := false;
lOldSiemens_IncorrectMosaicMM := false;
lCacheStart := 0;
lDiskCacheSz := 0;
@@ -3891,12 +3947,12 @@ begin
lTextOverFlow := false;
lImageFormatOK := true;
lHdrOK := false;
- //if lverboseRead then msg('xxx'+lFileName);
+ //if lverboseRead then dcmMsg('xxx'+lFileName);
if not fileexists(lFileName) then begin
lImageFormatOK := false;
exit;
end;
- //if lverboseRead then msg('zzzzz000000000');
+ //if lverboseRead then dcmMsg('zzzzz000000000');
TmpStr := string(StrUpper(PChar(ExtractFileExt(lFileName))));
lStr :='';
if TmpStr = '.FDF' then begin
@@ -4159,7 +4215,7 @@ begin
lImageFormatOK:= true;
exit;
end else if (lWord=12880){'P2'=1x8BIT ASCII} or (lWord=13136) {'P3'=3x8bit ASCI} then begin
- Msg('Warning: this image appears to be an ASCII ppm/pgm image. This software can only read binary ppm/pgm images');
+ dcmMsg('Warning: this image appears to be an ASCII ppm/pgm image. This software can only read binary ppm/pgm images');
end;//pgm/ppm binary signature signature
end; //.PPM/PGM extension
@@ -4469,9 +4525,9 @@ begin
goto 666;
end;
dseek(fp, 0);
- //Msg('DICM not at 0 or 128: ' +lFilename);
+ //dcmMsg('DICM not at 0 or 128: ' +lFilename);
end;
- end; //else Msg('DICM at 128{0}');;
+ end; //else dcmMsg('DICM at 128{0}');;
time_to_quit := FALSE;
lProprietaryImageThumbnail := false;
explicitVR := false;
@@ -4562,13 +4618,13 @@ lGrpStr := '';
end; //not first_one or explicit
if (first_one) and (lDicomdata.little_endian =0) and (e_len = $04000000) then begin
- Msg('Switching to little endian');
+ dcmMsg('Switching to little endian');
lDicomData.little_endian := 1;
dseek(fp, where);
first_one := false;
goto 777;
end else if (first_one) and (lDicomData.little_endian =1) and (e_len = $04000000) then begin
- Msg('Switching to little endian');
+ dcmMsg('Switching to little endian');
lDicomData.little_endian := 0;
dseek(fp, where);
first_one := false;
@@ -4578,14 +4634,16 @@ end; //not first_one or explicit
if e_len = ($FFFFFFFF) then begin
e_len := 0;
end;
-if lGELX then begin
- e_len := e_len and $FFFF;
-end;
+ if lGELX then begin
+ e_len := e_len and $FFFF;
+ end;
first_one := false;
remaining := e_len;
info := '?';
tmpstr := '';
-
+ if (lIndent > 0) and (not ((group= $FFFE) and (element = $E0DD))) and (not lManufacturerIsPhilips) then
+ //Philips stores slice positioning inside 0020,9113; lice orientation inside 0020,9116 but Siemens stores thumbnails in indented subheadings
+ goto 1234;
case group of
$0001 : // group for normal reading elscint DICOM
case element of
@@ -4612,9 +4670,10 @@ end;
else TmpStr := TmpStr +('.');
FreeMem( buff);
lStr := '';
+ //dcmMsg(TmpStr);
if TmpStr = '1.2.840.113619.5.2' then begin
lGELX := true;
- LBigSet := true;
+ LBigSet := true;
lBig := true;
end;
//
@@ -4624,6 +4683,7 @@ end;
// explicitVR := false; //china
lSwitchToImplicitAfterGroup0002 := true;
end;
+
if length(TmpStr) >= 19 then begin
if TmpStr[19] = '1' then begin
@@ -4636,20 +4696,18 @@ end;
lBig := true;
end else if TmpStr[19] = '4' then begin
if length(TmpStr) >= 21 then begin
- //lDicomData.JPEGCpt := true;
- if not lReadJPEGtables then begin
+ //Dec 2012.... dcm2nii can handle JPEG 123456
+ if {not lReadJPEGtables} false then begin
lImageFormatOK := false;
end else begin
i := strtoint(TmpStr[21]+TmpStr[22]);
- //if (TmpStr[22] <> '0') or ((TmpStr[21] <> '7') or (TmpStr[21] <> '0'))
-
-
if (i <> 57) and (i <> 70) then begin
lImageFormatOK := false;
//lDicomData.JPEGLossyCpt := true
end else begin
- //lImageFormatOK := false;//x
+
+ //lImageFormatOK := false;//123456
lDicomData.JPEGLosslessCpt := true;
end;
end;
@@ -4662,7 +4720,7 @@ end;
lImageFormatOK := false;
end;
if not lImageFormatOK then
- Msg('Unsupported Transfer Syntax '+(TmpStr)+' Solution: use MRIcro');
+ dcmMsg('Unsupported Transfer Syntax '+(TmpStr)+' Solution: use MRIcro');
end; {length}
remaining := 0;
@@ -4674,12 +4732,17 @@ end;
$13 : begin
info := 'Implementation Version Name';
if e_len > 4 then begin
- TmpStr := '';
- DICOMHeaderString(TmpStr);
- //lDicomData.ImplementationVersion := Str2Int(TmpStr);
- if TmpStr = 'MEDIFACE 1 5' then
- lMediface0002_0013 := true; //detect MEDIFACE 1.5 error: error in length of two elements 0008:1111 and 0008:1140
+ TmpStr := '';
+ DICOMHeaderString(TmpStr);
+ //lDicomData.ImplementationVersion := Str2Int(TmpStr);
+ if TmpStr = 'OSIRIX' then
+ lOsirix0002_0013 := true;
+ if TmpStr = 'MEDIFACE 1 5' then
+ lMediface0002_0013 := true; //detect MEDIFACE 1.5 error: error in length of two elements 0008:1111 and 0008:1140
end; //length > 4
+
+
+
end; //element 13
$16 : info := 'Source App Entity Title';
$100: info := 'Private Info Creator UID';
@@ -4692,27 +4755,27 @@ end;
end;
$01 : info := 'Length to End';
$05 : info := 'Specific Character Set';
- $08 : begin
+ $08 : begin
info := 'Image Type';
- //Only read last word, e.g. 'TYPE\MOSAIC' will be read as 'MOSAIC'
- TmpStr := '';
if dFilePos(fp) > (filesz-e_len) then goto 666;
- GetMem( buff, e_len);
- dBlockRead(fp, buff{^}, e_len, n);
- i := e_len -1;
- while (i>-1) and (Char(buff[i]) in ['a'..'z','A'..'Z',' ']) do begin
- if (Char(buff[i])) <> ' ' then //strip filler characters: DICOM elements must be padded for even length
- TmpStr := upcase(Char(buff[i]))+TmpStr;
+ lSiemensMosaic0008_0008:= false;
+ if (e_len >= 6) then begin //search for 'MOSAIC'
+ GetMem( buff, e_len);
+ dBlockRead(fp, buff{^}, e_len, n);
+ i := e_len -6;//MOSAIC
+ while (i>-1) and (not lSiemensMosaic0008_0008) do begin
+ if (upcase(Char(buff[i])) = 'M') and (upcase(Char(buff[i+1])) = 'O')
+ and (upcase(Char(buff[i+2])) = 'S') and (upcase(Char(buff[i+3])) = 'A')
+ and (upcase(Char(buff[i+4])) = 'I') and (upcase(Char(buff[i+5])) = 'C')
+ then //strip filler characters: DICOM elements must be padded for even length
+ lSiemensMosaic0008_0008 := true;
dec(i);
- end;
- FreeMem( buff);
- remaining := 0;
- e_len := 0; {use tempstr}
- if TmpStr = 'MOSAIC' then begin
- lSiemensMosaic0008_0008:= true;
- //if lMatrixSz < 1 then lMatrixSz := 64;//B13
- end;
- end;
+ end;
+ FreeMem( buff);
+ remaining := 0;
+ e_len := 0; {use tempstr}
+ end;
+ end;
$10 : info := 'Recognition Code';
$12 : info := 'Instance Creation Date';
$13 : info := 'Instance Creation Time';
@@ -4828,7 +4891,7 @@ end;
//mixed will be followed by subsequent settings, so do not use it here....
if (i > 0) and (lDICOMdata.nOrder < kMaxOrderVal) then begin
inc(lDICOMdata.nOrder);
- //msg(TmpStr);
+ //dcmMsg(TmpStr);
lDICOMdata.order[lDICOMdata.nOrder] := i;
end;
(*[ magnitude * MAGNITUDE
@@ -4928,7 +4991,7 @@ end;
readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
if not lrOK then goto 666;
e_len := 0; remaining := 0;
- //lDicomData.kV := lFloat1;
+ lDicomData.kV := lFloat1;
end;
$70: begin t := _string; info := 'Counts Accumulated'; end;
@@ -4984,7 +5047,7 @@ end;
// A real kludge due to Siemens not documenting mosaics explicitly: this workaround may incorrectly think rescaled images are mosaics!
readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
lPhaseEncodingSteps := round(lfloat1);
- //xxxMsg(floattostr(lFloat1));
+ //xxxdcmMsg(floattostr(lFloat1));
if not lrOK then goto 666;
e_len := 0; remaining := 0; //1362 some use this for gap size, others for sum of gap and slicethickness!
//if (lfloat1 > lDICOMdata.XYZmm[3]) or (lDICOMdata.XYZmm[3]=1) then
@@ -5009,7 +5072,7 @@ end;
lDicomData.Vers0018_1020 := Siemensversion(TmpStr);
end;
- //showmsg(inttostr(lDicomData.Vers0018_1020)+' '+TmpStr);
+ //showdcmMsg(inttostr(lDicomData.Vers0018_1020)+' '+TmpStr);
end;
$1030: begin
info := 'Protocol Name';t := _string;
@@ -5096,7 +5159,7 @@ end;
kEr := false;
lMatrixSz := round(lFloat1);
- msg(TmpStr);
+ dcmMsg(TmpStr);
fx(lMatrixSz,lFLoat1,lFloat2,4321);*)
{fx(lA,lB,lC);
lMatrixSz := lB;
@@ -5158,6 +5221,63 @@ end;
$7048: info := 'Grid Period';
$7050: info := 'Filter Material LT';
$7060: info := 'Exposure Control Mode';
+ {$IFDEF read00189117}
+ $9117 : begin //SQ
+ //Philips has been inconsistent in reporting DTI tags. This makes archival support difficult
+ //It is unclear if this is intentional obfustication or simply incompetence, but it does mean
+ // that this shameful usage results in code that is unintuitive.
+ //Warning: 0018,9087 is used inconsistently by Philips: sometimes order is 0018,9087;0018,9089 other times 0018,9089;0018,9087
+ // sometimes if 0018,9087=0 (e.g. B0 scan, with 0018,9075='NONE/0') then 0018,9089 is not included
+ //Therefore, we only use this as a last resort! on Philips, prefer to use 2001,1003+ 2005,10b0/2005,10b1/2005,10b2
+
+ if (lUse00189117 = kUndefined) then
+ lUse00189117 := kYes;
+ if (lUse00189117 = kYes) then begin //Overly complicated due to Philips shameful use of these tags
+ if lDICOMdata.nDTIdir < kMaxDTIdir then
+ inc(lDICOMdata.nDTIdir);
+ lDICOMdata.DTI[lDICOMdata.nDTIdir].bval := 0;
+ //Philips may not report vectors for B0 images - so we will initialize these values
+ lDICOMdata.DTI[lDICOMdata.nDTIdir].v1 := 0;
+ lDICOMdata.DTI[lDICOMdata.nDTIdir].v2 := 0;
+ lDICOMdata.DTI[lDICOMdata.nDTIdir].v3 := 0;
+ end;
+ end;//9117
+ $9087: begin
+
+ if {(lGrpStr = 'FD') and} (lUse00189117 <> kNo) then begin
+ info := 'Diffusion b-value';
+ if lDICOMdata.nDTIdir < 1 then //for non-Philips data
+ lDICOMdata.nDTIdir := 1;
+ lDICOMdata.DTI[lDICOMdata.nDTIdir].bval := round(read64 (fp,lrOK));
+ //if lDICOMdata.DTI[lDICOMdata.nDTIdir].bval = 0 then //only once per volume
+ // Msg ('New feature: diffusion directions extracted from 0018:9089. Please validate bvec values www.mricro.com/mricron/dcm2nii.html');
+ //dcmMsg('bvalue '+ inttostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].bval));
+ if not lrOK then goto 666;
+ e_len := 0; remaining := 0;
+ //if (lDICOMdata.nDTIdir >2) and (lDicomData.ManufacturerID = kPhilipsID) then // 2001,1003
+ // dcmMsg('Warning: DTI data extracted from 0018,9087 and 0018,9089. Please inspect resulting bvec files - some Philips systems use these tags erraticly.');
+ end; //if lUse00189117
+
+ end; //9087 b-values
+ $9089: begin
+ if (lUse00189117 <> kNo) {lGrpStr = 'FD'} then begin //see lUse00189117
+ info := 'Diffusion Gradient vector [x,y,z]';
+ if lDICOMdata.nDTIdir < 1 then //for non-Philips data
+ lDICOMdata.nDTIdir := 1;
+ //readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
+ lDICOMdata.DTI[lDICOMdata.nDTIdir].v1 := read64 (fp,lrOK);
+ if not lrOK then goto 666;
+ lDICOMdata.DTI[lDICOMdata.nDTIdir].v2 := read64 (fp,lrOK);
+ if not lrOK then goto 666;
+ lDICOMdata.DTI[lDICOMdata.nDTIdir].v3 := read64 (fp,lrOK);
+ if not lrOK then goto 666;
+ //dcmMsg('xqas '+inttostr(lDICOMdata.nDTIdir)+' b: '+inttostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].bval)+' v1: '+floattostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].v1)+' '+lFileName);
+
+ e_len := 0; remaining := 0;
+ end; //if true
+ end; //9089 X/Y/Z diffusion direction
+ {$ENDIF} // read00189117
+
end;
$0019: begin
(*case element of //1362
@@ -5186,6 +5306,19 @@ $0019: begin
if lDicomData.ManufacturerID = kSiemensID then begin
case element of //1362
+ (* $100A: begin //unsigned short $100A
+ info := 'Number Of Images in Mosaic';
+ tmp := read16(fp,lrOK);
+ if not lrOK then goto 666;
+ fx(e_len,tmp,remaining);
+
+ end;*)
+ $1028: begin //7/2013
+ info := 'Siemens BandwidthPerPixelPhaseEncode';
+ lDICOMdata.BandwidthPerPixelPhaseEncode := read64 (fp,lrOK);
+ if not lrOK then goto 666;
+ e_len := 0; remaining := 0;
+ end; // BandwidthPerPixelPhaseEncode
$000C,$100C: begin
info := 'Siemens b-value';
readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
@@ -5194,7 +5327,6 @@ $0019: begin
tmpstr := floattostr(lFloat1);
lDICOMdata.DTI[1].bval := round(lFloat1);
lDICOMdata.SiemensDICOMDTI := true ;
- //msgfx( 777,lDICOMdata.DTI[1].bval,lDICOMdata.DTI[1].bval,lDICOMdata.DTI[1].bval);
end; // b-values
$000E,$100E: begin
info := 'Siemens Gradient vector [x,y,z]';
@@ -5205,14 +5337,8 @@ $0019: begin
if not lrOK then goto 666;
lDICOMdata.DTI[1].v3 := read64 (fp,lrOK);
if not lrOK then goto 666;
- //msgfx( 666,lDICOMdata.DTI[1].v1,lDICOMdata.DTI[1].v2,lDICOMdata.DTI[1].v3);
- //readfloats3 (fp, remaining, lDummyStr, lDICOMdata.DTI[1].v1,lDICOMdata.DTI[1].v2,lDICOMdata.DTI[1].v3, lROK);
- //ShowMsg(lDummyStr);
- //fx(e_len,lDICOMdata.DTI[1].v1,lDICOMdata.DTI[1].v2,lDICOMdata.DTI[1].v3);
-
e_len := 0; remaining := 0;
- //lDICOMdata.DTI[1].v1 := lFloat1;
- end; // X diffusion direction
+ end; // X/Y/Z diffusion direction
end;//Case element
@@ -5271,7 +5397,7 @@ $0020 :
lDicomData.ImageNum := lTempInt;
//March2008 - some Philips data has multiple image numbers...
// 0018,1020,Software Version=1.5.4\1.5.4.3\Gyroscan PMS/DICOM 2.0 MR .Id. datadefs.v 5.27 2004/10/18 06.50
- //msg(inttostr(lDicomData.ImageNum)+lDicomData.Filename);
+ //dcmMsg(inttostr(lDicomData.ImageNum)+lDicomData.Filename);
end;
$20 : begin info := 'Patient Orientation';
t := _string;
@@ -5280,22 +5406,32 @@ $0020 :
$32 : begin
info := 'Image Position Patient';
//June 2009 - for Philips new 4D format we want value from the first slice...
- if lPrev0020 then begin //5/2012: Philips R3.2.2 can save two instances of 0020:0032 for each slice: one from voxel center, one from voxel edge.
- if not lImagePositionPatientRead then begin
- readfloats3 (fp, remaining, lDummyStr, lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ, lROK);
- //fx( lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ,56789);
- if not lrOK then goto 666;
- e_len := 0;
- remaining := 0;
- lImagePositionPatientRead := true;
- //we assume Philips reports the slice thickness correctly....
- //an alternative would be to read both 1st and 2nd ImagePositionPatient and
- //compute the function DICOMinterslicedistance
+
+ if lInside2005140F then begin
+ if not (lPhilipsWarning) then
+ dcmMsg('*User: check slice thickness. Possible Philips R3.2.2 bug - scanner can report different 0020,0032 values for the same slice.');
+ lPhilipsWarning := true;
end else begin
+ //5/2012: Philips R3.2.2 can save two instances of 0020:0032 for each slice: one from voxel center, one from voxel edge.
+
+ if not lImagePositionPatientRead then begin
+ readfloats3 (fp, remaining, lDummyStr, lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ, lROK);
+ //fx( lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ,56789);
+ if not lrOK then goto 666;
+ e_len := 0;
+ remaining := 0;
+ lImagePositionPatientRead := true;
+ //we assume Philips reports the slice thickness correctly....
+ //an alternative would be to read both 1st and 2nd ImagePositionPatient and
+ //compute the function DICOMinterslicedistance
+ end else begin
+
CheckIntersliceDistance(l4DDistanceBetweenSliceCenters);
- end;
- end;
+ end; //not 1st read
+
+ end; //if lInside2005140F
+ //lInside2005140F := false;
end;
$35 : info := 'Image Orientation';
$37 : begin //nifti
@@ -5341,6 +5477,7 @@ $0020 :
$4000: info := 'Image Comments';
$5000: info := 'Original Image ID';
$5002: info := 'Original Image... Nomenclature';
+ //$9113: xxxx
end;
$0021:case element of
$104F: begin
@@ -5473,18 +5610,19 @@ $0028 : begin
if tmp = 8 then lDicomData.Allocbits_per_pixel := 8
else if tmp = 12 then lDicomData.Allocbits_per_pixel := 12
else if tmp = 16 then lDicomData.Allocbits_per_pixel := 16
+ else if tmp = 32 then lDicomData.Allocbits_per_pixel := 32
else if tmp = 24 then begin
//xlDicomData.SamplesPerPixel := 3;
lDicomData.Allocbits_per_pixel := 8
end else begin
lWord := tmp;
lWord := swap(lWord);
- if lWord in [8,12,16,24] then begin
+ if lWord in [8,12,16,24,32] then begin
lDicomData.Allocbits_per_pixel := tmp;
lByteSwap := true;
end else begin
if lImageFormatOK then
- Msg('This software only reads 8, 12 and 16 bit DICOM files. This file allocates '+inttostr(tmp)+' bits per voxel.');
+ dcmMsg('This software only reads 8, 12, 16, 24 [RGB] and 32 bit DICOM files. This file allocates '+inttostr(tmp)+' bits per voxel.');
lImageFormatOK := false;
end;
end;
@@ -5512,7 +5650,7 @@ $0028 : begin
lByteSwap := true;
end else begin
if lImageFormatOK then
- Msg('This software can only read 8, 12 and 16 bit DICOM files. This file stores '+inttostr(tmp)+' bits per voxel.');
+ dcmMsg('This software can only read 8, 12 and 16 bit DICOM files. This file stores '+inttostr(tmp)+' bits per voxel.');
lDicomData.Storedbits_per_pixel := tmp;
lImageFormatOK := false;{ }
end;
@@ -5787,12 +5925,16 @@ end; //$0028
case element of
$1010: begin
//lSiemensMosaic0029_1010:= true;
+ if (lDicomData.kV = 0) then begin //Siemens uses 0029:1010 for both CT and MRI, but only MRI is in CSA format
lDicomData.CSAImageHeaderInfoPos := (dFilePos(fp));
lDicomData.CSAImageHeaderInfoSz := e_len;
+ end;
info := 'Private Sequence Delimiter ['+inttostr(dFilePos(fp))+']';
- if not lImageFormatOK
+ if not lImageFormatOK then
+ time_to_quit := TRUE;
+
//x(lDicomData.RunLengthEncoding) or ( ((lDicomData.JPEGLossycpt) or (lDicomData.JPEGLosslesscpt)) and (gECATJPEG_table_entries >= lDICOMdata.XYZdim[3]))}
- then time_to_quit := TRUE;
+
dSeek(fp, dFilePos(fp) + e_len);
tmpstr := inttostr(e_len);
remaining := 0;
@@ -5824,7 +5966,7 @@ end; //$0028
(* $0045 : begin
case element of
$103B: begin
- msg('0045:103B');
+ dcmMsg('0045:103B');
end; //element $1010
end; //CASE...element
@@ -5852,22 +5994,27 @@ end; //$0028
$2001 : begin
if lDicomData.ManufacturerID = kPhilipsID then begin
case element of
+ {$IFDEF read20011003}
+ $1003: begin //bvalue - see lUse00189117
+ //if (lUse00189087 = kUndefined) then
+ // lUse00189087 := kNo; //see notes for 0018,9087 - shame on Philips!
- $1003: begin //bvalue
- if e_len = 4 then begin
- if lDICOMdata.nDTIdir < kMaxDTIdir then
+ if (e_len = 4) {and (lUse00189087 = kNo)} then begin
+ if (lDICOMdata.nDTIdir < kMaxDTIdir) and (not (lUse00189117 = kYes)) then //see 0018,9117 - Philips' usage shameful
inc(lDICOMdata.nDTIdir);
+ lUse00189117 := kNo;
lDICOMdata.DTI[lDICOMdata.nDTIdir].bval := round(read32r(fp,lrOK));
TmpStr := inttostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].bval);
t := _string;
- info :='DTI b-val';
+ info :='Philips DTI b-val';
if not lrOK then goto 666;
e_len := 0; remaining := 0;
end; //e_len = 4
-
+
end; //element 1003
+ {$ENDIF} // read20011003
$100B: begin
- info := 'philips: slice orientation';t := _string;
+ info := 'Philips: slice orientation';t := _string;
TmpStr := '';
DICOMHeaderString(TmpStr);
lDicomData.PhilipsSliceOrient := TmpStr;
@@ -5908,9 +6055,18 @@ end; //$0028
$2005 : begin
- //if lDicomData.ManufacturerID = kPhilipsID then Msg(inttohex(element,4));
+ //if lDicomData.ManufacturerID = kPhilipsID then dcmMsg(inttohex(element,4));
if lDicomData.ManufacturerID = kPhilipsID then begin
case element of
+ $140F: begin
+ //lInside2005140F := true;
+ if (e_len > 8) and (lOsirix0002_0013) then begin
+ //dcmMsg('WARNING: Images from Osirix which disrupts DICOM tags. Please validate output.');
+ e_len := 8; remaining := e_len; //qas 7/2013
+ end;
+ end;
+
+
$100E: begin
if e_len = 4 then begin
lPhilipsScaleSlope := read32r(fp,lrOK);
@@ -5953,48 +6109,70 @@ end; //$0028
e_len := 0; remaining := 0;
end;
end; // Philips RL angulation
- $10b0: begin
- if e_len = 4 then begin
+ {$IFDEF read20011003}
+ $10b0: begin //see lUse00189117
+
+ if (e_len = 4) and (lUse00189117 = kNo) then begin
lDICOMdata.DTI[lDICOMdata.nDTIdir].v1 := read32r(fp,lrOK);
TmpStr := floattostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].v1);
t := _string;
- info :='Gradient vector [x]';
+ // dcmMsg('zqas '+inttostr(lDICOMdata.nDTIdir)+' b: '+inttostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].bval)+' v1: '+floattostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].v1));
+
+ info :='Philips Gradient vector [x]';
if not lrOK then goto 666;
e_len := 0; remaining := 0;
end; //e_len = 4
end; //element 10b0
- $10b1: begin
- if e_len = 4 then begin
+ $10b1: begin //see lUse00189117
+ if (e_len = 4) and (lUse00189117 = kNo) then begin
lDICOMdata.DTI[lDICOMdata.nDTIdir].v2 := read32r(fp,lrOK);
TmpStr := floattostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].v2);
t := _string;
- info :='Gradient vector [y]';
+ info :='Philips Gradient vector [y]';
if not lrOK then goto 666;
e_len := 0; remaining := 0;
end; //e_len = 4
end; //element 10b1
- $10b2: begin
- if e_len = 4 then begin
+ $10b2: begin //see lUse00189117
+ if (e_len = 4) and (lUse00189117 = kNo) then begin
lDICOMdata.DTI[lDICOMdata.nDTIdir].v3 := read32r(fp,lrOK);
TmpStr := floattostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].v3);
t := _string;
- info :='Gradient vector [z]';
+ info :='Philips Gradient vector [z]';
//fx(lDICOMdata.DTI[lDICOMdata.nDTIdir].v1,lDICOMdata.DTI[lDICOMdata.nDTIdir].v2,lDICOMdata.DTI[lDICOMdata.nDTIdir].v3);
if not lrOK then goto 666;
e_len := 0; remaining := 0;
end; //e_len = 4
end; //element 10b2
+ {$ENDIF} // read20011003}
end; //CASE...element
end; //if Manufacturer = Philips
end; //group 2005
$5200 : begin
case element of
$9230: begin
- if (lDicomData.ManufacturerID = kPhilipsID) and (orientation_not_visible( lDICOMdata))then
- read_philips_hidden(lFilename, dFilePos(fp),e_len,lDICOMdata);
+ if (e_len > 8) and (lDicomData.ManufacturerID = kPhilipsID) and (lOsirix0002_0013) then begin
+ dcmMsg('WARNING: Images from Osirix which disrupts DICOM tags. PLEASE VALIDATE OUTPUT.');
+ e_len := 8; remaining := e_len; //qas 7/2013
+ end;
+ //if (lDicomData.ManufacturerID = kPhilipsID) and (orientation_not_visible( lDICOMdata))then
+ // read_philips_hidden(lFilename, dFilePos(fp),e_len,lDICOMdata);
end //element 9230
end; //case element
end; //group 5200
+ $5400 : begin
+ case element of
+ $0100: begin
+ //can not convert sound files to images 12/2012
+ lImageFormatOK := false;
+ dcmMsg('Note: the DICOM file '+lFileName+' stores a waveform sequence (e.g. ECG) that will not be converted to an image');
+ info :='WaveformSequence';
+ //fx(lDICOMdata.DTI[lDICOMdata.nDTIdir].v1,lDICOMdata.DTI[lDICOMdata.nDTIdir].v2,lDICOMdata.DTI[lDICOMdata.nDTIdir].v3);
+ if not lrOK then goto 666;
+ e_len := 0; remaining := 0;
+ end //element 0100
+ end; //case element
+ end; //group 5400
$DDFF : begin
case element of
$00E0: begin
@@ -6006,6 +6184,11 @@ end; //$0028
$FFFE : begin
case element of
$E000 : begin
+ e_len := 0; remaining := e_len; //qas 7/2013
+ inc(lIndent);
+ lInside00209113 := (lprevGroup = $0020) and (lprevelement = $9113);
+ lInside2005140F := (lprevGroup = $2005) and (lprevelement = $140F);
+ // if (lInside00209113) then fx(333);
(*iif lJPEGEntries > 17 then
lTestError := true;
@@ -6053,11 +6236,12 @@ lProprietaryImageThumbnail := false; //1496
lFirstFragment := false;//Dec09
lDICOMdataBackUp := lDICOMData;//Dec09
- if (e_len >= (lDicomData.XYZdim[1]*lDicomData.XYZdim[2])){Apr 2011} and (lDicomData.XYZdim[1]> 1) then begin
+ if ((e_len > 1024) and ((lDicomData.JPEGLosslessCpt)) or (e_len >= (lDicomData.XYZdim[1]*lDicomData.XYZdim[2]))){Apr 2011} and (lDicomData.XYZdim[1]> 1) then begin
lDICOMdata.CompressOffset := dFilePos(fp);
lDICOMdata.CompressSz := e_len;
+
Time_To_Quit := true;
- //msg('abba'+inttostr(lDICOMdata.CompressOffset)+' '+inttostr(lDICOMdata.CompressSz));
+ //dcmMsg('abba'+inttostr(lDICOMdata.CompressOffset)+' '+inttostr(lDICOMdata.CompressSz));
end;
info := 'Image Fragment ['+inttostr(dFilePos(fp))+']';
@@ -6069,6 +6253,9 @@ lProprietaryImageThumbnail := false; //1496
e_len := 0;
end;
$E0DD : begin
+ if (lIndent > 0) then dec(lIndent);
+ lInside00209113 := false;
+ lInside2005140F := false;
info := 'Sequence Delimiter';
if (lDICOMdata.XYZdim[1]<lDICOMdataBackUp.XYZdim[1]) then begin
lDICOMData := lDICOMdataBackUp;
@@ -6076,7 +6263,6 @@ lProprietaryImageThumbnail := false; //1496
//lDICOMData := lDICOMdataBackUp;
end else if not lImageFormatOK then begin
//x(lDicomData.RunLengthEncoding) or ( ((lDicomData.JPEGLossycpt) or (lDicomData.JPEGLosslesscpt)) and (gECATJPEG_table_entries >= lDICOMdata.XYZdim[3])) then
-
time_to_quit := TRUE;
end;
//RLE ABBA
@@ -6111,12 +6297,13 @@ lProprietaryImageThumbnail := false; //1496
$10 : begin
info := 'Pixel Data';
TmpStr := inttostr(e_len);
- if (lDICOMdata.XYZdim[1]<lDICOMdataBackUp.XYZdim[1]) then begin
+ //ShowdcmMsg(inttostr(ExpectedDicomBytes(lDicomData) ) +' '+ inttostr(e_len));
+ if ((ExpectedDicomBytes(lDicomData) ) > e_len) or (lDICOMdata.XYZdim[1]<lDICOMdataBackUp.XYZdim[1]) then begin
lDICOMData := lDICOMdataBackUp;
- dSeek(fp, dFilePos(fp) + e_len);
- //lDICOMData := lDICOMdataBackUp;
- end else if {(not lDicomData.RunLengthEncoding) and} (not lDicomData.JPEGLossycpt) and (not lDicomData.JPEGLosslesscpt) then begin
- time_to_quit := TRUE;
+ dSeek(fp, dFilePos(fp) + e_len);
+ //lDICOMData := lDICOMdataBackUp;
+ end else if {(not lDicomData.RunLengthEncoding) and} (not lDicomData.JPEGLossycpt) and (not lDicomData.JPEGLosslesscpt) then begin
+ time_to_quit := TRUE;
//xlDicomData.ImageSz := e_len;
end;
@@ -6138,18 +6325,15 @@ lProprietaryImageThumbnail := false; //1496
end;
lStr := '';
- if group = $0020 then
- lPrev0020 := true
- else
- lPrev0020 := false;
-
-
+ 1234:
+ lprevGroup := Group;
+ lprevElement := element;
if (Time_TO_Quit) and (not lImageFormatOK) then begin
lHdrOK := true;
goto 666;
end;
-//Msg(inttohex(group,4) +':'+inttohex(element,4) +' '+inttostr(e_len)+'@'+ inttostr(dfilepos(fp)));
+//dcmMsg(inttohex(group,4) +':'+inttohex(element,4) +' '+inttostr(e_len)+'@'+ inttostr(dfilepos(fp)));
if (e_len + dfilepos(fp)) > FileSz then begin//patch for GE files that only fill top 16-bytes w Random data
e_len := e_len and $FFFF;
@@ -6163,8 +6347,8 @@ end;
if not lImageFormatOK(*x(lDICOMdata.GenesisCpt) or (lDICOMdata.JPEGlosslessCpt) or (lDICOMdata.JPEGlossyCpt)*) then
lHdrOK := true
else begin
- Msg('dcm Error: not a DICOM image: '+lFilename);
- {Msg('Diagnostics saved as: c:\dcmcrash.txt');
+ dcmMsg('dcm Error: not a DICOM image: '+lFilename);
+ {dcmMsg('Diagnostics saved as: c:\dcmcrash.txt');
//diagnostics
assignfile(lTextF,'c:\dcmcrash.txt');
Filemode := 0;
@@ -6172,7 +6356,7 @@ end;
Write(lTextF,lDynStr);
closefile(lTextF); }
- //Msg(inttohex(group,4) +':'+inttohex(element,4) +' '+inttostr(e_len)+'@'+ inttostr(dfilepos(fp)));
+ //dcmMsg(inttohex(group,4) +':'+inttohex(element,4) +' '+inttostr(e_len)+'@'+ inttostr(dfilepos(fp)));
end;
goto 666;
end;
@@ -6234,9 +6418,10 @@ end;
mtConfirmation, [mbYes, mbNo], 0) = mrNo then GOTO 666;
*)
//if (Group > $2005) then
- // msg(info+' '+IntToStr(where)+': ('+IntToHex(group,4)+','+IntToHex(element,4)+')'+IntToStr(e_len));
+ // dcmMsg(info+' '+IntToStr(where)+': ('+IntToHex(group,4)+','+IntToHex(element,4)+')'+IntToStr(e_len));
{$IFDEF Troubleshoot}
- Msg( IntToHex(group,4)+','+IntToHex(element,4)+','+Info+'='+lStr);//+' Offset'+inttostr(dfilepos(fp))+' Length'+inttostr(e_len));
+WriteLn(myFile,IntToHex(group,4)+','+IntToHex(element,4)+','+Info+'='+lStr);//+' Offset'+inttostr(dfilepos(fp))+' Length'+inttostr(e_len));
+// dcmMsg( IntToHex(group,4)+','+IntToHex(element,4)+','+Info+'='+lStr);//+' Offset'+inttostr(dfilepos(fp))+' Length'+inttostr(e_len));
{$ENDIF Troubleshoot}
@@ -6250,7 +6435,8 @@ if length(lDynStr) > kMaxTextBuf then begin
//goto 666;
end else
lDynStr := lDynStr+IntToHex(group,4)+','+IntToHex(element,4)+','+Info+'='+lStr+kCR ;
- Msg(IntToHex(group,4)+','+IntToHex(element,4)+','+inttostr(e_len)+'@'+inttostr(dfilepos(fp))+','+Info+'='+lStr);
+
+ dcmMsg(AddIndent(lIndent)+IntToHex(group,4)+','+IntToHex(element,4)+','+inttostr(e_len)+'@'+inttostr(dfilepos(fp))+','+Info+'='+lStr);
end; //not verbose read
end; // end for
@@ -6272,7 +6458,7 @@ if lByteSwap then begin
//xByteSwap(lDicomData.Storedbits_per_pixel);
end;
-if (lDICOMdata.ManufacturerID = kPhilipsID) and (l4DDistanceBetweenSliceCenters <> MaxInt) then //some 3D and 4D Philips files do not correctly report interslice distance in 0018,0088 and 0018,0050...
+if (lDICOMdata.ManufacturerID = kPhilipsID) and (l4DDistanceBetweenSliceCenters <> kNaNsingle) then //some 3D and 4D Philips files do not correctly report interslice distance in 0018,0088 and 0018,0050...
lDICOMdata.XYZmm[3] := (l4DDistanceBetweenSliceCenters);
if (lPrefs.PhilipsPrecise) and (lManufacturerIsPhilips) and (lPhilipsScaleSlope <> 0) then begin
PhilipsPrecise (lDicomData.IntenScale, lDICOMdata.intenIntercept,lPhilipsScaleSlope, lDicomData.IntenScale, lDICOMdata.intenIntercept,true);
@@ -6322,19 +6508,21 @@ if lManufacturerIsBruker then
if (lEchoNum > 0) and (lEchoNum < 16) then begin
lDicomData.AcquNum := lDicomData.AcquNum + (1000*lEchoNum);
-end;
+end;
+
if lVerboseRead then begin
- Msg ('DICOM data');
- Msg ('Image Series/Number/Xpos/YPos/ZPos:'+kTab+inttostr(lDicomData.AcquNum)+kTab+inttostr(lDicomData.ImageNum)+kTab+floattostr(lDicomData.PatientPosX)+kTab+floattostr(lDicomData.PatientPosY)+kTab+floattostr(lDicomData.PatientPosZ));
- Msg ('BPP: '+inttostr(lDicomData.Allocbits_per_pixel));
- Msg ('XYZ dim:' +inttostr(lDicomData.XYZdim[1])+'/'+inttostr(lDicomData.XYZdim[2])+'/'+inttostr(lDicomData.XYZdim[3]) );
- Msg ('XYZ mm:'+floattostrf(lDicomData.XYZmm[1],ffFixed,8,2)+'/'+floattostrf(lDicomData.XYZmm[2],ffFixed,8,2)+'/'+floattostrf(lDicomData.XYZmm[3],ffFixed,8,2) );
- Msg ('DTI bvalue:'+ inttostr(lDICOMdata.DTI[1].bval));
- Msg ('DTI bvec:'+floattostrf(lDicomData.DTI[1].v1,ffFixed,8,2)+'/'+floattostrf(lDicomData.DTI[1].v2,ffFixed,8,2)+'/'+floattostrf(lDicomData.DTI[1].v3,ffFixed,8,2) );
+ // lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ
+ dcmMsg ('DICOM data');
+ dcmMsg ('Series/Acquisition/Image/Xpos/YPos/ZPos:'+kTab+inttostr(lDicomData.SeriesNum)+kTab+inttostr(lDicomData.AcquNum)+kTab+inttostr(lDicomData.ImageNum)+kTab+floattostr(lDicomData.PatientPosX)+kTab+floattostr(lDicomData.PatientPosY)+kTab+floattostr(lDicomData.PatientPosZ));
+ dcmMsg ('BPP: '+inttostr(lDicomData.Allocbits_per_pixel));
+ dcmMsg ('XYZ dim:' +inttostr(lDicomData.XYZdim[1])+'/'+inttostr(lDicomData.XYZdim[2])+'/'+inttostr(lDicomData.XYZdim[3]) );
+ dcmMsg ('XYZ mm:'+floattostrf(lDicomData.XYZmm[1],ffFixed,8,2)+'/'+floattostrf(lDicomData.XYZmm[2],ffFixed,8,2)+'/'+floattostrf(lDicomData.XYZmm[3],ffFixed,8,2) );
+ dcmMsg ('DTI bvalue:'+ inttostr(lDICOMdata.DTI[1].bval));
+ dcmMsg ('DTI bvec:'+floattostrf(lDicomData.DTI[1].v1,ffFixed,8,2)+'/'+floattostrf(lDicomData.DTI[1].v2,ffFixed,8,2)+'/'+floattostrf(lDicomData.DTI[1].v3,ffFixed,8,2) );
end;
- //msg('abba'+inttostr(lDICOMdata.CompressOffset)+' '+inttostr(lDICOMdata.CompressSz));
+ //dcmMsg('abba'+inttostr(lDICOMdata.CompressOffset)+' '+inttostr(lDICOMdata.CompressSz));
666:
- //if not lHdrOk then Msg('zx'+lFilename);
+ //if not lHdrOk then dcmMsg('zx'+lFilename);
if lDiskCacheSz > 0 then
freemem(lDiskCacheRA);
if not lHdrOK then lImageFormatOK := false;
@@ -6347,4 +6535,4 @@ if lVerboseRead then begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/dicomcompat.pas b/dcm2nii/dicomcompat_28June.pas
old mode 100644
new mode 100755
similarity index 93%
copy from dcm2nii/dicomcompat.pas
copy to dcm2nii/dicomcompat_28June.pas
index 2f3a5f6..d3ad4e3
--- a/dcm2nii/dicomcompat.pas
+++ b/dcm2nii/dicomcompat_28June.pas
@@ -82,6 +82,16 @@ begin
result := sec;
end;
+function AddIndent(lIndent: integer): string;
+var
+ i: integer;
+begin
+ result := '';
+ if lIndent < 1 then
+ exit;
+ //for i := 1 to lIndent do
+ result := result +'|';
+end;
procedure read_ecat_data(var lDICOMdata: DICOMdata;lVerboseRead,lReadECAToffsetTables:boolean; var lHdrOK, lImageFormatOK: boolean; var lDynStr: string;lFileName: string);
label
@@ -691,7 +701,7 @@ end else if (not lFLoat) and (lDicomData.Allocbits_per_pixel > 16) then begin
lImageFormatOK := false;
end else if (lFloat) then begin //zebra change float check
//Msg('WARNING: The image '+lFileName+' uses floating point [real] numbers. The current software can only read integer data type Interfile images.');
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
//lImageFormatOK := false;
end;
333:
@@ -829,7 +839,7 @@ repeat
end;
3:begin
lDicomData.Allocbits_per_pixel := 32;
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
end;
else begin
lHdrEnd := true;
@@ -1059,7 +1069,7 @@ until (linPos >= FileSz) or (lHdrEnd){EOF(fp)};
//xlDicomData.Rotate180deg := true;
lImageFormatOK := true;
if (lFloat) then begin //zebra change float check
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
//lImageFormatOK := false;
end;
333:
@@ -2581,7 +2591,7 @@ begin
6: lDicomData.Allocbits_per_pixel := 64; //double
end;
if (lDT0 = 5) or (lDT0 = 6) then
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
//xlDicomData.Storedbits_per_pixel := lDicomData.Allocbits_per_pixel;
//lImgNC_Type := lDT0;
end;
@@ -3160,11 +3170,21 @@ begin
result := strtoint(S);
end; *)
+function ExpectedDicomBytes (var lDICOMdata: DICOMdata): integer;
+begin
+ if lDicomData.JPEGLosslessCpt then begin
+ result := 0; //actual compressed size unknown
+ exit;
+ end;
+ result := lDicomdata.XYZdim[1]*lDicomdata.XYZdim[2]*lDicomdata.XYZdim[3]*(lDicomData.Allocbits_per_pixel DIV 8);
+end;
+
procedure read_dicom_data_compat(lReadJPEGtables,lVerboseRead,lAutoDECAT7,lReadECAToffsetTables,lAutoDetectInterfile,lAutoDetectGenesis,lReadColorTables: boolean; var lDICOMdata: DICOMdata; var lHdrOK, lImageFormatOK: boolean; var lDynStr: string;var lFileName: string; var lPrefs: TPrefs);
label 666,777;
const
-kMaxTextBuf = 50000; //maximum for screen output
-kDiskCache = 16384; //size of disk buffer
+ kMaxTextBuf = 50000; //maximum for screen output
+ kDiskCache = 16384; //size of disk buffer
+ kNaNsingle : single = 1/0;
type
dicom_types = (unknown, i8, i16, i32, ui8, ui16, ui32, _string{,_float} );
@@ -3412,8 +3432,12 @@ begin
remaining := 0;
//compute Distance between current slice and 1st slice...
lDx := sqrt( sqr(lX-lDicomData.PatientPosX)+sqr(lY-lDicomData.PatientPosY)+sqr(lZ-lDicomData.PatientPosZ));
- if (lDx > 0) and (lDx < lMinDistance) then //if 0 then this is a repeat, not a new slice
- lMinDistance := lDx;
+ if (lDx > 0) and (lMinDistance = kNaNsingle) then //first value
+ lMinDistance := lDx
+ else if (lDx > 0) and (lDx < lMinDistance) then //if 0 then this is a repeat, not a new slice
+ lMinDistance := lDx
+ else
+ exit;
end;
procedure readfloats6 (var fp: file; remaining: integer; var lOutStr: string; var lf1, lf2,lf3,lf4,lf5,lf6: double; var lReadOK: boolean);
@@ -3850,12 +3874,20 @@ begin
FreeMem( buff);
dseek(fp, lStartPos);
end;
-var lPrev0020: boolean;
+label 1234;
+var lIndent: integer;
+ lprevGroup, lprevElement: uint32;
+var lInside00209113, lInside2005140F, lPhilipsWarning: boolean;//philips can list two DIFFERENT spatial positions per slice - ignore the one hidden inside 2005,140FlPrev0020: boolean;
begin
//Init
//for lnVol := 1 to kMaxOrderVal do
// lDICOMdata.OrderSlope[lDICOMdata.nOrder] := 0; //show this was not set
- lPrev0020 := false;
+ lInside00209113 := false;
+ lprevGroup := 0;
+ lprevElement := 0;
+ lPhilipsWarning := false;
+ lIndent := 0;
+ lInside2005140F := false;
lSwitchToImplicitAfterGroup0002 := false;
lGELX := false;
lByteSwap := false;
@@ -3863,7 +3895,7 @@ begin
Clear_Dicom_Data(lDICOMdataBackUp);
lDicomData.XYZdim[1] := 1;
lImagePositionPatientRead := false;// for 4D files, we need first volume
- l4DDistanceBetweenSliceCenters := maxint;
+ l4DDistanceBetweenSliceCenters := kNaNsingle;
lEchoNum := 0;
lThickness := 0;
lTestError := false;
@@ -4578,13 +4610,15 @@ end; //not first_one or explicit
if e_len = ($FFFFFFFF) then begin
e_len := 0;
end;
-if lGELX then begin
- e_len := e_len and $FFFF;
-end;
+ if lGELX then begin
+ e_len := e_len and $FFFF;
+ end;
first_one := false;
remaining := e_len;
info := '?';
tmpstr := '';
+ //10b1 if (lIndent > 0) and (not ((group= $FFFE) and (element = $E0DD))) and (not lManufacturerIsPhilips) then
+ // goto 1234; //Philips stores slice positioning inside 0020,9113; lice orientation inside 0020,9116 but Siemens stores thumbnails in indented subheadings
case group of
$0001 : // group for normal reading elscint DICOM
@@ -4612,9 +4646,10 @@ end;
else TmpStr := TmpStr +('.');
FreeMem( buff);
lStr := '';
+ //Msg(TmpStr);
if TmpStr = '1.2.840.113619.5.2' then begin
lGELX := true;
- LBigSet := true;
+ LBigSet := true;
lBig := true;
end;
//
@@ -4624,6 +4659,7 @@ end;
// explicitVR := false; //china
lSwitchToImplicitAfterGroup0002 := true;
end;
+
if length(TmpStr) >= 19 then begin
if TmpStr[19] = '1' then begin
@@ -4636,20 +4672,18 @@ end;
lBig := true;
end else if TmpStr[19] = '4' then begin
if length(TmpStr) >= 21 then begin
- //lDicomData.JPEGCpt := true;
- if not lReadJPEGtables then begin
+ //Dec 2012.... dcm2nii can handle JPEG 123456
+ if {not lReadJPEGtables} false then begin
lImageFormatOK := false;
end else begin
i := strtoint(TmpStr[21]+TmpStr[22]);
- //if (TmpStr[22] <> '0') or ((TmpStr[21] <> '7') or (TmpStr[21] <> '0'))
-
-
if (i <> 57) and (i <> 70) then begin
lImageFormatOK := false;
//lDicomData.JPEGLossyCpt := true
end else begin
- //lImageFormatOK := false;//x
+
+ //lImageFormatOK := false;//123456
lDicomData.JPEGLosslessCpt := true;
end;
end;
@@ -4662,7 +4696,7 @@ end;
lImageFormatOK := false;
end;
if not lImageFormatOK then
- Msg('Unsupported Transfer Syntax '+(TmpStr)+' Solution: use MRIcro');
+ Msg('Unsupported Transfer Syntax '+(TmpStr)+' Solution: use MRIcro');
end; {length}
remaining := 0;
@@ -4694,25 +4728,25 @@ end;
$05 : info := 'Specific Character Set';
$08 : begin
info := 'Image Type';
- //Only read last word, e.g. 'TYPE\MOSAIC' will be read as 'MOSAIC'
- TmpStr := '';
if dFilePos(fp) > (filesz-e_len) then goto 666;
- GetMem( buff, e_len);
- dBlockRead(fp, buff{^}, e_len, n);
- i := e_len -1;
- while (i>-1) and (Char(buff[i]) in ['a'..'z','A'..'Z',' ']) do begin
- if (Char(buff[i])) <> ' ' then //strip filler characters: DICOM elements must be padded for even length
- TmpStr := upcase(Char(buff[i]))+TmpStr;
+ lSiemensMosaic0008_0008:= false;
+ if (e_len >= 6) then begin //search for 'MOSAIC'
+ GetMem( buff, e_len);
+ dBlockRead(fp, buff{^}, e_len, n);
+ i := e_len -6;//MOSAIC
+ while (i>-1) and (not lSiemensMosaic0008_0008) do begin
+ if (upcase(Char(buff[i])) = 'M') and (upcase(Char(buff[i+1])) = 'O')
+ and (upcase(Char(buff[i+2])) = 'S') and (upcase(Char(buff[i+3])) = 'A')
+ and (upcase(Char(buff[i+4])) = 'I') and (upcase(Char(buff[i+5])) = 'C')
+ then //strip filler characters: DICOM elements must be padded for even length
+ lSiemensMosaic0008_0008 := true;
dec(i);
- end;
- FreeMem( buff);
- remaining := 0;
- e_len := 0; {use tempstr}
- if TmpStr = 'MOSAIC' then begin
- lSiemensMosaic0008_0008:= true;
- //if lMatrixSz < 1 then lMatrixSz := 64;//B13
- end;
- end;
+ end;
+ FreeMem( buff);
+ remaining := 0;
+ e_len := 0; {use tempstr}
+ end;
+ end;
$10 : info := 'Recognition Code';
$12 : info := 'Instance Creation Date';
$13 : info := 'Instance Creation Time';
@@ -4772,6 +4806,7 @@ end;
if lManufacturerIsPhilips then
lDicomData.ManufacturerID := kPhilipsID;
+
if (length(TmpStr) > 3) and (TmpStr[1]='G') and (TmpStr[2]='E') then
lDicomData.ManufacturerID := kGEID;
if (length(TmpStr) > 3) and (TmpStr[1]='S') and (TmpStr[2]='I') and (TmpStr[3]='E') then
@@ -4928,7 +4963,7 @@ end;
readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
if not lrOK then goto 666;
e_len := 0; remaining := 0;
- //lDicomData.kV := lFloat1;
+ lDicomData.kV := lFloat1;
end;
$70: begin t := _string; info := 'Counts Accumulated'; end;
@@ -5158,6 +5193,7 @@ end;
$7048: info := 'Grid Period';
$7050: info := 'Filter Material LT';
$7060: info := 'Exposure Control Mode';
+ //$9114: fx(1233);
end;
$0019: begin
(*case element of //1362
@@ -5186,6 +5222,20 @@ $0019: begin
if lDicomData.ManufacturerID = kSiemensID then begin
case element of //1362
+ (*$100A: begin //unsigned short $100A
+ info := 'Number Of Images in Mosaic';
+ tmp := read16(fp,lrOK);
+ if not lrOK then goto 666;
+ fx(e_len,tmp,remaining);
+
+ end;*)
+ $1028: begin //7/2013
+ info := 'Siemens BandwidthPerPixelPhaseEncode';
+ lDICOMdata.BandwidthPerPixelPhaseEncode := read64 (fp,lrOK);
+ if not lrOK then goto 666;
+ e_len := 0; remaining := 0;
+ end; // b-values
+
$000C,$100C: begin
info := 'Siemens b-value';
readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
@@ -5280,22 +5330,32 @@ $0020 :
$32 : begin
info := 'Image Position Patient';
//June 2009 - for Philips new 4D format we want value from the first slice...
- if lPrev0020 then begin //5/2012: Philips R3.2.2 can save two instances of 0020:0032 for each slice: one from voxel center, one from voxel edge.
- if not lImagePositionPatientRead then begin
- readfloats3 (fp, remaining, lDummyStr, lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ, lROK);
- //fx( lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ,56789);
- if not lrOK then goto 666;
- e_len := 0;
- remaining := 0;
- lImagePositionPatientRead := true;
- //we assume Philips reports the slice thickness correctly....
- //an alternative would be to read both 1st and 2nd ImagePositionPatient and
- //compute the function DICOMinterslicedistance
+
+ if lInside2005140F then begin
+ if not (lPhilipsWarning) then
+ Msg('*User: check slice thickness. Possible Philips R3.2.2 bug - scanner can report different 0020,0032 values for the same slice.');
+ lPhilipsWarning := true;
end else begin
+ //5/2012: Philips R3.2.2 can save two instances of 0020:0032 for each slice: one from voxel center, one from voxel edge.
+
+ if not lImagePositionPatientRead then begin
+ readfloats3 (fp, remaining, lDummyStr, lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ, lROK);
+ //fx( lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ,56789);
+ if not lrOK then goto 666;
+ e_len := 0;
+ remaining := 0;
+ lImagePositionPatientRead := true;
+ //we assume Philips reports the slice thickness correctly....
+ //an alternative would be to read both 1st and 2nd ImagePositionPatient and
+ //compute the function DICOMinterslicedistance
+ end else begin
+
CheckIntersliceDistance(l4DDistanceBetweenSliceCenters);
- end;
- end;
+ end; //not 1st read
+
+ end; //if lInside2005140F
+ //lInside2005140F := false;
end;
$35 : info := 'Image Orientation';
$37 : begin //nifti
@@ -5341,6 +5401,7 @@ $0020 :
$4000: info := 'Image Comments';
$5000: info := 'Original Image ID';
$5002: info := 'Original Image... Nomenclature';
+ //$9113: xxxx
end;
$0021:case element of
$104F: begin
@@ -5473,18 +5534,19 @@ $0028 : begin
if tmp = 8 then lDicomData.Allocbits_per_pixel := 8
else if tmp = 12 then lDicomData.Allocbits_per_pixel := 12
else if tmp = 16 then lDicomData.Allocbits_per_pixel := 16
+ else if tmp = 32 then lDicomData.Allocbits_per_pixel := 32
else if tmp = 24 then begin
//xlDicomData.SamplesPerPixel := 3;
lDicomData.Allocbits_per_pixel := 8
end else begin
lWord := tmp;
lWord := swap(lWord);
- if lWord in [8,12,16,24] then begin
+ if lWord in [8,12,16,24,32] then begin
lDicomData.Allocbits_per_pixel := tmp;
lByteSwap := true;
end else begin
if lImageFormatOK then
- Msg('This software only reads 8, 12 and 16 bit DICOM files. This file allocates '+inttostr(tmp)+' bits per voxel.');
+ Msg('This software only reads 8, 12, 16, 24 [RGB] and 32 bit DICOM files. This file allocates '+inttostr(tmp)+' bits per voxel.');
lImageFormatOK := false;
end;
end;
@@ -5787,12 +5849,16 @@ end; //$0028
case element of
$1010: begin
//lSiemensMosaic0029_1010:= true;
+ if (lDicomData.kV = 0) then begin //Siemens uses 0029:1010 for both CT and MRI, but only MRI is in CSA format
lDicomData.CSAImageHeaderInfoPos := (dFilePos(fp));
lDicomData.CSAImageHeaderInfoSz := e_len;
+ end;
info := 'Private Sequence Delimiter ['+inttostr(dFilePos(fp))+']';
- if not lImageFormatOK
+ if not lImageFormatOK then
+ time_to_quit := TRUE;
+
//x(lDicomData.RunLengthEncoding) or ( ((lDicomData.JPEGLossycpt) or (lDicomData.JPEGLosslesscpt)) and (gECATJPEG_table_entries >= lDICOMdata.XYZdim[3]))}
- then time_to_quit := TRUE;
+
dSeek(fp, dFilePos(fp) + e_len);
tmpstr := inttostr(e_len);
remaining := 0;
@@ -5911,6 +5977,9 @@ end; //$0028
//if lDicomData.ManufacturerID = kPhilipsID then Msg(inttohex(element,4));
if lDicomData.ManufacturerID = kPhilipsID then begin
case element of
+ (* $140F: begin
+ lInside2005140F := true;
+ end;*)
$100E: begin
if e_len = 4 then begin
lPhilipsScaleSlope := read32r(fp,lrOK);
@@ -5955,20 +6024,23 @@ end; //$0028
end; // Philips RL angulation
$10b0: begin
if e_len = 4 then begin
+ //msg('2005,10b0 @ '+ inttostr(dFilePos(fp)) +' #'+inttostr(lDICOMdata.nDTIdir));
lDICOMdata.DTI[lDICOMdata.nDTIdir].v1 := read32r(fp,lrOK);
TmpStr := floattostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].v1);
t := _string;
- info :='Gradient vector [x]';
+ info :='Philips Gradient vector [x]';
if not lrOK then goto 666;
e_len := 0; remaining := 0;
end; //e_len = 4
end; //element 10b0
$10b1: begin
+
if e_len = 4 then begin
- lDICOMdata.DTI[lDICOMdata.nDTIdir].v2 := read32r(fp,lrOK);
+
+ lDICOMdata.DTI[lDICOMdata.nDTIdir].v2 := read32r(fp,lrOK);
TmpStr := floattostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].v2);
t := _string;
- info :='Gradient vector [y]';
+ info :='Philips Gradient vector [y]';
if not lrOK then goto 666;
e_len := 0; remaining := 0;
end; //e_len = 4
@@ -5978,23 +6050,57 @@ end; //$0028
lDICOMdata.DTI[lDICOMdata.nDTIdir].v3 := read32r(fp,lrOK);
TmpStr := floattostr(lDICOMdata.DTI[lDICOMdata.nDTIdir].v3);
t := _string;
- info :='Gradient vector [z]';
+ info :='Philips Gradient vector [z]';
//fx(lDICOMdata.DTI[lDICOMdata.nDTIdir].v1,lDICOMdata.DTI[lDICOMdata.nDTIdir].v2,lDICOMdata.DTI[lDICOMdata.nDTIdir].v3);
if not lrOK then goto 666;
e_len := 0; remaining := 0;
end; //e_len = 4
+
+
end; //element 10b2
+ $140f: begin
+ //msg('2005:140F@ '+inttostr(dFilePos(fp)) +' len: '+inttostr(e_len) +' '+ chr(lT0)+chr(lT1));
+ if (e_len > 8) then begin
+ e_len := 8; remaining := e_len; //qas 7/2013
+ end;
+ end;//140f
+ $1455: begin
+ //msg('2005:1455@ '+inttostr(dFilePos(fp)) +' len: '+inttostr(e_len) +' '+ chr(lT0)+chr(lT1));
+ (*if (e_len > 8) then begin
+ e_len := 8; remaining := e_len; //qas 7/2013
+ end; *)
+ end;//1455
+
end; //CASE...element
end; //if Manufacturer = Philips
end; //group 2005
$5200 : begin
case element of
$9230: begin
- if (lDicomData.ManufacturerID = kPhilipsID) and (orientation_not_visible( lDICOMdata))then
- read_philips_hidden(lFilename, dFilePos(fp),e_len,lDICOMdata);
+ //msg('5200:9230@ '+inttostr(dFilePos(fp))+' e_len '+inttostr(e_len)+' remaining '+inttostr(remaining));
+ //lverboseRead := true; //qas
+ //fx(e_len,678xx9);
+ if (e_len > 8) then begin
+ e_len := 8; remaining := e_len; //qas 7/2013
+ end;
+ (* if (lDicomData.ManufacturerID = kPhilipsID) and (orientation_not_visible( lDICOMdata))then
+ read_philips_hidden(lFilename, dFilePos(fp),e_len,lDICOMdata);*)
end //element 9230
end; //case element
end; //group 5200
+ $5400 : begin
+ case element of
+ $0100: begin
+ //can not convert sound files to images 12/2012
+ lImageFormatOK := false;
+ msg('Note: the DICOM file '+lFileName+' stores a waveform sequence (e.g. ECG) that will not be converted to an image');
+ info :='WaveformSequence';
+ //fx(lDICOMdata.DTI[lDICOMdata.nDTIdir].v1,lDICOMdata.DTI[lDICOMdata.nDTIdir].v2,lDICOMdata.DTI[lDICOMdata.nDTIdir].v3);
+ if not lrOK then goto 666;
+ e_len := 0; remaining := 0;
+ end //element 0100
+ end; //case element
+ end; //group 5400
$DDFF : begin
case element of
$00E0: begin
@@ -6006,6 +6112,14 @@ end; //$0028
$FFFE : begin
case element of
$E000 : begin
+ //if (lIndent > 3) then lverboseRead := false; //qas
+ inc(lIndent);
+ //msg('FFFE:E000@ '+inttostr(dFilePos(fp)) +' len: '+inttostr(e_len) +' '+ chr(lT0)+chr(lT1));
+
+ e_len := 0; remaining := e_len; //qas 7/2013
+ lInside00209113 := (lprevGroup = $0020) and (lprevelement = $9113);
+ lInside2005140F := (lprevGroup = $2005) and (lprevelement = $140F);
+ // if (lInside00209113) then fx(333);
(*iif lJPEGEntries > 17 then
lTestError := true;
@@ -6053,9 +6167,10 @@ lProprietaryImageThumbnail := false; //1496
lFirstFragment := false;//Dec09
lDICOMdataBackUp := lDICOMData;//Dec09
- if (e_len >= (lDicomData.XYZdim[1]*lDicomData.XYZdim[2])){Apr 2011} and (lDicomData.XYZdim[1]> 1) then begin
+ if ((e_len > 1024) and ((lDicomData.JPEGLosslessCpt)) or (e_len >= (lDicomData.XYZdim[1]*lDicomData.XYZdim[2]))){Apr 2011} and (lDicomData.XYZdim[1]> 1) then begin
lDICOMdata.CompressOffset := dFilePos(fp);
lDICOMdata.CompressSz := e_len;
+
Time_To_Quit := true;
//msg('abba'+inttostr(lDICOMdata.CompressOffset)+' '+inttostr(lDICOMdata.CompressSz));
end;
@@ -6069,6 +6184,9 @@ lProprietaryImageThumbnail := false; //1496
e_len := 0;
end;
$E0DD : begin
+ if (lIndent > 0) then dec(lIndent);
+ lInside00209113 := false;
+ lInside2005140F := false;
info := 'Sequence Delimiter';
if (lDICOMdata.XYZdim[1]<lDICOMdataBackUp.XYZdim[1]) then begin
lDICOMData := lDICOMdataBackUp;
@@ -6076,7 +6194,6 @@ lProprietaryImageThumbnail := false; //1496
//lDICOMData := lDICOMdataBackUp;
end else if not lImageFormatOK then begin
//x(lDicomData.RunLengthEncoding) or ( ((lDicomData.JPEGLossycpt) or (lDicomData.JPEGLosslesscpt)) and (gECATJPEG_table_entries >= lDICOMdata.XYZdim[3])) then
-
time_to_quit := TRUE;
end;
//RLE ABBA
@@ -6111,12 +6228,13 @@ lProprietaryImageThumbnail := false; //1496
$10 : begin
info := 'Pixel Data';
TmpStr := inttostr(e_len);
- if (lDICOMdata.XYZdim[1]<lDICOMdataBackUp.XYZdim[1]) then begin
+ //Showmsg(inttostr(ExpectedDicomBytes(lDicomData) ) +' '+ inttostr(e_len));
+ if ((ExpectedDicomBytes(lDicomData) ) > e_len) or (lDICOMdata.XYZdim[1]<lDICOMdataBackUp.XYZdim[1]) then begin
lDICOMData := lDICOMdataBackUp;
- dSeek(fp, dFilePos(fp) + e_len);
- //lDICOMData := lDICOMdataBackUp;
- end else if {(not lDicomData.RunLengthEncoding) and} (not lDicomData.JPEGLossycpt) and (not lDicomData.JPEGLosslesscpt) then begin
- time_to_quit := TRUE;
+ dSeek(fp, dFilePos(fp) + e_len);
+ //lDICOMData := lDICOMdataBackUp;
+ end else if {(not lDicomData.RunLengthEncoding) and} (not lDicomData.JPEGLossycpt) and (not lDicomData.JPEGLosslesscpt) then begin
+ time_to_quit := TRUE;
//xlDicomData.ImageSz := e_len;
end;
@@ -6138,12 +6256,9 @@ lProprietaryImageThumbnail := false; //1496
end;
lStr := '';
- if group = $0020 then
- lPrev0020 := true
- else
- lPrev0020 := false;
-
-
+ 1234:
+ lprevGroup := Group;
+ lprevElement := element;
if (Time_TO_Quit) and (not lImageFormatOK) then begin
lHdrOK := true;
goto 666;
@@ -6250,7 +6365,8 @@ if length(lDynStr) > kMaxTextBuf then begin
//goto 666;
end else
lDynStr := lDynStr+IntToHex(group,4)+','+IntToHex(element,4)+','+Info+'='+lStr+kCR ;
- Msg(IntToHex(group,4)+','+IntToHex(element,4)+','+inttostr(e_len)+'@'+inttostr(dfilepos(fp))+','+Info+'='+lStr);
+
+ Msg(AddIndent(lIndent)+IntToHex(group,4)+','+IntToHex(element,4)+','+inttostr(e_len)+'@'+inttostr(dfilepos(fp))+','+Info+'='+lStr);
end; //not verbose read
end; // end for
@@ -6272,7 +6388,7 @@ if lByteSwap then begin
//xByteSwap(lDicomData.Storedbits_per_pixel);
end;
-if (lDICOMdata.ManufacturerID = kPhilipsID) and (l4DDistanceBetweenSliceCenters <> MaxInt) then //some 3D and 4D Philips files do not correctly report interslice distance in 0018,0088 and 0018,0050...
+if (lDICOMdata.ManufacturerID = kPhilipsID) and (l4DDistanceBetweenSliceCenters <> kNaNsingle) then //some 3D and 4D Philips files do not correctly report interslice distance in 0018,0088 and 0018,0050...
lDICOMdata.XYZmm[3] := (l4DDistanceBetweenSliceCenters);
if (lPrefs.PhilipsPrecise) and (lManufacturerIsPhilips) and (lPhilipsScaleSlope <> 0) then begin
PhilipsPrecise (lDicomData.IntenScale, lDICOMdata.intenIntercept,lPhilipsScaleSlope, lDicomData.IntenScale, lDICOMdata.intenIntercept,true);
@@ -6322,10 +6438,12 @@ if lManufacturerIsBruker then
if (lEchoNum > 0) and (lEchoNum < 16) then begin
lDicomData.AcquNum := lDicomData.AcquNum + (1000*lEchoNum);
-end;
+end;
+
if lVerboseRead then begin
+ // lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ
Msg ('DICOM data');
- Msg ('Image Series/Number/Xpos/YPos/ZPos:'+kTab+inttostr(lDicomData.AcquNum)+kTab+inttostr(lDicomData.ImageNum)+kTab+floattostr(lDicomData.PatientPosX)+kTab+floattostr(lDicomData.PatientPosY)+kTab+floattostr(lDicomData.PatientPosZ));
+ Msg ('Series/Acquisition/Image/Xpos/YPos/ZPos:'+kTab+inttostr(lDicomData.SeriesNum)+kTab+inttostr(lDicomData.AcquNum)+kTab+inttostr(lDicomData.ImageNum)+kTab+floattostr(lDicomData.PatientPosX)+kTab+floattostr(lDicomData.PatientPosY)+kTab+floattostr(lDicomData.PatientPosZ));
Msg ('BPP: '+inttostr(lDicomData.Allocbits_per_pixel));
Msg ('XYZ dim:' +inttostr(lDicomData.XYZdim[1])+'/'+inttostr(lDicomData.XYZdim[2])+'/'+inttostr(lDicomData.XYZdim[3]) );
Msg ('XYZ mm:'+floattostrf(lDicomData.XYZmm[1],ffFixed,8,2)+'/'+floattostrf(lDicomData.XYZmm[2],ffFixed,8,2)+'/'+floattostrf(lDicomData.XYZmm[3],ffFixed,8,2) );
@@ -6347,4 +6465,4 @@ if lVerboseRead then begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/dicomfast.pas b/dcm2nii/dicomfast.pas
old mode 100644
new mode 100755
index 7db0a4a..234a460
--- a/dcm2nii/dicomfast.pas
+++ b/dcm2nii/dicomfast.pas
@@ -18,7 +18,7 @@ interface
uses
{$IFNDEF FPC}Controls, {$ENDIF}
- SysUtils,define_types,classes,dicomtypes;
+ SysUtils,define_types,classes,dicomtypes,dialogs_msg;
function fast_read_dicom_data(var lDICOMdata: DICOMdata; lOffset: integer; var lFileName: string): boolean; //x3 faster!
@@ -130,9 +130,9 @@ begin
if (lFilePos < 0) or (lFilePos > lFileSz) then begin
lBuffStart := lFilePos;
lBufPos := 1;
- msg(lFileName);
+ dcmMsg(lFileName);
lFailure := true;
- Msg('Error: buffer overrun in DICOM read.');
+ dcmMsg('Error: buffer overrun in DICOM read.');
exit;
end;
if lFilePos+kMaxBuf > lFileSz then
@@ -366,7 +366,7 @@ begin //function fast_read_dicom_data
lPos := lOffset;
if lOffset = 128 then begin //DICOM files start with DICM at 128, Siemens shadow headers do not
if DCMStr(4) <> 'DICM' then begin
- Msg(DCMStr(4)+ ' <> DICM');
+ dcmMsg(DCMStr(4)+ ' <> DICM');
FreeMem(lByteRA);
exit;
end;
@@ -374,12 +374,12 @@ begin //function fast_read_dicom_data
end;//Offset = 128
//next check VR
if not( chr(GetByte(lPos+4)) in ['A'..'Z']) or not( chr(GetByte(lPos+5)) in ['A'..'Z']) then
- Msg('implicit VR untested');
+ dcmMsg('implicit VR untested');
//next check Endian
lTemp := lPos;
ReadGroupElementLength(lGroupElement,lLength);
if lLength > kMax16bit then
- Msg('ByteSwapped');
+ dcmMsg('ByteSwapped');
lPos := lTemp;
//end VR check
while (lDICOMData.imagestart = 0) and (not lBufferError) do begin
@@ -474,7 +474,7 @@ begin //function fast_read_dicom_data
FreeMem(lByteRA);
//Remaining portions only if anonymizing
{$IFDEF ANON}
- Msg('Anonymizing DICOM '+extractfilename(lFilename));
+ dcmMsg('Anonymizing DICOM '+extractfilename(lFilename));
lBufferSz := lFileSz;
GetMem(lByteRA,lBufferSz);
//read original
@@ -509,4 +509,4 @@ begin //function fast_read_dicom_data
end; //function fast_read_dicom_data
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/dicomfastread.pas b/dcm2nii/dicomfastread.pas
old mode 100644
new mode 100755
index 3e08f05..f6d1ca4
--- a/dcm2nii/dicomfastread.pas
+++ b/dcm2nii/dicomfastread.pas
@@ -15,17 +15,15 @@ interface
//0019,10bd (or 0019,a0bd)= Z diffusion direction
//0018,1312 = phase encoding.
-
uses
{$IFNDEF FPC}Controls, {$ENDIF}
SysUtils,define_types,classes,dicomtypes;
-
function fast_read_dicom_datax(var lDICOMdata: DICOMdata; lOffset,lFileSz: integer; var lFileName: string): boolean; //x3 faster!
procedure read_philips_hidden(var lFilename: string; lOffset,lLength: integer; var lDICOMdata: DICOMdata);
function orientation_not_visible( lDICOMdata: DICOMdata) : boolean;
implementation
-uses dialogsx;
+uses dialogsx, dialogs_msg;
{$DEFINE notANON}
function fast_read_dicom_datax(var lDICOMdata: DICOMdata; lOffset,lFileSz: integer; var lFileName: string): boolean;
@@ -75,6 +73,10 @@ const
kPhilipsPhantom1 = $91130020;//$0020+($9113 shl 16 );
kPhilipsPhantom2 = $91160020;
kPhilipsPhantom3 = $91100028;
+ kPhilipsDTIv1 = $10b02005;
+ kPhilipsDTIv2 = $10b12005;
+ kPhilipsDTIv3 = $10b22005;
+
kMaxFloats = 6;
var
vr : array [1..2] of Char;
@@ -259,6 +261,23 @@ begin
result := GetByte(lPos)+(GetByte(lPos+1) shl 8)+(GetByte(lPos+2) shl 16)+(GetByte(lPos+3) shl 24);; //byte order??
end; //function DCMint
+function DCMsingle (lBytes: integer): single; //read 16 bit short integer
+type
+ swaptype = packed record
+ case byte of
+ 0:(b0,b1,b2,b3 : word); //word is 16 bit
+ 1:(float:single);
+ end;
+var
+ outguy:swaptype;
+begin
+ outguy.b0 := GetByte(lPos);
+ outguy.b1 := GetByte(lPos+1);
+ outguy.b2 := GetByte(lPos+2);
+ outguy.b3 := GetByte(lPos+3);
+ result:=outguy.float;
+end;
+
{$IFDEF ANON}
Type
TPosLen = RECORD //peristimulus plot
@@ -354,7 +373,7 @@ begin //function fast_read_dicom_data
lPos := lOffset;
if lOffset = 128 then begin //DICOM files start with DICM at 128, Siemens shadow headers do not
if DCMStr(4) <> 'DICM' then begin
- Msg(DCMStr(4)+ ' <> DICM');
+ dcmMsg(DCMStr(4)+ ' <> DICM');
FreeMem(lByteRA);
exit;
end;
@@ -362,12 +381,12 @@ begin //function fast_read_dicom_data
end;//Offset = 128
//next check VR
if not( chr(GetByte(lPos+4)) in ['A'..'Z']) or not( chr(GetByte(lPos+5)) in ['A'..'Z']) then
- Msg('implicit VR untested');
+ dcmMsg('implicit VR untested');
//next check Endian
lTemp := lPos;
ReadGroupElementLength(lGroupElement,lLength);
if lLength > kMax16bit then
- Msg('ByteSwapped');
+ dcmMsg('ByteSwapped');
lPos := lTemp;
//end VR check
result := true;
@@ -445,6 +464,7 @@ begin //function fast_read_dicom_data
lDICOMdata.CSAImageHeaderInfoSz := lLength;
end;
kSlicesPer3DVol: lDICOMData.SlicesPer3DVol := DCMint (lLength);
+
kImageStart: lDICOMData.ImageStart := lPos ; //-1 as indexed from 0.. not 1..
end; //Case lGroupElement
//Msg(VR+inttohex(lGroupElement and kMax16bit,4) +':'+inttohex( lGroupElement shr 16,4)+' '+inttostr(lLength)+'@'+inttostr(lPos) );
@@ -525,16 +545,16 @@ var
li : integer;
lDICOMdataX: DICOMdata;
begin
- if not fast_read_dicom_datax(lDICOMdataX, lOffset+8, lOffset+lLength, lFileName) then exit;
+ if not fast_read_dicom_datax(lDICOMdataX, lOffset+8, lOffset+lLength, lFileName) then exit;
//fx(lDICOMdataX.XYZmm[1],lDICOMdataX.XYZmm[2]);
- for li := 1 to 2 do //only XY-direction - as philips reports correct Z in header
+ for li := 1 to 2 do //only XY-direction - as philips reports correct Z in header
lDICOMdata.XYZmm[li] := lDICOMdataX.XYZmm[li];
- for li := 1 to 6 do
- lDicomData.Orient[li] := lDicomDataX.Orient[li];
- lDicomData.PatientPosX := lDicomDataX.PatientPosX;
- lDicomData.PatientPosY := lDicomDataX.PatientPosY;
- lDicomData.PatientPosZ := lDicomDataX.PatientPosZ;
+ for li := 1 to 6 do
+ lDicomData.Orient[li] := lDicomDataX.Orient[li];
+ lDicomData.PatientPosX := lDicomDataX.PatientPosX;
+ lDicomData.PatientPosY := lDicomDataX.PatientPosY;
+ lDicomData.PatientPosZ := lDicomDataX.PatientPosZ;
end;
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/dicomtypes.pas b/dcm2nii/dicomtypes.pas
old mode 100644
new mode 100755
index 7b2199c..537665e
--- a/dcm2nii/dicomtypes.pas
+++ b/dcm2nii/dicomtypes.pas
@@ -12,8 +12,8 @@ const
kGEID = 1;
kPhilipsID = 2;
kSiemensID = 3;
- kMaxDTIDir = 1024;//Maximum DTI directions
- kMaxOrderVal = 1024;
+ kMaxDTIDir = 4095;//Maximum DTI directions
+ kMaxOrderVal = 4095;
type
TDTI = record
v1,v2,v3: double; //4=volume, eg time: some EC*T7 images
@@ -29,9 +29,9 @@ end;
XYZori: array [1..3] of integer;
XYZmm: array [1..3] of double;
Orient: array [1..6] of double;
- SignedData,SiemensDICOMDTICSA,SiemensDICOMDTI,Float,file4D,JPEGLossyCpt,JPEGLosslessCpt: boolean;
+ SignedData,SiemensDICOMDTICSA,SiemensDICOMDTI,FloatData,file4D,JPEGLossyCpt,JPEGLosslessCpt: boolean;
SecSinceMidnight,PatientPosX,PatientPosY,PatientPosZ,AngulationAP,AngulationFH,AngulationRL: double;
- TE, TR,IntenScale,IntenIntercept,location{,DTIv1,DTIv2,DTIv3}: single;
+ BandwidthPerPixelPhaseEncode, kV,TE, TR,IntenScale,IntenIntercept,location{,DTIv1,DTIv2,DTIv3}: single;
{Bval,}SlicesPer3DVol,SiemensInterleaved {0=no,1=yes,2=not defined},SiemensSlices,SiemensMosaicX,SiemensMosaicY,
nOrder,nDTIdir,AcquNum,ImageNum,SeriesNum,ImageStart,little_endian,Allocbits_per_pixel,SamplesPerPixel,
CSAImageHeaderInfoPos,CSAImageHeaderInfoSz,ManufacturerID,PlanarConfig, //ImplementationVersion,
@@ -203,7 +203,7 @@ function DICOMstr (i: integer; var lDICOMra: TDICOMrap): string; overload;
implementation
-uses dicom,sysutils,define_types,dialogsx;
+uses dicom,sysutils,define_types,dialogsx,dialogs_msg;
function YearsOld (lDICOM: DICOMdata): single;
var
@@ -250,12 +250,12 @@ end;
procedure PartialAcquisitionError;
begin
- Msg('* Potential partial acquisition or improper segmentation of files');
+ dcmMsg('* Potential partial acquisition or improper segmentation of files');
{$IFDEF GUI}
- Msg('* Possible solution: check ''Collapse folders'' in Help/Preferences and select directory that contains all images in subfolders');
+ dcmMsg('* Possible solution: check ''Collapse folders'' in Help/Preferences and select directory that contains all images in subfolders');
{$ELSE}
- Msg('* Possible solution: use -c Y and use folder containing subdirectories as input');
- Msg('* or change .ini file to read: CollapseFolders=1');
+ dcmMsg('* Possible solution: use -c Y and use folder containing subdirectories as input');
+ dcmMsg('* or change .ini file to read: CollapseFolders=1');
{$ENDIF}
end;
@@ -474,7 +474,7 @@ begin
try
lFloatRA[lnF] := strtofloat(lFStr);
except on EConvertError do
- Msg('Unable to interpret '+lNumarisTag+ ' in '+extractfilename(lFilename));
+ dcmMsg('Unable to interpret '+lNumarisTag+ ' in '+extractfilename(lFilename));
end;//except
if lnF = lnFloats then begin
result := true;
@@ -562,7 +562,7 @@ begin //a 96x96 mosaic is usually saved as '64*64', but in B13 you can see '96p*
if not result then exit;
lI1 := round(lFloatRA[1]);
lI2 := round(lFloatRA[2]);
- //Msg(lvStr+' '+floattostr( lI1)+'x'+inttostr(lI2));
+ //dcmMsg(lvStr+' '+floattostr( lI1)+'x'+inttostr(lI2));
end;
begin // GetCSAImageHeaderInfoRaw
@@ -579,7 +579,7 @@ begin // GetCSAImageHeaderInfoRaw
lf3 := 0;//impossible, therefore not DTI
GetMem(lByteRA,lLength);
AssignFile(lInFile, lFileName);
- //Msg('fz '+lFilename);
+ //dcmMsg('fz '+lFilename);
FileMode := 0; //Set file access to read only
Reset(lInFile, 1);
seek(lInFile,lStart);
@@ -629,6 +629,7 @@ begin
Orient[lI] := 0;
DateTime := BogusDateTime;
ManufacturerID := 0;
+ kV := 0;
//ImplementationVersion := 0;
Vers0018_1020 := 0;
AngulationFH := 0;
@@ -670,7 +671,7 @@ begin
//MaxIntensity := 0;
//MinIntensity := 0;
//MinIntensitySet := false;
- Float := false;
+ FloatData := false;
ImageNum := -1;
SlicesPer3DVol := 0;
SiemensInterleaved := 2; //0=no,1=yes,2=undefined
@@ -719,6 +720,8 @@ begin
SignedData := true;
CompressOffset := 0;
CompresssZ := 0;
+ BandwidthPerPixelPhaseEncode := 0; //7/2013
+
end;
end;
@@ -731,4 +734,4 @@ begin
end;
end.
-
+
\ No newline at end of file
diff --git a/dcm2nii/diskfree.pas b/dcm2nii/diskfree.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/example/attention.nii.gz b/dcm2nii/example/attention.nii.gz
deleted file mode 100644
index 9944ff9..0000000
Binary files a/dcm2nii/example/attention.nii.gz and /dev/null differ
diff --git a/dcm2nii/example/cutr.ini b/dcm2nii/example/cutr.ini
deleted file mode 100644
index 1399986..0000000
--- a/dcm2nii/example/cutr.ini
+++ /dev/null
@@ -1,23 +0,0 @@
-[BOOL]
-SmoothBG=1
-SmoothOverlay=1
-Trilinear=1
-OverlayFromBGSurface=1
-ShowCutout=1
-FlipLR=0
-[INT]
-BGNearClip=0
-OverlayNearClip=0
-Azimuth=110
-Elevation=45
-BGSurface=25
-OverlaySurface=1
-BGDepth=12
-OverlayDepth=8
-CutoutLo1=96
-CutoutHi1=181
-CutoutLo2=118
-CutoutHi2=217
-CutoutLo3=87
-CutoutHi3=181
-CutoutBias=3
diff --git a/dcm2nii/example/fmri2r.ini b/dcm2nii/example/fmri2r.ini
deleted file mode 100644
index f5831d5..0000000
--- a/dcm2nii/example/fmri2r.ini
+++ /dev/null
@@ -1,24 +0,0 @@
-[BOOL]
-SmoothBG=1
-SmoothOverlay=1
-Trilinear=1
-OverlayFromBGSurface=0
-ShowCutout=0
-FlipLR=0
-[INT]
-BGNearClip=0
-OverlayNearClip=0
-Azimuth=110
-Elevation=45
-BGSurface=25
-OverlaySurface=1
-BGDepth=8
-OverlayDepth=8
-CutoutLo1=90
-CutoutHi1=181
-CutoutLo2=118
-CutoutHi2=217
-CutoutLo3=90
-CutoutHi3=181
-OverlayFromBGSurface=0
-CutoutBias=4
diff --git a/dcm2nii/example/fmri3r.ini b/dcm2nii/example/fmri3r.ini
deleted file mode 100644
index 389a715..0000000
--- a/dcm2nii/example/fmri3r.ini
+++ /dev/null
@@ -1,22 +0,0 @@
-[BOOL]
-SmoothBG=1
-SmoothOverlay=1
-Trilinear=1
-OverlayFromBGSurface=1
-ShowCutout=0
-FlipLR=0
-[INT]
-BGNearClip=0
-OverlayNearClip=0
-Azimuth=80
-Elevation=45
-BGSurface=25
-OverlaySurface=1
-BGDepth=8
-OverlayDepth=8
-CutoutLo1=90
-CutoutHi1=181
-CutoutLo2=118
-CutoutHi2=217
-CutoutLo3=90
-CutoutHi3=181
diff --git a/dcm2nii/example/fmrir.ini b/dcm2nii/example/fmrir.ini
deleted file mode 100644
index fe5a2d4..0000000
--- a/dcm2nii/example/fmrir.ini
+++ /dev/null
@@ -1,22 +0,0 @@
-[BOOL]
-SmoothBG=1
-SmoothOverlay=0
-Trilinear=0
-OverlayFromBGSurface=1
-ShowCutout=0
-FlipLR=0
-[INT]
-BGNearClip=0
-OverlayNearClip=0
-Azimuth=80
-Elevation=45
-BGSurface=51
-OverlaySurface=1
-BGDepth=8
-OverlayDepth=12
-CutoutLo1=90
-CutoutHi1=181
-CutoutLo2=108
-CutoutHi2=217
-CutoutLo3=90
-CutoutHi3=181
diff --git a/dcm2nii/example/lesions/1.voi b/dcm2nii/example/lesions/1.voi
deleted file mode 100644
index b98f478..0000000
Binary files a/dcm2nii/example/lesions/1.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/10.voi b/dcm2nii/example/lesions/10.voi
deleted file mode 100644
index f43514a..0000000
Binary files a/dcm2nii/example/lesions/10.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/11.voi b/dcm2nii/example/lesions/11.voi
deleted file mode 100644
index 620a004..0000000
Binary files a/dcm2nii/example/lesions/11.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/12.voi b/dcm2nii/example/lesions/12.voi
deleted file mode 100644
index 4920051..0000000
Binary files a/dcm2nii/example/lesions/12.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/13.voi b/dcm2nii/example/lesions/13.voi
deleted file mode 100644
index 91aef2c..0000000
Binary files a/dcm2nii/example/lesions/13.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/14.voi b/dcm2nii/example/lesions/14.voi
deleted file mode 100644
index a014e7c..0000000
Binary files a/dcm2nii/example/lesions/14.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/15.voi b/dcm2nii/example/lesions/15.voi
deleted file mode 100644
index 8c9c714..0000000
Binary files a/dcm2nii/example/lesions/15.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/16.voi b/dcm2nii/example/lesions/16.voi
deleted file mode 100644
index a18669f..0000000
Binary files a/dcm2nii/example/lesions/16.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/17.voi b/dcm2nii/example/lesions/17.voi
deleted file mode 100644
index d6bc018..0000000
Binary files a/dcm2nii/example/lesions/17.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/18.voi b/dcm2nii/example/lesions/18.voi
deleted file mode 100644
index c9eee95..0000000
Binary files a/dcm2nii/example/lesions/18.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/19.voi b/dcm2nii/example/lesions/19.voi
deleted file mode 100644
index c349b2d..0000000
Binary files a/dcm2nii/example/lesions/19.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/2.voi b/dcm2nii/example/lesions/2.voi
deleted file mode 100644
index 1a5e9ba..0000000
Binary files a/dcm2nii/example/lesions/2.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/20.voi b/dcm2nii/example/lesions/20.voi
deleted file mode 100644
index 1cbba6b..0000000
Binary files a/dcm2nii/example/lesions/20.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/21.voi b/dcm2nii/example/lesions/21.voi
deleted file mode 100644
index 6e08d28..0000000
Binary files a/dcm2nii/example/lesions/21.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/22.voi b/dcm2nii/example/lesions/22.voi
deleted file mode 100644
index b877f26..0000000
Binary files a/dcm2nii/example/lesions/22.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/23.voi b/dcm2nii/example/lesions/23.voi
deleted file mode 100644
index 0859061..0000000
Binary files a/dcm2nii/example/lesions/23.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/24.voi b/dcm2nii/example/lesions/24.voi
deleted file mode 100644
index f6949fb..0000000
Binary files a/dcm2nii/example/lesions/24.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/3.voi b/dcm2nii/example/lesions/3.voi
deleted file mode 100644
index d9de58f..0000000
Binary files a/dcm2nii/example/lesions/3.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/4.voi b/dcm2nii/example/lesions/4.voi
deleted file mode 100644
index cbbec20..0000000
Binary files a/dcm2nii/example/lesions/4.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/5.voi b/dcm2nii/example/lesions/5.voi
deleted file mode 100644
index 390a0c3..0000000
Binary files a/dcm2nii/example/lesions/5.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/6.voi b/dcm2nii/example/lesions/6.voi
deleted file mode 100644
index 4e939ec..0000000
Binary files a/dcm2nii/example/lesions/6.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/7.voi b/dcm2nii/example/lesions/7.voi
deleted file mode 100644
index 3eff297..0000000
Binary files a/dcm2nii/example/lesions/7.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/8.voi b/dcm2nii/example/lesions/8.voi
deleted file mode 100644
index 8c24f9b..0000000
Binary files a/dcm2nii/example/lesions/8.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/9.voi b/dcm2nii/example/lesions/9.voi
deleted file mode 100644
index 1c9640b..0000000
Binary files a/dcm2nii/example/lesions/9.voi and /dev/null differ
diff --git a/dcm2nii/example/lesions/binomial.val b/dcm2nii/example/lesions/binomial.val
deleted file mode 100644
index 8b0ee6c..0000000
--- a/dcm2nii/example/lesions/binomial.val
+++ /dev/null
@@ -1,29 +0,0 @@
-#Version:0
-#Covary Volume 0
-#Template C:\template.img
-#CritPct 16
-ImageName Cancel
-1.voi 0
-2.voi 0
-3.voi 0
-4.voi 0
-5.voi 0
-6.voi 0
-7.voi 0
-8.voi 0
-9.voi 0
-10.voi 0
-11.voi 0
-12.voi 0
-13.voi 1
-14.voi 1
-15.voi 1
-16.voi 1
-17.voi 1
-18.voi 1
-19.voi 1
-20.voi 1
-21.voi 1
-22.voi 1
-23.voi 1
-24.voi 1
\ No newline at end of file
diff --git a/dcm2nii/example/lesions/continuous.val b/dcm2nii/example/lesions/continuous.val
deleted file mode 100644
index 87252bf..0000000
--- a/dcm2nii/example/lesions/continuous.val
+++ /dev/null
@@ -1,29 +0,0 @@
-#Version:0
-#Covary Volume 0
-#Template C:\template.img
-#CritPct 16
-ImageName Cancel
-1.voi 2
-2.voi 44
-3.voi 22
-4.voi 24
-5.voi 23
-6.voi 22
-7.voi 18
-8.voi 12
-9.voi 15
-10.voi 41
-11.voi 32
-12.voi 22
-13.voi 60
-14.voi 58
-15.voi 57
-16.voi 57
-17.voi 55
-18.voi 56
-19.voi 60
-20.voi 59
-21.voi 57
-22.voi 58
-23.voi 56
-24.voi 57
\ No newline at end of file
diff --git a/dcm2nii/example/saccades.nii.gz b/dcm2nii/example/saccades.nii.gz
deleted file mode 100644
index 66d166e..0000000
Binary files a/dcm2nii/example/saccades.nii.gz and /dev/null differ
diff --git a/dcm2nii/extrafpc.cfg b/dcm2nii/extrafpc.cfg
old mode 100644
new mode 100755
diff --git a/dcm2nii/filename.pas b/dcm2nii/filename.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/fpc-res.or b/dcm2nii/fpc-res.or
old mode 100644
new mode 100755
diff --git a/dcm2nii/fpc-res.res b/dcm2nii/fpc-res.res
deleted file mode 100644
index 98ec032..0000000
Binary files a/dcm2nii/fpc-res.res and /dev/null differ
diff --git a/dcm2nii/gui.dfm b/dcm2nii/gui.dfm
old mode 100644
new mode 100755
index 3aee9ac..9961827
Binary files a/dcm2nii/gui.dfm and b/dcm2nii/gui.dfm differ
diff --git a/dcm2nii/gui.lfm b/dcm2nii/gui.lfm
old mode 100644
new mode 100755
index 716b790..607a85b
--- a/dcm2nii/gui.lfm
+++ b/dcm2nii/gui.lfm
@@ -1,22 +1,22 @@
object MainForm: TMainForm
- Left = 685
+ Left = 355
Height = 363
- Top = 174
+ Top = 132
Width = 598
ActiveControl = Panel1
AllowDropFiles = True
Caption = 'dcm2nii'
- ClientHeight = 344
+ ClientHeight = 363
ClientWidth = 598
Menu = MainMenu1
OnClose = FormClose
OnCreate = FormCreate
OnDropFiles = FormDropFiles
OnShow = FormShow
- LCLVersion = '0.9.30.4'
+ LCLVersion = '1.0.2.0'
object Memo1: TMemo
Left = 4
- Height = 306
+ Height = 325
Top = 34
Width = 590
Align = alClient
@@ -50,10 +50,10 @@ object MainForm: TMainForm
end
object TypeCombo: TComboBox
Left = 160
- Height = 21
+ Height = 20
Top = 3
Width = 264
- ItemHeight = 13
+ ItemHeight = 0
Items.Strings = (
'SPM2 (3D Anlyze hdr/img)'
'SPM5 (3D NIfTI hdr/img)'
diff --git a/dcm2nii/gui.lrs b/dcm2nii/gui.lrs
old mode 100644
new mode 100755
index be15b19..6f4550d
--- a/dcm2nii/gui.lrs
+++ b/dcm2nii/gui.lrs
@@ -1,12 +1,12 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TMainForm','FORMDATA',[
- 'TPF0'#9'TMainForm'#8'MainForm'#4'Left'#3#173#2#6'Height'#3'k'#1#3'Top'#3#174
- +#0#5'Width'#3'V'#2#13'ActiveControl'#7#6'Panel1'#14'AllowDropFiles'#9#7'Capt'
- +'ion'#6#7'dcm2nii'#12'ClientHeight'#3'X'#1#11'ClientWidth'#3'V'#2#4'Menu'#7#9
+ 'TPF0'#9'TMainForm'#8'MainForm'#4'Left'#3'c'#1#6'Height'#3'k'#1#3'Top'#3#132#0
+ +#5'Width'#3'V'#2#13'ActiveControl'#7#6'Panel1'#14'AllowDropFiles'#9#7'Captio'
+ +'n'#6#7'dcm2nii'#12'ClientHeight'#3'k'#1#11'ClientWidth'#3'V'#2#4'Menu'#7#9
+'MainMenu1'#7'OnClose'#7#9'FormClose'#8'OnCreate'#7#10'FormCreate'#11'OnDrop'
- +'Files'#7#13'FormDropFiles'#6'OnShow'#7#8'FormShow'#10'LCLVersion'#6#8'0.9.3'
- +'0.4'#0#5'TMemo'#5'Memo1'#4'Left'#2#4#6'Height'#3'2'#1#3'Top'#2'"'#5'Width'#3
+ +'Files'#7#13'FormDropFiles'#6'OnShow'#7#8'FormShow'#10'LCLVersion'#6#7'1.0.2'
+ +'.0'#0#5'TMemo'#5'Memo1'#4'Left'#2#4#6'Height'#3'E'#1#3'Top'#2'"'#5'Width'#3
+'N'#2#5'Align'#7#8'alClient'#18'BorderSpacing.Left'#2#4#19'BorderSpacing.Rig'
+'ht'#2#4#20'BorderSpacing.Bottom'#2#4#10'ScrollBars'#7#14'ssAutoVertical'#8
+'TabOrder'#2#0#0#0#6'TPanel'#6'Panel1'#4'Left'#2#0#6'Height'#2'"'#3'Top'#2#0
@@ -15,12 +15,12 @@ LazarusResources.Add('TMainForm','FORMDATA',[
+'ft'#2#1#6'Height'#2#26#3'Top'#2#5#5'Width'#3#140#0#9'Alignment'#7#14'taRigh'
+'tJustify'#7'Anchors'#11#6'akLeft'#0#8'AutoSize'#8#7'Caption'#6#16'Output Fo'
+'rmat: '#6'Layout'#7#8'tlCenter'#11'ParentColor'#8#0#0#9'TComboBox'#9'TypeC'
- +'ombo'#4'Left'#3#160#0#6'Height'#2#21#3'Top'#2#3#5'Width'#3#8#1#10'ItemHeigh'
- +'t'#2#13#13'Items.Strings'#1#6#24'SPM2 (3D Anlyze hdr/img)'#6#23'SPM5 (3D NI'
- +'fTI hdr/img)'#6#19'SPM8 (3D NIfTI nii)'#6#16'4D NIfTI hdr/img'#6#23'FSL/SPM'
- +'8 (4D NIfTI nii)'#6#29'Compressed FSL (4D NIfTI nii)'#0#5'Style'#7#14'csDro'
- +'pDownList'#8'TabOrder'#2#0#0#0#0#11'TOpenDialog'#10'OpenHdrDlg'#11'FilterIn'
- +'dex'#2#0#4'left'#2#24#3'top'#2'0'#0#0#9'TMainMenu'#9'MainMenu1'#4'left'#2'X'
+ +'ombo'#4'Left'#3#160#0#6'Height'#2#20#3'Top'#2#3#5'Width'#3#8#1#10'ItemHeigh'
+ +'t'#2#0#13'Items.Strings'#1#6#24'SPM2 (3D Anlyze hdr/img)'#6#23'SPM5 (3D NIf'
+ +'TI hdr/img)'#6#19'SPM8 (3D NIfTI nii)'#6#16'4D NIfTI hdr/img'#6#23'FSL/SPM8'
+ +' (4D NIfTI nii)'#6#29'Compressed FSL (4D NIfTI nii)'#0#5'Style'#7#14'csDrop'
+ +'DownList'#8'TabOrder'#2#0#0#0#0#11'TOpenDialog'#10'OpenHdrDlg'#11'FilterInd'
+ +'ex'#2#0#4'left'#2#24#3'top'#2'0'#0#0#9'TMainMenu'#9'MainMenu1'#4'left'#2'X'
+#3'top'#2'0'#0#9'TMenuItem'#5'File1'#7'Caption'#6#4'File'#0#9'TMenuItem'#13
+'DICOMtoNIfTI1'#7'Caption'#6#14'DICOM to NIfTI'#8'ShortCut'#3'D@'#7'OnClick'
+#7#15'dcm2niiBtnClick'#0#0#9'TMenuItem'#12'ModifyNIfTI1'#7'Caption'#6#12'Mod'
diff --git a/dcm2nii/gui.pas b/dcm2nii/gui.pas
old mode 100644
new mode 100755
index f548fda..7235205
--- a/dcm2nii/gui.pas
+++ b/dcm2nii/gui.pas
@@ -2,16 +2,27 @@ unit gui;
{$IFDEF FPC}{$mode objfpc}{$H+}{$ENDIF}
interface
uses
-{$IFDEF FPC}LResources,{$ENDIF}
+
+
+
+{$IFDEF FPC}LResources,LCLIntf, {$ELSE} Messages,{$ENDIF}
{$IFNDEF UNIX} Windows,ShellAPI,ShlObj,
{$ELSE}
-BaseUnix,LCLType,
+//BaseUnix,
+LCLType,
{$ENDIF}
-Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls,
-ToolWin, ComCtrls, ExtCtrls,IniFiles,define_types,sortdicom,dicom,parconvert,
-filename, convert,userdir, paramstrs,nifti_hdr,nii_math,dicomtypes,nii_crop,
+//Messages,
+SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls,
+//ToolWin,
+//ComCtrls,
+ExtCtrls,
+//IniFiles,
+define_types,sortdicom,//dicom,
+parconvert,
+//filename,convert, nifti_hdr,ConvertSimple,
+userdir, paramstrs,nii_math,dicomtypes,nii_crop,
nii_orient, nii_4dto3d,nii_asl,nii_reslice, Menus,nii_3dto4d,prefs,
-ConvertSimple,GraphicsMathLibrary;
+GraphicsMathLibrary;
{$IFDEF FPC}
type
{ TMainForm }
@@ -249,7 +260,11 @@ var
lStartTime: DWord;
lStrings : TStrings;
begin
- DecimalSeparator := '.';
+ {$IFDEF FPC}
+ DefaultFormatSettings.DecimalSeparator := '.';
+ {$ELSE}
+ DecimalSeparator := '.';
+ {$ENDIF}
result := false;
if (not Fileexists(lFilename)) and (not DirExists(lFilename)) then
exit;
@@ -260,7 +275,7 @@ begin
refresh;
Memo1.lines.add('Converting '+lFilename);
lOutDir := extractfiledir(lFilename);
- {$IFNDEF UNIX}lStartTime := GetTickCount;{$ENDIF}
+ lStartTime := GetTickCount;
if DirExists(lFilename) then begin
RecursiveFolderSearch(lFilename,lFilename,lPrefs,0);
lPrefs.NameAppend := '';
@@ -287,10 +302,7 @@ begin
lPrefs.NameAppend := '';
end;
end;
- {$IFNDEF UNIX}Memo1.lines.add('Conversion completed in '+inttostr(GetTickCount-lStartTime)+' ms');
- {$ELSE}
- Memo1.lines.add('Conversion completed');
- {$ENDIF}
+ Memo1.lines.add('Conversion completed in '+inttostr(GetTickCount-lStartTime)+' ms');
end;
function ShowHeader (lFilename: string): boolean;
@@ -470,9 +482,20 @@ begin
Exit1.visible := false;
{$ENDIF}
{$IFNDEF UNIX}DragAcceptFiles(Handle, True);{$ENDIF}
- //Memo1.Lines.Add(kVers);
- DecimalSeparator := '.';
+ {$IFDEF FPC}
+ DefaultFormatSettings.DecimalSeparator := '.';
+ {$ELSE}
+ DecimalSeparator := '.';
+ {$ENDIF}
Application.HintHidePause := 30000;
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+ DICOMtoNIfTI1.ShortCut := ShortCut(Word('D'), [ssMeta]);
+ Copy1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ Preferences1.ShortCut := ShortCut(Word('P'), [ssMeta]);
+ About1.ShortCut := ShortCut(Word('A'), [ssMeta]);
+ {$ENDIF}//Carbon
+ {$ENDIF}//Darwin
end;
@@ -1091,7 +1114,8 @@ end;
procedure TMainForm.ExtractDICOMdims1Click(Sender: TObject);
var
- sTitle,lDirName: string;
+ {$IFNDEF FPC}sTitle,{$ENDIF}
+ lDirName: string;
lPrefs: TPrefs;
begin
CheckPrefs(lPrefs,False);
@@ -1104,13 +1128,14 @@ begin
exit;
lDirName := extractfiledir( OpenHdrDlg.Filename);
{$ENDIF}
+ Memo1.lines.Clear;
ConvertDCM2NII(lDirName,lPrefs);
end;
procedure TMainForm.ExtractDICOMhdr1Click(Sender: TObject);
var
lnVol,lVol: integer;
- lHdrName: string;
+ //lHdrName: string;
begin
if not OpenDialogExecute('Select the 3D NIfTI images to inspect)',true,false,kAnyFilter) then
exit;
@@ -1148,4 +1173,4 @@ finalization
{$ENDIF}
end.
-
+
\ No newline at end of file
diff --git a/dcm2nii/guii.lrs b/dcm2nii/guii.lrs
old mode 100644
new mode 100755
diff --git a/dcm2nii/lsjpeg.pas b/dcm2nii/lsjpeg.pas
old mode 100644
new mode 100755
index 2ed121f..4ec1c1d
--- a/dcm2nii/lsjpeg.pas
+++ b/dcm2nii/lsjpeg.pas
@@ -1,751 +1,777 @@
-unit lsjpeg;
-{//$DEFINE Stream}
-//rev13: changes by CR and JGS
-//rev19: uses Lookup table for decoding Huffman table: this doubles the speed
-interface
- {$H+}
-
-uses
-dialogsx,
-{$IFNDEF UNIX}
- //windows,
-{$ENDIF}
- sysutils,define_types,classes;
-type
- HufRA = record
- HufSz,HufCode,HufVal: Integer;
- end;
-{$IFDEF Stream}
- procedure DecodeJPEG(var lStream: TMemoryStream; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
-{$ELSE}
- procedure DecodeJPEG(var infp: file; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
-{$ENDIF}
-implementation
-
-{$IFDEF Stream}
- procedure DecodeJPEG(var lStream: TMemoryStream; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
-{$ELSE}
-procedure DecodeJPEG(var infp: file; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
-{$ENDIF}
-const
- kmaxFrames = 4;
-label
- 666 {EOF};
- var
- lRawRA: bytep;
- lImgRA: WordP;
- lHufVal,lAbba,lOffset,lLineStart,lPredicted,lPredictedG,lPredictedB,lRestartSegmentSz,
- lSz,k,Code,Si,lIncX,lIncY,lInc,lPredA,lPredB,lPredC,lCurrentBitPos,btS1,btS2, btMarkerType,
- DHTnLi,DHTtcth,SOFprecision,SOSpttrans, SOFnf,SOFarrayPos,SOSns,SOSarrayPos,SOSss,SOSse,SOSahal:integer;//byte;
- lHufTable,lnHufTables,{lDecode,}lImgStart,lRawSz,lRawPos,lItems,SOFydim, SOFxdim: integer;
- lMaxHufSi,lMaxHufVal: array [1..kmaxFrames] of integer;
- DHTLiRA,DHTstartRA: array [1..kmaxFrames,0..31] of integer;//byte;
- lBitMask: array [1..17] of integer;
- lSSSSszRA: array [1..kMaxFrames,0..17] of byte;
- lLookUpRA: array [1..kMaxFrames,0..255] of byte; //lists all possible SSSS with <= 8bits
- lHufRA: array [1..kMaxFrames,0..31] of HufRA;
- lFrameCount,lSegmentLength,lSegmentEnd,lI: integer;
- lImgTypeC3,lHdrOK: boolean;
-function ReadBit: integer; //Read the next single bit
-begin
- result := (lRawRA^[lRawPos] shr (7-lCurrentBitPos)) and 1;
- lCurrentBitPos := lCurrentBitPos + 1;
- if (lCurrentBitPos = 8) then begin
- lRawPos := 1+lRawPos;
- lCurrentBitPos := 0;
- end;
-end;
-
-
-
-function ReadBits ( lNum: integer): integer; //lNum: bits to read, not to exceed 16
-begin
- result := lRawRA^[lRawPos];
- result := result shl 8 + lRawRA^[lRawPos+1];
- result := result shl 8 + lRawRA^[lRawPos+2];
- result := (result shr (24-lCurrentBitPos-lNum)) and lBitMask[lNum]; //lCurrentBitPos is incremented from 1, so -1
- lCurrentBitPos := lCurrentBitPos + lNum;
- if (lCurrentBitPos > 7) then begin
- lRawPos := lRawPos+(lCurrentBitPos shr 3);
- lCurrentBitPos := (lCurrentBitPos and 7);
- end;
-end;
-
-function DecodePixelDifference( lFrame: integer): integer;//Red/Green/Blue each a separate 'Frame': can have unique huffman tables
-var
- lByte,lHufValSSSS,lInput,lInputbits,lDiff,lI: integer;
-begin
- // read one byte from the stream, without modifying the pointer
- lByte := (lRawRA^[lRawPos] shl lCurrentBitPos) + (lRawRA^[lRawPos+1] shr (8-lCurrentBitPos));
- lByte := lByte and 255;
- lHufValSSSS := lLookUpRA[lFrame,lByte];
- //lLookUpRA: array [1..kMaxFrames,0..255] of byte; //lists all possible SSSS with <= 8bits
- if lHufValSSSS < 255 then begin
- lCurrentBitPos := lSSSSszRA[lFrame,lHufValSSSS] + lCurrentBitPos;
- lRawPos := lRawPos + (lCurrentBitpos shr 3);
- lCurrentBitpos := lCurrentBitpos and 7;
- //AdvanceBitPos(lSSSSszRA[lFrame,lSSSS]), but inlined;
- end else begin //full SSSS is not in the first 8-bits
- if (lByte < 0) or (lByte > 255) then msg('lsjeg error');
- lInput := lByte;
- lInputBits := 8;
- inc(lRawPos); // forward 8 bits = precisely 1 byte
- repeat
- Inc(lInputBits);
- lInput := lInput shl 1 + ReadBit;
- if DHTLiRA[lFrame,lInputBits] <> 0 then begin //if any entires with this length
- for lI := DHTstartRA[lFrame,lInputBits] to (DHTstartRA[lFrame,lInputBits]+DHTLiRA[lFrame,lInputBits]-1) do begin
- if (lInput = lHufRA[lFrame,lI].HufCode) then
- lHufValSSSS := lHufRA[lFrame,lI].HufVal;
- end; //check each code
- end; //if any entires with this length
- if (lInputBits >= lMaxHufSi[lFrame]) and (lHufValSSSS > 254) then begin//exhausted options CR: added rev13
- lHufValSSSS := lMaxHufVal[lFrame];
- end;
- until (lHufValSSSS < 255);
- end; //answer in first 8 bits
- //The HufVal is referred to as the SSSS in the Codec, so it is called 'lHufValSSSS'
- case lHufValSSSS of
- 0: result:= 0;
- 1: if ReadBit = 0 then result := -1 else result := 1;
- (*BELOW only a tiny bit faster to separate 2..15 into 2..9 and 10..15, requires extra procedure and more
- 2..9: begin //see 10..15 for explanation
- lDiff := ReadBits2_9(lHufValSSSS);
- if (lDiff > (lBitMask[lHufValSSSS-1])) then //add
- result := lDiff
- else //negation
- result := lDiff - lBitMask[lHufValSSSS];
- end; //2..9 *)
- 2..15: begin
- //Osiris includes extra bits after SSSS=16...a violation of the standard See "TABLE H.2 - Difference categories for lossless Huffman coding" of the codec ITU-T81
- //According to the Codec H.1.2.2 "No extra bits are appended after SSSS = 16 is encoded."
- //To patch for Osiris Change case from 2..15 to 2..16
- // This will work for Osiris images, but will break non-Osiris images
- lDiff := ReadBits(lHufValSSSS);
- if (lDiff > (lBitMask[lHufValSSSS-1])) then //add
- result := lDiff
- // this is slightly unintuitive: the positive bit is identical to the offset shown in TABLE H.2, a slower but more intuitive way to do this is:
- //result := (lDiff and lBitMask[lHufVal-1]) + (1 shl (lHufval-1));
- //where you clip off the sign bit and then SHL appropriately
- else //negation
- result := lDiff - lBitMask[lHufValSSSS];
- //NEXT to lines are a bit more intuitive:
- //lDiff := lBitMask[lHufVal-1]- lDiff;
- //result := -(lDiff + (1 shl (lHufval-1)));//negation
- end; //10..15
- else //16, not osiris
- result := 32768;
- end; //case HuffVal
-end; //func DecodePixelDifference
-
-procedure ReadByte(var lByte: integer);
-begin
- inc(lRawPos);
- lByte := lRawRA^[lRawPos];
-end;
-
-function ReadWord: word;
-var
- lbtL1, lbtL2: byte;
-begin
- inc(lRawPos);
- lbtL1 := lRawRA^[lRawPos];
- inc(lRawPos);
- lbtL2 := lRawRA^[lRawPos];
- result := (256 * lbtL1 + lbtL2)
-end;
-//NEXT: main procedure
- begin
- lAbba := 4;
- lnHufTables := 0;
- lRawSz := lCptSize;
- lRawPos := 0;
- lRestartSegmentSz := 0;
- lImgTypeC3 := false;
- SOFxdim:= 1;
- if lRawSz < 32 then goto 666;
- for lFrameCount := 1 to kMaxFrames do
- for lInc := 1 to 16 do
- DHTstartRA[lFrameCount,lInc] := 0;
- SOFydim := 1;
- SOSpttrans := 0;
- lHdrOK := false;
- SOFnf := 0;
- SOSns := 0;
- GetMem( lRawRA, lRawSz);
-{$IFDEF Stream}
- lStream.Seek(lCptPosition, soFromBeginning);
- lStream.readBuffer(lRawRA^, lRawSz);
-{$ELSE}
- Seek(infp,lCptPosition);
- BlockRead(infp, lRawRA^, lRawSz);
-{$ENDIF}
- ReadByte(btS1);
- ReadByte(btS1);
- repeat
- repeat
- if lRawPos <= lRawSz then ReadByte(btS1);
- if btS1 <> $FF then begin
- goto 666;
- end;
- if lRawPos <= lRawSz then ReadByte( btMarkerType);
- case btMarkerType of //only process segments with length fields
- $0,$1,$D0..$D7,$FF: btMarkerType := 0; //0&FF = fillers, $1=TEM,$D0..D7=resync
- end;
- until (lRawPos >= lRawSz) or (btMarkerType <> 0);
- lSegmentLength := ReadWord;
- lSegmentEnd := lRawPos+(lSegmentLength - 2);
- if lSegmentEnd > lRawSz then goto 666;
- if (btMarkerType = $C3) then
- lImgTypeC3 := true;
- if lverbose then msg( inttohex(btMarkerType,2));
- case btMarkerType of
- $0: ; //filler - ignore
- $C0..$C3,$C5..$CB,$CD..$CF: begin //read SOF FrameHeader
- ReadByte(SOFprecision);
- SOFydim := ReadWord;
- SOFxdim:= ReadWord;
- ReadByte(SOFnf);
- if lverbose then msg('[precision:'+inttostr(SOFprecision)+' X*Y:'+inttostr(SOFxdim)+'*'+inttostr(SOFydim)+'nFrames:'+inttostr(SOFnf)+'] ');
- if (not lImgTypeC3) or ((SOFnf <> 1) and (SOFnf <> 3)) then begin
- msg('Unable to extract this file format.');
- end;
- SOFarrayPos := lRawPos;
- lRawPos := (lSegmentEnd);
- end; //SOF FrameHeader
- $C4: begin //DHT Huffman
- if lverbose then msg( 'HuffmanLength'+inttostr(lSegmentLength)+':');
- //if SOFnf <1 then SOFnf := 1; //we may not know SOFnf yet!
- lFrameCount := 1;
- repeat
- ReadByte( DHTtcth);
- //msg(inttostr(lFrameCount)+'@'+inttostr(DHTtcth and 15)+'x'+inttostr(DHTtcth ));
- DHTnLi := 0;
- for lInc := 1 to 16 do begin
- ReadByte(DHTliRA[lFrameCount,lInc]);
- DHTnLi := DHTnLi + DHTliRA[lFrameCount,lInc];
- if DHTliRA[lFrameCount,lInc] <> 0 then lMaxHufSi[lFrameCount] := lInc;
- //msg(inttostr(DHTliRA[lFrameCount,lInc])+'@'+inttostr(lMaxHufSi));
- end;
- if DHTnLi > 17 then begin
- msg('Huffman table corrupted.');
- goto 666;
- end;
- lIncY := 0; //frequency
-
- for lInc := 0 to 31 do begin
- lHufRA[lFrameCount, lInc].HufVal := -1;
- lHufRA[lFrameCount, lInc].HufSz := -1;
- lHufRA[lFrameCount, lInc].HufCode := -1;
- end;
-
- for lInc := 1 to 16 do begin //set the huffman size values
- if DHTliRA[lFrameCount,lInc]> 0 then begin
- DHTstartRA[lFrameCount,lInc] := lIncY+1;
- for lIncX := 1 to DHTliRA[lFrameCount,lInc] do begin
- inc(lIncY);
- ReadByte(btS1);
- lHufRA[lFrameCount,lIncY].HufVal := btS1;
- lMaxHufVal[lFrameCount] := btS1;
- if (btS1 >= 0) and (btS1 <= 16) then
- lHufRA[lFrameCount,lIncY].HufSz := lInc
- else begin
- msg('Huffman size array corrupted.');
- goto 666;
- end;
- end;
- end; //Length of size lInc > 0
- end;
- //msg('Max bits:'+inttostr(lMaxHufSi)+' SSSS:'+inttostr(lMaxHufVal));
- K := 1;
- Code := 0;
- Si := lHufRA[lFrameCount,K].HufSz;//HuffSizeRA[1];
- repeat
- while (Si = lHufRA[lFrameCount,K].HufSz) do begin
- lHufRA[lFrameCount,K].HufCode := Code;
- //msg('bits: '+inttostr(Si)+' NthEntry:'+inttostr(K)+' Code:'+inttostr(Code));
- Code := Code + 1;
- Inc(K);
- end;
- if K <= DHTnLi then begin
- while lHufRA[lFrameCount,K].HufSz > Si do begin
- Code := Code Shl 1;
- Si := Si + 1;
- end; //while Si
- end; //K <= 17
- until K > DHTnLi;// JGS added rev13
- inc(lFrameCount);
- until (lSegmentEnd-lRawPos) < 18;
- lnHufTables := lFrameCount - 1;
- //msg(inttostr(lnHufTables));
- lRawPos := (lSegmentEnd);
- end; //$C4: DHT Huffman
- $DD: begin //Define Restart
- lRestartSegmentSz := Readword;
- lRawPos := (lSegmentEnd);
- end;
- $DA: begin //read SOS Scan Header
- if SOSns > 0 then goto 666; //multiple SOS!
- ReadByte(SOSns);
- //if Ns = 1 then NOT interleaved, else interleaved: see B.2.3
- SOSarrayPos := lRawPos;
- if SOSns > 0 then begin
- for lInc := 1 to SOSns do begin
- ReadByte( btS1); //component identifier 1=Y,2=Cb,3=Cr,4=I,5=Q
- ReadByte(btS2); //horizontal and vertical sampling factors
- end;
- end;
- ReadByte(SOSss); //predictor selection B.3
- ReadByte( SOSse);
- ReadByte( SOSahal); //lower 4bits= pointtransform
- SOSpttrans := SOSahal and 16;
- if lverbose then
- msg('[Predictor: '+inttostr(SOSss)+' PointTransform:'+inttostr(SOSahal)+'] ');
- lRawPos := (lSegmentEnd);
- end; //$DA SOS - Scan Header
- else begin //skip marker segment;
- lRawPos := (lSegmentEnd);
- end;
- end; //case markertype
- until (lRawPos >= lRawSz) or (btMarkerType = $DA); {hexDA=Start of scan}
- lHdrOK := true; //errors goto label 666, so are NOT OK
- lImgStart := lRawPos;
-666:
- if not lHdrOK then begin
- msg('Unable to read this file - is this really a JPEG image?');
- exit;
- end;
- if (not lImgTypeC3) then exit; //lossless compressed huffman tables
- //NEXT: unpad data - delete byte that follows $FF
- lINc := lRawPos;
- lIncX := lRawPos;
- repeat
- lRawRA^[lIncX] := lRawRA^[lInc];
- if lRawRA^[lInc] = 255 then begin
- if (lRawRA^[lInc+1] = $00) then
- lInc := lInc+1
- else begin
- //msg(inttostr(lRawRA^[lInc+1]));
- if (lRawRA^[lInc+1] = $D9) then //end of image
- lIncX := -666; //end of padding
- end;
- end;
- inc(lInc);
- inc(lIncX);
- until lIncX < 0;
- //End: Data unpadding
- //NEXT: Create Huffman LookupTable.
- //We will compute all possible outcomes for an 8-bit value, while less intuitive than
- //reading Huffman 1 bit at a time, it doubles the decompression speed
- lBitMask[1]:= 1;
- lBitMask[2]:= 3;
- lBitMask[3]:= 7;
- lBitMask[4]:= 15;
- lBitMask[5]:= 31;
- lBitMask[6]:= 63;
- lBitMask[7]:= 127;
- lBitMask[8]:= 255;
- lBitMask[9]:= 511;
- lBitMask[10]:= 1023;
- lBitMask[11]:= 2047;
- lBitMask[12]:= 4095;
- lBitMask[13]:= 8191;
- lBitMask[14]:= 16383;
- lBitMask[15]:= 32767;
- lBitMask[16]:= 65535;
- lBitMask[17]:= 131071; //ONLY required for Osiris corrupted images, see DecodePixelDifference for details
- //NEXT: some RGB images use only a single Huffman table for all 3 colour planes. In this case, replicate the correct values
- if (lnHufTables < SOFnf) then begin //use single Hufman table for each frame
- //msg('generating tables'+inttostr(SOFnf));
- if lnHufTables < 1 then begin
- msg('Lossless JPEG decoding error: no Huffman tables.');
- exit;
- end;
- for lFrameCount := 2 to SOFnf do begin
- for lInc := 1 to 16 do
- DHTstartRA[lFrameCount,lInc] := DHTstartRA[1,lInc];
- for lInc := 0 to 31 do begin
- lHufRA[lFrameCount,lInc].HufCode := lHufRA[1,lInc].HufCode;
- lHufRA[lFrameCount,lInc].HufVal := lHufRA[1,lInc].HufVal;
- lHufRA[lFrameCount,lInc].HufSz := lHufRA[1,lInc].HufSz;
- DHTliRA[lFrameCount,lInc] := DHTliRA[1,lInc];
- end; //for each table entry
- end; //for each frame xx
- end;// if lnHufTables < SOFnf
- for lFrameCount := 1 to kMaxFrames do
- for lInc := 0 to 17 do
- lSSSSszRA[lFrameCount,lInc] := 123; //Impossible value for SSSS, suggests 8-bits can not describe answer
- for lFrameCount := 1 to kMaxFrames do
- for lInc := 0 to 255 do
- lLookUpRA[lFrameCount,lInc] := 255; //Impossible value for SSSS, suggests 8-bits can not describe answer
- //NEXT fill lookuptable
- for lFrameCount := 1 to SOFnf do begin
- lIncY := 0;
- for lSz := 1 to 8 do begin //set the huffman lookup table for keys with lengths <=8
- if DHTliRA[lFrameCount,lSz]> 0 then begin
- for lIncX := 1 to DHTliRA[lFrameCount,lSz] do begin
- inc(lIncY);
- lHufVal := lHufRA[lFrameCount,lIncY].HufVal; //SSSS
- {if (lHufVal < 0) or (lHufVal > 17) then begin
- msg('Unknown SSSS =' +inttostr(lHufVal));
- lHufVal := 16;
- end; }
- lSSSSszRA[lFrameCount,lHufVal] := lSz;
- k := (lHufRA[lFrameCount,lIncY].HufCode shl (8-lSz )) and 255; //K= most sig bits for hufman table
- if lSz < 8 then begin //fill in all possible bits that exceed the huffman table
- lInc := lBitMask[8-lSz];
- for lCurrentBitPos := 0 to lInc do begin
- lLookUpRA[lFrameCount,k+lCurrentBitPos] := lHufVal;
- end;
- end else
- lLookUpRA[lFrameCount,k] := lHufVal; //SSSS
-
- {msg('Frame ' + inttostr(lFrameCount) + ' SSSS= '+inttostr(lHufRA[lFrameCount,lIncY].HufVal)+
- ' Size= '+inttostr(lHufRA[1,lIncY].HufSz)+
- ' Code= '+inttostr(lHufRA[1,lIncY].HufCode)+
- ' SHL Code= '+inttostr(k)+
- ' EmptyBits= '+inttostr(lInc)); }
- end; //Set SSSS
- end; //Length of size lInc > 0
- end; //for lInc := 1 to 8
- end; //For each frame, e.g. once each for Red/Green/Blue
- //Next: uncompress data: different loops for different predictors
- SOFxdim:= SOFnf*SOFxdim;
- lItems := SOFxdim*SOFydim;
- //if lVerbose then msg('precision'+inttostr(SOFprecision));
- //for timing, multiple decoding loops lRawAbba := lRawPos;for lLoopsAbba := 1 to 100 do begin lRawPos := lRawAbba;
- //if (lRestartSegmentSz > 0) and ((SOFPrecision<> 8) or (SOSss = 7)) then //add restart support if we ever find any samples to test
- // msg('This image uses restart markers. Please contact the author. Predictor:Precision '+inttostr(SOSss)+':'+inttostr(SOFPrecision));
- inc(lRawPos);//abbax
- lCurrentBitPos := 0; //read in a new byte
- //lCurrentBitPos := 1; //read in a new byte
- lItems := SOFxdim*SOFydim;
- lPredicted := 1 shl (SOFPrecision-1-SOSpttrans);
- lInc := 0;
- if (SOFPrecision<> 8) then begin //start - 16 bit data
- lImgRA := @lOutSmallRA[0];{set to 1 for MRIcro, else 0}
- FillChar(lImgRA^,lItems*sizeof(word), 0); //zero array
- lPredB:= 0;
- lPredC := 0;
- case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
- 2: lPredA:= SOFxDim-1; //Rb directly above
- 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
- 4,5: begin
- lPredA := 0;
- lPredB := SOFxDim-1; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- 6: begin
- lPredB := 0;
- lPredA := SOFxDim-1; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- else lPredA := 0; //Ra: directly to left
- end; //case SOSss: predictor offset
- for lIncX := 1 to SOFxdim do begin
- inc(lInc); //writenext voxel
- if lInc > 1 then lPredicted := lImgRA^[lInc-1];
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //first line: use prev voxel prediction;
-
-
- if lRestartSegmentSz = 0 then begin
- for lIncY := 2 to SOFyDim do begin
- inc(lInc); //write next voxel
- lPredicted := lImgRA^[lInc-SOFxdim];
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- if SOSss = 4 then begin
- for lIncX := 2 to SOFxdim do begin
- lPredicted := lImgRA^[lInc-lPredA]+lImgRA^[lInc-lPredB]-lImgRA^[lInc-lPredC];
- inc(lInc); //writenext voxel
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //for lIncX
- end else if (SOSss = 5) or (SOSss = 6) then begin
- for lIncX := 2 to SOFxdim do begin
- lPredicted := lImgRA^[lInc-lPredA]+ ((lImgRA^[lInc-lPredB]-lImgRA^[lInc-lPredC]) shr 1);
- inc(lInc); //writenext voxel
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //for lIncX
- end else if SOSss = 7 then begin
- for lIncX := 2 to SOFxdim do begin
- inc(lInc); //writenext voxel
- lPredicted := (lImgRA^[lInc-1]+lImgRA^[lInc-SOFxdim]) shr 1;
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //for lIncX
- end else begin //SOSss 1,2,3 read single values
- for lIncX := 2 to SOFxdim do begin
- lPredicted := lImgRA^[lInc-lPredA];
- inc(lInc); //writenext voxel
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //for lIncX
- end; //SOSss predictor
-
-
- end; //for lIncY
- end {RestartSegmentSz = 0} else begin {restartsegment}
- if SOSss > 3 then
- msg('Unusual 16-bit lossless JPEG with restart segments. Please contact the author:'+inttostr(SOSss));
- lSegmentEnd := lRestartSegmentSz;
- repeat
- if lSegmentEnd > lItems then lSegmentEnd := lItems;
- lLineStart := (((lInc div SOFxDim)+1)* SOFxDim){-1};
- if lInc > (SOFxDim+1) then
- lPredicted := 1 shl (SOFPrecision-1-SOSpttrans)
- else
- lPredicted := lImgRA^[lInc-SOFxdim];
-
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRA^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredicted := lImgRA^[lInc-lPredA];
- end;
- if (lSegmentEnd+1) < lItems then begin
- dec(lRawPos);
- repeat
- while (lRawRA^[lRawPos] <> 255) do
- inc(lRawPos);
- inc(lRawPos);
- until (lRawRA^[lRawPos] >= $D0) and (lRawRA^[lRawPos] <= $D7);
- lCurrentBitPos := 0; //read in a new byte
- inc(lRawPos);//abbax
- end;
- lSegmentEnd := lSegmentEnd + lRestartSegmentSz;
- until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
- end; //restartsegments
- end else if SOFnf = 3 then begin //>8bit data; 8 bit follows
- //LOSSLESS JPEG: 7 possible predictors - we will handle all of them
- lPredB:= 0;
- lPredC := 0;
- case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
- 2: lPredA:= SOFxDim-3; //Rb directly above
- 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
- 5: begin
- lPredA := 0;
- lPredB := SOFxDim-3; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- 6: begin
- lPredB := 0;
- lPredA := SOFxDim-3; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- else lPredA := 0; //Ra: directly to left
- end; //case SOSss: predictor offset
- lPredictedG := lPredicted;
- lPredictedB := lPredicted;
- lOffset := 0;
- lInc := lOffset;
- for lIncX := 1 to (SOFxdim div 3) do begin //write first line
- //DecodePixelDifference=RED
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- lPredicted := lImgRAz^[lInc];
- inc(lInc); //writenext voxel
- //DecodePixelDifference=GREEN
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2);
- lPredictedG := lImgRAz^[lInc];
- inc(lInc); //writenext voxel
- //DecodePixelDifference=BLUE
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3);
- lPredictedB := lImgRAz^[lInc];
- inc(lInc); //writenext voxel
- end; //first line: use prev voxel prediction;
- if lRestartSegmentSz = 0 then lSegmentEnd := lItems
- else lSegmentEnd := lRestartSegmentSz;
- repeat
- if lSegmentEnd > lItems then lSegmentEnd := lItems;
- lLineStart := (((lInc div SOFxDim)+1)* SOFxDim)+lOffset{-1};
- if lInc > (SOFxDim+1) then begin
- lPredicted := 1 shl (SOFPrecision-1-SOSpttrans);
- lPredictedG := lPredicted;
- lPredictedB := lPredicted;
- end else begin
- lPredicted := lImgRAz^[lInc-SOFxdim+lOffset];
- lPredictedG := lImgRAz^[1+lInc-SOFxdim+lOffset];
- lPredictedB := lImgRAz^[2+lInc-SOFxdim+lOffset];
- end;
- if SOSss = 4 then begin //predictor = 4
- //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
- while lInc < (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1); //RED
- inc(lInc);
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
- inc(lInc);
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
- inc(lInc);
- if lInc = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc-SOFxdim];
- lPredictedG := lImgRAz^[lInc-SOFxdim+1];
- lPredictedB := lImgRAz^[lInc-SOFxdim+2];
- lLineStart := lLineStart + (SOFxDim);
- end else begin
- lPredicted := lImgRAz^[lInc-3]+lImgRAz^[lInc-3-(SOFxDim-3)]-lImgRAz^[lInc-3-SOFxDim];
- lPredictedG := lImgRAz^[lInc-2]+lImgRAz^[lInc-2-(SOFxDim-3)]-lImgRAz^[lInc-2-SOFxDim];
- lPredictedB := lImgRAz^[lInc-1]+lImgRAz^[lInc-1-(SOFxDim-3)]-lImgRAz^[lInc-1-SOFxDim];
- end;
- end;
- //xxx
- end else if (SOSss = 5) or (SOSss = 6) then begin //predictor = 5 or 6
- //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
- while lInc < (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1); //RED
- inc(lInc);
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
- inc(lInc);
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
- inc(lInc);
- if lInc = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc-SOFxdim];
- lPredictedG := lImgRAz^[lInc-SOFxdim+1];
- lPredictedB := lImgRAz^[lInc-SOFxdim+2];
- lLineStart := lLineStart + (SOFxDim);
- end else begin
- lPredicted := lImgRAz^[lInc-3-lPredA]+((lImgRAz^[lInc-3-lPredB]-lImgRAz^[lInc-3-lPredC])shr 1);
- lPredictedG := lImgRAz^[lInc-2-lPredA]+((lImgRAz^[lInc-2-lPredB]-lImgRAz^[lInc-2-lPredC])shr 1);
- lPredictedB := lImgRAz^[lInc-1-lPredA]+((lImgRAz^[lInc-1-lPredB]-lImgRAz^[lInc-1-lPredC])shr 1);
- end;
- end;
- end else if SOSss = 7 then begin //predictor = 7
- while lInc < (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1); //RED
- inc(lInc);
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
- inc(lInc);
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
- inc(lInc);
- if lInc = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc-SOFxdim];
- lPredictedG := lImgRAz^[lInc-SOFxdim+1];
- lPredictedB := lImgRAz^[lInc-SOFxdim+2];
- lLineStart := lLineStart + (SOFxDim);
- end else begin
- lPredicted := (lImgRAz^[lInc-3]+lImgRAz^[lInc-3-(SOFxDim-3)])shr 1;
- lPredictedG := (lImgRAz^[lInc-2]+lImgRAz^[lInc-2-(SOFxDim-3)]) shr 1;
- lPredictedB := (lImgRAz^[lInc-1]+lImgRAz^[lInc-1-(SOFxDim-3)]) shr 1;
- end;
- end;
-
- end else begin //predictor in range 1,2,3
- //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
- while lInc < (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1); //RED
- inc(lInc);
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
- inc(lInc);
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
- inc(lInc);
- if lInc = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc-SOFxdim];
- lPredictedG := lImgRAz^[lInc-SOFxdim+1];
- lPredictedB := lImgRAz^[lInc-SOFxdim+2];
- lLineStart := lLineStart + (SOFxDim);
- end else begin
- lPredicted := lImgRAz^[lInc-3-lPredA];
- lPredictedG := lImgRAz^[lInc-2-lPredA];
- lPredictedB := lImgRAz^[lInc-1-lPredA];
- end;
- end;
- end; //predictor <> 7
- until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
- // end; //8<>15data type
- end else begin //previously 12/16/24bit data, 8 bit follows
- lInc := 0;
- //LOSSLESS JPEG: 7 possible predictors - we will handle all of them
- lPredB:= 0;
- lPredC := 0;
- case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
- 2: lPredA:= SOFxDim-1; //Rb directly above
- 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
- 5: begin
- lPredA := 0;
- lPredB := SOFxDim-1; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- 6: begin
- lPredB := 0;
- lPredA := SOFxDim-1; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- else lPredA := 0; //Ra: directly to left
- end; //case SOSss: predictor offset
- //lOffset := -1;
- for lIncX := 1 to SOFxdim do begin //write first line
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- inc(lInc); //writenext voxel
- lPredicted := lImgRAz^[lInc-1];
- end; //first line: use prev voxel prediction;
- if lRestartSegmentSz = 0 then lSegmentEnd := lItems
- else lSegmentEnd := lRestartSegmentSz;
- repeat
- if lSegmentEnd > lItems then lSegmentEnd := lItems;
- lLineStart := (((lInc div SOFxDim)+1)* SOFxDim){-1};
- if lInc > (SOFxDim+1) then
- lPredicted := 1 shl (SOFPrecision-1-SOSpttrans)
- else
- lPredicted := lImgRAz^[lInc-SOFxdim];
- if SOSss = 4 then begin //predictor 4 : ABOVE+LEFT-(UPPERLEFT)
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredicted := lImgRAz^[lInc]+lImgRAz^[lInc-(SOFxDim-1)] -lImgRAz^[lInc-SOFxDim] ;
- end;
-
- end else if (SOSss = 5) or (SOSss=6) then begin //predictor 5,6 : comparisons
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredicted := lImgRAz^[lInc-lPredA]+((lImgRAz^[lInc-lPredB]-lImgRAz^[lInc-lPredC]) shr 1) ;
- end;
- end else if SOSss = 7 then begin //predictor 7: average above and left
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredA := lImgRAz^[lInc];
- lPredB:= lImgRAz^[lInc-SOFxDim+1];//correct
- lPredicted := (lPredA+lPredB) shr 1;
- end;
- end else begin //predictor <> 7 : assume SOSss=1: previous
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredicted := lImgRAz^[lInc-lPredA];
- end;
- end; //predictor <> 7
- if (lSegmentEnd+1) < lItems then begin
- dec(lRawPos);
- {msg('x'+inttostr(lRawPos)+' '+inttostr(lRawRA^[lRawPos])+':'+
- inttostr(lRawRA^[lRawPos+1])+':'+inttostr(lRawRA^[lRawPos+2])+':'+
- inttostr(lRawRA^[lRawPos+3])+':');}
- repeat
- while (lRawRA^[lRawPos] <> 255) do
- inc(lRawPos);
- inc(lRawPos);
- //msg(inttostr(lRawRA^[lRawPos]));
- until (lRawRA^[lRawPos] >= $D0) and (lRawRA^[lRawPos] <= $D7);
- //lCurrentByteVal := 0; //not FF
- lCurrentBitPos := 0; //read in a new byte
- //msg('x');
- inc(lRawPos);//abbax
- //lCurrentBitPos := 9; //read in a new byte
- end;
- lSegmentEnd := lSegmentEnd + lRestartSegmentSz;
- until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
- end; //8<>15data type
-end;
-
-end.
-
+unit lsjpeg;
+{*$DEFINE Stream}
+//rev13: changes by CR and JGS
+//rev19: uses Lookup table for decoding Huffman table: this doubles the speed
+//rev26: fixed memory leak: FreeMem(lRawRA)
+interface
+{$IFDEF FPC} {$mode delphi}{$H+} {$ENDIF}
+
+uses
+dialogsx,dialogs_msg,
+ sysutils,define_types,classes;
+type
+ HufRA = record
+ HufSz,HufCode,HufVal: Integer;
+ end;
+{$IFDEF Stream}
+ procedure DecodeJPEG(var lStream: TMemoryStream; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
+{$ELSE}
+ procedure DecodeJPEG(var infp: file; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
+{$ENDIF}
+implementation
+
+{$IFDEF Stream}
+ procedure DecodeJPEG(var lStream: TMemoryStream; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
+{$ELSE}
+procedure DecodeJPEG(var infp: file; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
+{$ENDIF}
+const
+ kmaxFrames = 4;
+label
+ 666 {EOF}, 123 {Freemem};
+ var
+ lRawRA: bytep;
+ lImgRA: WordP;
+ lHufVal,lAbba,lOffset,lLineStart,lPredicted,lPredictedG,lPredictedB,lRestartSegmentSz,
+ lSz,k,Code,Si,lIncX,lIncY,lInc,lPredA,lPredB,lPredC,lCurrentBitPos,btS1,btS2, btMarkerType,
+ DHTnLi,DHTtcth,SOFprecision,SOSpttrans, SOFnf,SOFarrayPos,SOSns,SOSarrayPos,SOSss,SOSse,SOSahal:integer;//byte;
+ lHufTable,lnHufTables,{lDecode,}lImgStart,lRawSz,lRawPos,lItems,SOFydim, SOFxdim: integer;
+ lMaxHufSi,lMaxHufVal: array [1..kmaxFrames] of integer;
+ DHTLiRA,DHTstartRA: array [1..kmaxFrames,0..31] of integer;//byte;
+ lBitMask: array [1..17] of integer;
+ lSSSSszRA: array [1..kMaxFrames,0..17] of byte;
+ lLookUpRA: array [1..kMaxFrames,0..255] of byte; //lists all possible SSSS with <= 8bits
+ lHufRA: array [1..kMaxFrames,0..31] of HufRA;
+ lFrameCount,lSegmentLength,lSegmentEnd,lI: integer;
+ lImgTypeC3,lHdrOK: boolean;
+function ReadBit: integer; //Read the next single bit
+begin
+ result := (lRawRA[lRawPos] shr (7-lCurrentBitPos)) and 1;
+ lCurrentBitPos := lCurrentBitPos + 1;
+ if (lCurrentBitPos = 8) then begin
+ lRawPos := 1+lRawPos;
+ lCurrentBitPos := 0;
+ end;
+end; //nested proc ReadBit
+
+(*
+START Disabled Procedures
+// These functions are not used: these routines have been inlined (following VTune profiling)
+// but they are useful utilities if you want to explore Huffman Tables
+function ReadBits2_9 ( lNum: integer): integer; //lNum: bits to read, not to exceed 9
+//wo Advance: does not increment the Byte/Bit position. Use AdvanceBitPos to do this
+begin
+ result := lRawRA[lRawPos];
+ result := result shl 8 + lRawRA[lRawPos+1];
+ //result := result shl 8 + lRawRA[lRawPos+2];
+ result := (result shr (16-lCurrentBitPos-lNum)) and lBitMask[lNum]; //lCurrentBitPos is incremented from 1, so -1
+ lCurrentBitPos := lCurrentBitPos + lNum;
+ if (lCurrentBitPos > 7) then begin
+ lRawPos := lRawPos+(lCurrentBitPos shr 3{div 8});
+ lCurrentBitPos := (lCurrentBitPos and 7{mod 8});
+ end;
+end;
+procedure RetractBitPos(lNum: integer);
+begin
+ lCurrentBitPos := lCurrentBitPos - lNum;
+ while (lCurrentBitPos < 0) do begin
+ lRawPos := lRawPos - 1;
+ lCurrentBitPos := lCurrentBitPos + 8;
+ end;
+end;
+procedure AdvanceBitPos(lNum: integer);
+//Advances Bit/Byte counters
+begin
+ lCurrentBitPos := lCurrentBitPos + lNum;
+ if (lCurrentBitPos > 7) then begin
+ lRawPos := lRawPos+(lCurrentBitPos shr 3{div 8});
+ lCurrentBitPos := (lCurrentBitPos and 7{mod 8});
+ end;
+end;
+END Disabled Procedures*)
+
+function ReadBits ( lNum: integer): integer; //lNum: bits to read, not to exceed 16
+begin
+ result := lRawRA[lRawPos];
+ result := result shl 8 + lRawRA[lRawPos+1];
+ result := result shl 8 + lRawRA[lRawPos+2];
+ result := (result shr (24-lCurrentBitPos-lNum)) and lBitMask[lNum]; //lCurrentBitPos is incremented from 1, so -1
+ lCurrentBitPos := lCurrentBitPos + lNum;
+ if (lCurrentBitPos > 7) then begin
+ lRawPos := lRawPos+(lCurrentBitPos shr 3{div 8});
+ lCurrentBitPos := (lCurrentBitPos and 7{mod 8});
+ end;
+end; //nested proc ReadBits
+
+function DecodePixelDifference( lFrame: integer): integer;//Red/Green/Blue each a separate 'Frame': can have unique huffman tables
+var
+ lByte,lHufValSSSS,lInput,lInputbits,lDiff,lI: integer;
+begin
+ // read one byte from the stream, without modifying the pointer
+ lByte := (lRawRA[lRawPos] shl lCurrentBitPos) + (lRawRA[lRawPos+1] shr (8-lCurrentBitPos));
+ lByte := lByte and 255;
+ lHufValSSSS := lLookUpRA[lFrame,lByte];
+ //lLookUpRA: array [1..kMaxFrames,0..255] of byte; //lists all possible SSSS with <= 8bits
+ if lHufValSSSS < 255 then begin
+ lCurrentBitPos := lSSSSszRA[lFrame,lHufValSSSS] + lCurrentBitPos;
+ lRawPos := lRawPos + (lCurrentBitpos shr 3);
+ lCurrentBitpos := lCurrentBitpos and 7;
+ //AdvanceBitPos(lSSSSszRA[lFrame,lSSSS]), but inlined;
+ end else begin //full SSSS is not in the first 8-bits
+ //if (lByte < 0) or (lByte > 255) then showmessage('yikes: this is impossible');
+ lInput := lByte;
+ lInputBits := 8;
+ inc(lRawPos); // forward 8 bits = precisely 1 byte
+ repeat
+ Inc(lInputBits);
+ lInput := lInput shl 1 + ReadBit;
+ if DHTLiRA[lFrame,lInputBits] <> 0 then begin //if any entires with this length
+ for lI := DHTstartRA[lFrame,lInputBits] to (DHTstartRA[lFrame,lInputBits]+DHTLiRA[lFrame,lInputBits]-1) do begin
+ if (lInput = lHufRA[lFrame,lI].HufCode) then
+ lHufValSSSS := lHufRA[lFrame,lI].HufVal;
+ end; //check each code
+ end; //if any entires with this length
+ if (lInputBits >= lMaxHufSi[lFrame]) and (lHufValSSSS > 254) then begin//exhausted options CR: added rev13
+ lHufValSSSS := lMaxHufVal[lFrame];
+ end;
+ until (lHufValSSSS < 255){found};
+ end; //answer in first 8 bits
+ //The HufVal is referred to as the SSSS in the Codec, so it is called 'lHufValSSSS'
+ case lHufValSSSS of
+ 0: result:= 0;
+ 1: if ReadBit = 0 then result := -1 else result := 1;
+ (*BELOW only a tiny bit faster to separate 2..15 into 2..9 and 10..15, requires extra procedure and more
+ 2..9: begin //see 10..15 for explanation
+ lDiff := ReadBits2_9(lHufValSSSS);
+ if (lDiff > (lBitMask[lHufValSSSS-1])) then //add
+ result := lDiff
+ else //negation
+ result := lDiff - lBitMask[lHufValSSSS];
+ end; //2..9 *)
+ 2..15: begin
+ //Osiris includes extra bits after SSSS=16...a violation of the standard See "TABLE H.2 - Difference categories for lossless Huffman coding" of the codec ITU-T81
+ //According to the Codec H.1.2.2 "No extra bits are appended after SSSS = 16 is encoded."
+ //To patch for Osiris Change case from 2..15 to 2..16
+ // This will work for Osiris images, but will break non-Osiris images
+ lDiff := ReadBits(lHufValSSSS);
+ if (lDiff > (lBitMask[lHufValSSSS-1])) then //add
+ result := lDiff
+ // this is slightly unintuitive: the positive bit is identical to the offset shown in TABLE H.2, a slower but more intuitive way to do this is:
+ //result := (lDiff and lBitMask[lHufVal-1]) + (1 shl (lHufval-1));
+ //where you clip off the sign bit and then SHL appropriately
+ else //negation
+ result := lDiff - lBitMask[lHufValSSSS];
+ //NEXT to lines are a bit more intuitive:
+ {lDiff := lBitMask[lHufVal-1]- lDiff;
+ result := -(lDiff + (1 shl (lHufval-1)));}//negation
+ end; //10..15
+ else {16, not osiris}
+ result := 32768;
+ end; //case HuffVal
+end; //nested proc DecodePixelDifference
+
+procedure ReadByte(var lByte: integer);
+begin
+ inc(lRawPos);
+ lByte := lRawRA[lRawPos];
+end; //nested proc ReadByte
+
+function ReadWord: word;
+var
+ lbtL1, lbtL2: byte;
+begin
+ inc(lRawPos);
+ lbtL1 := lRawRA[lRawPos];
+ inc(lRawPos);
+ lbtL2 := lRawRA[lRawPos];
+ result := (256 * lbtL1 + lbtL2)
+end; //nested proc ReadWord
+//NEXT: main procedure
+ begin
+ lAbba := 4;
+ lnHufTables := 0;
+ lRawSz := lCptSize;
+ lRawPos := 0;
+ lRestartSegmentSz := 0;
+ lImgTypeC3 := false;
+ SOFxdim:= 1;
+ if lRawSz < 32 then goto 666;
+ for lFrameCount := 1 to kMaxFrames do
+ for lInc := 1 to 16 do
+ DHTstartRA[lFrameCount,lInc] := 0;
+ SOFydim := 1;
+ SOSpttrans := 0;
+ lHdrOK := false;
+ SOFnf := 0;
+ SOSns := 0;
+ GetMem( lRawRA, lRawSz);
+{$IFDEF Stream}
+ lStream.Seek(lCptPosition, soFromBeginning);
+ lStream.readBuffer(lRawRA^, lRawSz);
+{$ELSE}
+ Seek(infp,lCptPosition);
+ BlockRead(infp, lRawRA^, lRawSz);
+{$ENDIF}
+ ReadByte(btS1);
+ ReadByte(btS1);
+ repeat
+ repeat
+ if lRawPos <= lRawSz then ReadByte(btS1);
+ if btS1 <> $FF then begin
+ goto 666;
+ end;
+ if lRawPos <= lRawSz then ReadByte( btMarkerType);
+ case btMarkerType of //only process segments with length fields
+ $0,$1,$D0..$D7,$FF: btMarkerType := 0; //0&FF = fillers, $1=TEM,$D0..D7=resync
+ end;
+ until (lRawPos >= lRawSz) or (btMarkerType <> 0);
+ lSegmentLength := ReadWord;
+ lSegmentEnd := lRawPos+(lSegmentLength - 2);
+ if lSegmentEnd > lRawSz then goto 666;
+ if (btMarkerType = $C3) then
+ lImgTypeC3 := true;
+ if lverbose then dcmMsg( {result+}inttohex(btMarkerType,2){':'+inttostr( lSegmentLength )+'@'+inttostr(positon)+' '});
+ case btMarkerType of
+ $0: ; //filler - ignore
+ $C0..$C3,$C5..$CB,$CD..$CF: begin //read SOF FrameHeader
+ ReadByte(SOFprecision);
+ SOFydim := ReadWord;
+ SOFxdim:= ReadWord;
+ ReadByte(SOFnf);
+ if lverbose then dcmMsg('[precision:'+inttostr(SOFprecision)+' X*Y:'+inttostr(SOFxdim)+'*'+inttostr(SOFydim)+'nFrames:'+inttostr(SOFnf)+'] ');
+ if (not lImgTypeC3) or ((SOFnf <> 1) and (SOFnf <> 3)) then begin
+ dcmMsg('Unable to extract this file format.');
+ end;
+ SOFarrayPos := lRawPos;
+ lRawPos := (lSegmentEnd);
+ end; //SOF FrameHeader
+ $C4: begin //DHT Huffman
+ if lverbose then dcmMsg( 'HuffmanLength'+inttostr(lSegmentLength)+':');
+ //if SOFnf <1 then SOFnf := 1; //we may not know SOFnf yet!
+ lFrameCount := 1;
+ repeat
+ ReadByte( DHTtcth);
+ //showmessage(inttostr(lFrameCount)+'@'+inttostr(DHTtcth and 15)+'x'+inttostr(DHTtcth ));
+ DHTnLi := 0;
+ for lInc := 1 to 16 do begin
+ ReadByte(DHTliRA[lFrameCount,lInc]);
+ DHTnLi := DHTnLi + DHTliRA[lFrameCount,lInc];
+ if DHTliRA[lFrameCount,lInc] <> 0 then lMaxHufSi[lFrameCount] := lInc;
+ //showmessage(inttostr(DHTliRA[lFrameCount,lInc])+'@'+inttostr(lMaxHufSi));
+ end;
+ if DHTnLi > 17 then begin
+ dcmMsg('Huffman table corrupted.');
+ goto 666;
+ end;
+ lIncY := 0; //frequency
+
+ for lInc := 0 to 31 do begin
+ lHufRA[lFrameCount, lInc].HufVal := -1;
+ lHufRA[lFrameCount, lInc].HufSz := -1;
+ lHufRA[lFrameCount, lInc].HufCode := -1;
+ end;
+
+ for lInc := 1 to 16 do begin //set the huffman size values
+ if DHTliRA[lFrameCount,lInc]> 0 then begin
+ DHTstartRA[lFrameCount,lInc] := lIncY+1;
+ for lIncX := 1 to DHTliRA[lFrameCount,lInc] do begin
+ inc(lIncY);
+ ReadByte(btS1);
+ lHufRA[lFrameCount,lIncY].HufVal := btS1;
+ lMaxHufVal[lFrameCount] := btS1;
+ if (btS1 >= 0) and (btS1 <= 16) then
+ lHufRA[lFrameCount,lIncY].HufSz := lInc
+ else begin
+ dcmMsg('Huffman size array corrupted.');
+ goto 666;
+ end; {}
+ end;
+ end; //Length of size lInc > 0
+ end;
+ //showmessage('Max bits:'+inttostr(lMaxHufSi)+' SSSS:'+inttostr(lMaxHufVal));
+ K := 1;
+ Code := 0;
+ Si := lHufRA[lFrameCount,K].HufSz;//HuffSizeRA[1];
+ repeat
+ while (Si = lHufRA[lFrameCount,K].HufSz) do begin
+ lHufRA[lFrameCount,K].HufCode := Code;
+ //showmessage('bits: '+inttostr(Si)+' NthEntry:'+inttostr(K)+' Code:'+inttostr(Code));
+ Code := Code + 1;
+ Inc(K);
+ end;
+ if K <= DHTnLi then begin
+ while lHufRA[lFrameCount,K].HufSz > Si do begin
+ Code := Code Shl 1;
+ Si := Si + 1;
+ end; //while Si
+ end; //K <= 17
+ until K > DHTnLi;// JGS added rev13
+ inc(lFrameCount);
+ until (lSegmentEnd-lRawPos) < 18;
+ lnHufTables := lFrameCount - 1;
+ //showmessage(inttostr(lnHufTables));
+ lRawPos := (lSegmentEnd);
+ end; //$C4: DHT Huffman
+ $DD: begin //Define Restart
+ lRestartSegmentSz := Readword;
+ lRawPos := (lSegmentEnd);
+ end;
+ $DA: begin //read SOS Scan Header
+ if SOSns > 0 then goto 666; //multiple SOS!
+ ReadByte(SOSns);
+ //if Ns = 1 then NOT interleaved, else interleaved: see B.2.3
+ SOSarrayPos := lRawPos;
+ if SOSns > 0 then begin
+ for lInc := 1 to SOSns do begin
+ ReadByte( btS1); //component identifier 1=Y,2=Cb,3=Cr,4=I,5=Q
+ ReadByte(btS2); //horizontal and vertical sampling factors
+ end;
+ end;
+ ReadByte(SOSss); //predictor selection B.3
+ ReadByte( SOSse);
+ ReadByte( SOSahal); //lower 4bits= pointtransform
+ SOSpttrans := SOSahal and 16;
+ if lverbose then
+ dcmMsg('[Predictor: '+inttostr(SOSss)+' PointTransform:'+inttostr(SOSahal)+'] ');
+ lRawPos := (lSegmentEnd);
+ end; //$DA SOS - Scan Header
+ else begin //skip marker segment;
+ lRawPos := (lSegmentEnd);
+ end;
+ end; //case markertype
+ until (lRawPos >= lRawSz) or (btMarkerType = $DA); {hexDA=Start of scan}
+ lHdrOK := true; //errors goto label 666, so are NOT OK
+ lImgStart := lRawPos;
+666:
+ if not lHdrOK then begin
+ dcmMsg('Unable to read this file - is this really a JPEG image?');
+ goto 123;
+ end;
+ if (not lImgTypeC3) then
+ goto 123; //lossless compressed huffman tables
+ //NEXT: unpad data - delete byte that follows $FF
+ lINc := lRawPos;
+ lIncX := lRawPos;
+ repeat
+ lRawRA[lIncX] := lRawRA[lInc];
+ if lRawRA[lInc] = 255 then begin
+ if (lRawRA[lInc+1] = $00) then
+ lInc := lInc+1
+ else begin
+ //showmessage(inttostr(lRawRA[lInc+1]));
+ if (lRawRA[lInc+1] = $D9) then //end of image
+ lIncX := -666; //end of padding
+ end;
+ end;
+ inc(lInc);
+ inc(lIncX);
+ until lIncX < 0;
+ //End: Data unpadding
+ //NEXT: Create Huffman LookupTable.
+ //We will compute all possible outcomes for an 8-bit value, while less intuitive than
+ //reading Huffman 1 bit at a time, it doubles the decompression speed
+ lBitMask[1]:= 1;
+ lBitMask[2]:= 3;
+ lBitMask[3]:= 7;
+ lBitMask[4]:= 15;
+ lBitMask[5]:= 31;
+ lBitMask[6]:= 63;
+ lBitMask[7]:= 127;
+ lBitMask[8]:= 255;
+ lBitMask[9]:= 511;
+ lBitMask[10]:= 1023;
+ lBitMask[11]:= 2047;
+ lBitMask[12]:= 4095;
+ lBitMask[13]:= 8191;
+ lBitMask[14]:= 16383;
+ lBitMask[15]:= 32767;
+ lBitMask[16]:= 65535;
+ lBitMask[17]:= 131071; //ONLY required for Osiris corrupted images, see DecodePixelDifference for details
+ //NEXT: some RGB images use only a single Huffman table for all 3 colour planes. In this case, replicate the correct values
+ if (lnHufTables < SOFnf) then begin //use single Hufman table for each frame
+ //showmessage('generating tables'+inttostr(SOFnf));
+ if lnHufTables < 1 then begin
+ dcmMsg('Lossless JPEG decoding error: no Huffman tables.');
+ goto 123;
+ end;
+ for lFrameCount := 2 to SOFnf do begin
+ for lInc := 1 to 16 do
+ DHTstartRA[lFrameCount,lInc] := DHTstartRA[1,lInc];
+ for lInc := 0 to 31 do begin
+ lHufRA[lFrameCount,lInc].HufCode := lHufRA[1,lInc].HufCode;
+ lHufRA[lFrameCount,lInc].HufVal := lHufRA[1,lInc].HufVal;
+ lHufRA[lFrameCount,lInc].HufSz := lHufRA[1,lInc].HufSz;
+ DHTliRA[lFrameCount,lInc] := DHTliRA[1,lInc];
+ end; //for each table entry
+ end; //for each frame xx
+ end;// if lnHufTables < SOFnf
+ for lFrameCount := 1 to kMaxFrames do
+ for lInc := 0 to 17 do
+ lSSSSszRA[lFrameCount,lInc] := 123; //Impossible value for SSSS, suggests 8-bits can not describe answer
+ for lFrameCount := 1 to kMaxFrames do
+ for lInc := 0 to 255 do
+ lLookUpRA[lFrameCount,lInc] := 255; //Impossible value for SSSS, suggests 8-bits can not describe answer
+ //NEXT fill lookuptable
+ for lFrameCount := 1 to SOFnf do begin
+ lIncY := 0;
+ for lSz := 1 to 8 do begin //set the huffman lookup table for keys with lengths <=8
+ if DHTliRA[lFrameCount,lSz]> 0 then begin
+ for lIncX := 1 to DHTliRA[lFrameCount,lSz] do begin
+ inc(lIncY);
+ lHufVal := lHufRA[lFrameCount,lIncY].HufVal; //SSSS
+ {if (lHufVal < 0) or (lHufVal > 17) then begin
+ showmessage('Unknown SSSS =' +inttostr(lHufVal));
+ lHufVal := 16;
+ end; }
+ lSSSSszRA[lFrameCount,lHufVal] := lSz;
+ k := (lHufRA[lFrameCount,lIncY].HufCode shl (8-lSz )) and 255; //K= most sig bits for hufman table
+ if lSz < 8 then begin //fill in all possible bits that exceed the huffman table
+ lInc := lBitMask[8-lSz];
+ for lCurrentBitPos := 0 to lInc do begin
+ lLookUpRA[lFrameCount,k+lCurrentBitPos] := lHufVal;
+ end;
+ end else
+ lLookUpRA[lFrameCount,k] := lHufVal; //SSSS
+
+ {Showmessage('Frame ' + inttostr(lFrameCount) + ' SSSS= '+inttostr(lHufRA[lFrameCount,lIncY].HufVal)+
+ ' Size= '+inttostr(lHufRA[1,lIncY].HufSz)+
+ ' Code= '+inttostr(lHufRA[1,lIncY].HufCode)+
+ ' SHL Code= '+inttostr(k)+
+ ' EmptyBits= '+inttostr(lInc)); {}
+ end; //Set SSSS
+ end; //Length of size lInc > 0
+ end; //for lInc := 1 to 8
+ end; //For each frame, e.g. once each for Red/Green/Blue
+ //Next: uncompress data: different loops for different predictors
+ SOFxdim:= SOFnf*SOFxdim;
+ lItems := SOFxdim*SOFydim;
+ //if lVerbose then showmessage('precision'+inttostr(SOFprecision));
+ //for timing, multiple decoding loops lRawAbba := lRawPos;for lLoopsAbba := 1 to 100 do begin lRawPos := lRawAbba;
+ //if (lRestartSegmentSz > 0) and ((SOFPrecision<> 8) or (SOSss = 7)) then //add restart support if we ever find any samples to test
+ // showmessage('This image uses restart markers. Please contact the author. Predictor:Precision '+inttostr(SOSss)+':'+inttostr(SOFPrecision));
+ inc(lRawPos);//abbax
+ lCurrentBitPos := 0; //read in a new byte
+ //lCurrentBitPos := 1; //read in a new byte
+ lItems := SOFxdim*SOFydim;
+ lPredicted := 1 shl (SOFPrecision-1-SOSpttrans);
+ lInc := 0;
+ if (SOFPrecision<> 8) then begin //start - 16 bit data
+ lImgRA := @lOutSmallRA[0];{set to 1 for MRIcro, else 0}
+ FillChar(lImgRA^,lItems*sizeof(word), 0); //zero array
+ lPredB:= 0;
+ lPredC := 0;
+ case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
+ 2: lPredA:= SOFxDim-1; //Rb directly above
+ 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
+ 4,5: begin
+ lPredA := 0;
+ lPredB := SOFxDim-1; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ 6: begin
+ lPredB := 0;
+ lPredA := SOFxDim-1; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ else lPredA := 0; //Ra: directly to left
+ end; //case SOSss: predictor offset
+ for lIncX := 1 to SOFxdim do begin
+ inc(lInc); //writenext voxel
+ if lInc > 1 then lPredicted := lImgRA[lInc-1];
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //first line: use prev voxel prediction;
+ if lRestartSegmentSz = 0 then begin
+ for lIncY := 2 to SOFyDim do begin
+ inc(lInc); //write next voxel
+ lPredicted := lImgRA[lInc-SOFxdim];
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ if SOSss = 4 then begin
+ for lIncX := 2 to SOFxdim do begin
+ lPredicted := lImgRA[lInc-lPredA]+lImgRA[lInc-lPredB]-lImgRA[lInc-lPredC];
+ inc(lInc); //writenext voxel
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //for lIncX
+ end else if (SOSss = 5) or (SOSss = 6) then begin
+ for lIncX := 2 to SOFxdim do begin
+ lPredicted := lImgRA[lInc-lPredA]+ ((lImgRA[lInc-lPredB]-lImgRA[lInc-lPredC]) shr 1);
+ inc(lInc); //writenext voxel
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //for lIncX
+ end else if SOSss = 7 then begin
+ for lIncX := 2 to SOFxdim do begin
+ inc(lInc); //writenext voxel
+ lPredicted := (lImgRA[lInc-1]+lImgRA[lInc-SOFxdim]) shr 1;
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //for lIncX
+ end else begin //SOSss 1,2,3 read single values
+ for lIncX := 2 to SOFxdim do begin
+ lPredicted := lImgRA[lInc-lPredA];
+ inc(lInc); //writenext voxel
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //for lIncX
+ end; //SOSss predictor
+
+
+ end; //for lIncY
+ end {RestartSegmentSz = 0} else begin {restartsegment}
+ if SOSss > 3 then
+ dcmMsg('Unusual 16-bit lossless JPEG with restart segments. Please contact the author:'+inttostr(SOSss));
+ lSegmentEnd := lRestartSegmentSz;
+ repeat
+ if lSegmentEnd > lItems then lSegmentEnd := lItems;
+ lLineStart := (((lInc div SOFxDim)+1)* SOFxDim){-1};
+ if lInc > (SOFxDim+1) then
+ lPredicted := 1 shl (SOFPrecision-1-SOSpttrans)
+ else
+ lPredicted := lImgRA[lInc-SOFxdim];
+
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRA[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredicted := lImgRA[lInc-lPredA];
+ end;
+ if (lSegmentEnd+1) < lItems then begin
+ dec(lRawPos);
+ repeat
+ while (lRawRA[lRawPos] <> 255) do
+ inc(lRawPos);
+ inc(lRawPos);
+ until (lRawRA[lRawPos] >= $D0) and (lRawRA[lRawPos] <= $D7);
+ lCurrentBitPos := 0; //read in a new byte
+ inc(lRawPos);//abbax
+ end;
+ lSegmentEnd := lSegmentEnd + lRestartSegmentSz;
+ until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
+ end; //restartsegments
+ end else if SOFnf = 3 then begin //>8bit data; 8 bit follows
+ //LOSSLESS JPEG: 7 possible predictors - we will handle all of them
+ lPredB:= 0;
+ lPredC := 0;
+ case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
+ 2: lPredA:= SOFxDim-3; //Rb directly above
+ 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
+ 5: begin
+ lPredA := 0;
+ lPredB := SOFxDim-3; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ 6: begin
+ lPredB := 0;
+ lPredA := SOFxDim-3; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ else lPredA := 0; //Ra: directly to left
+ end; //case SOSss: predictor offset
+ lPredictedG := lPredicted;
+ lPredictedB := lPredicted;
+ lOffset := 0;
+ lInc := lOffset;
+ for lIncX := 1 to (SOFxdim div 3) do begin //write first line
+ //DecodePixelDifference=RED
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ lPredicted := lImgRAz[lInc];
+ inc(lInc); //writenext voxel
+ //DecodePixelDifference=GREEN
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2);
+ lPredictedG := lImgRAz[lInc];
+ inc(lInc); //writenext voxel
+ //DecodePixelDifference=BLUE
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3);
+ lPredictedB := lImgRAz[lInc];
+ inc(lInc); //writenext voxel
+ end; //first line: use prev voxel prediction;
+ if lRestartSegmentSz = 0 then lSegmentEnd := lItems
+ else lSegmentEnd := lRestartSegmentSz;
+ repeat
+ if lSegmentEnd > lItems then lSegmentEnd := lItems;
+ lLineStart := (((lInc div SOFxDim)+1)* SOFxDim)+lOffset{-1};
+ if lInc > (SOFxDim+1) then begin
+ lPredicted := 1 shl (SOFPrecision-1-SOSpttrans);
+ lPredictedG := lPredicted;
+ lPredictedB := lPredicted;
+ end else begin
+ lPredicted := lImgRAz[lInc-SOFxdim+lOffset];
+ lPredictedG := lImgRAz[1+lInc-SOFxdim+lOffset];
+ lPredictedB := lImgRAz[2+lInc-SOFxdim+lOffset];
+ end;
+ if SOSss = 4 then begin //predictor = 4
+ //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
+ while lInc < (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1); //RED
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
+ inc(lInc);
+ if lInc = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ lPredictedG := lImgRAz[lInc-SOFxdim+1];
+ lPredictedB := lImgRAz[lInc-SOFxdim+2];
+ lLineStart := lLineStart + (SOFxDim);
+ end else begin
+ lPredicted := lImgRAz[lInc-3]+lImgRAz[lInc-3-(SOFxDim-3)]-lImgRAz[lInc-3-SOFxDim];
+ lPredictedG := lImgRAz[lInc-2]+lImgRAz[lInc-2-(SOFxDim-3)]-lImgRAz[lInc-2-SOFxDim];
+ lPredictedB := lImgRAz[lInc-1]+lImgRAz[lInc-1-(SOFxDim-3)]-lImgRAz[lInc-1-SOFxDim];
+ end;
+ end;
+ //xxx
+ end else if (SOSss = 5) or (SOSss = 6) then begin //predictor = 5 or 6
+ //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
+ while lInc < (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1); //RED
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
+ inc(lInc);
+ if lInc = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ lPredictedG := lImgRAz[lInc-SOFxdim+1];
+ lPredictedB := lImgRAz[lInc-SOFxdim+2];
+ lLineStart := lLineStart + (SOFxDim);
+ end else begin
+ lPredicted := lImgRAz[lInc-3-lPredA]+((lImgRAz[lInc-3-lPredB]-lImgRAz[lInc-3-lPredC])shr 1);
+ lPredictedG := lImgRAz[lInc-2-lPredA]+((lImgRAz[lInc-2-lPredB]-lImgRAz[lInc-2-lPredC])shr 1);
+ lPredictedB := lImgRAz[lInc-1-lPredA]+((lImgRAz[lInc-1-lPredB]-lImgRAz[lInc-1-lPredC])shr 1);
+ end;
+ end;
+ end else if SOSss = 7 then begin //predictor = 7
+ while lInc < (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1); //RED
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
+ inc(lInc);
+ if lInc = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ lPredictedG := lImgRAz[lInc-SOFxdim+1];
+ lPredictedB := lImgRAz[lInc-SOFxdim+2];
+ lLineStart := lLineStart + (SOFxDim);
+ end else begin
+ lPredicted := (lImgRAz[lInc-3]+lImgRAz[lInc-3-(SOFxDim-3)])shr 1;
+ lPredictedG := (lImgRAz[lInc-2]+lImgRAz[lInc-2-(SOFxDim-3)]) shr 1;
+ lPredictedB := (lImgRAz[lInc-1]+lImgRAz[lInc-1-(SOFxDim-3)]) shr 1;
+ end;
+ end;
+
+ end else begin //predictor in range 1,2,3
+ //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
+ while lInc < (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1); //RED
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
+ inc(lInc);
+ if lInc = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ lPredictedG := lImgRAz[lInc-SOFxdim+1];
+ lPredictedB := lImgRAz[lInc-SOFxdim+2];
+ lLineStart := lLineStart + (SOFxDim);
+ end else begin
+ lPredicted := lImgRAz[lInc-3-lPredA];
+ lPredictedG := lImgRAz[lInc-2-lPredA];
+ lPredictedB := lImgRAz[lInc-1-lPredA];
+ end;
+ end;
+ end; //predictor <> 7
+ until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
+ // end; //8<>15data type
+ end else begin //previously 12/16/24bit data, 8 bit follows
+ lInc := 0;
+ //LOSSLESS JPEG: 7 possible predictors - we will handle all of them
+ lPredB:= 0;
+ lPredC := 0;
+ case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
+ 2: lPredA:= SOFxDim-1; //Rb directly above
+ 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
+ 5: begin
+ lPredA := 0;
+ lPredB := SOFxDim-1; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ 6: begin
+ lPredB := 0;
+ lPredA := SOFxDim-1; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ else lPredA := 0; //Ra: directly to left
+ end; //case SOSss: predictor offset
+ //lOffset := -1;
+ for lIncX := 1 to SOFxdim do begin //write first line
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ inc(lInc); //writenext voxel
+ lPredicted := lImgRAz[lInc-1];
+ end; //first line: use prev voxel prediction;
+ if lRestartSegmentSz = 0 then lSegmentEnd := lItems
+ else lSegmentEnd := lRestartSegmentSz;
+ repeat
+ if lSegmentEnd > lItems then lSegmentEnd := lItems;
+ lLineStart := (((lInc div SOFxDim)+1)* SOFxDim){-1};
+ if lInc > (SOFxDim+1) then
+ lPredicted := 1 shl (SOFPrecision-1-SOSpttrans)
+ else
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ if SOSss = 4 then begin //predictor 4 : ABOVE+LEFT-(UPPERLEFT)
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredicted := lImgRAz[lInc]+lImgRAz[lInc-(SOFxDim-1)] -lImgRAz[lInc-SOFxDim] ;
+ end;
+
+ end else if (SOSss = 5) or (SOSss=6) then begin //predictor 5,6 : comparisons
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredicted := lImgRAz[lInc-lPredA]+((lImgRAz[lInc-lPredB]-lImgRAz[lInc-lPredC]) shr 1) ;
+ end;
+ end else if SOSss = 7 then begin //predictor 7: average above and left
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredA := lImgRAz[lInc];
+ lPredB:= lImgRAz[lInc-SOFxDim+1];//correct
+ lPredicted := (lPredA+lPredB) shr 1;
+ end;
+ end else begin //predictor <> 7 : assume SOSss=1: previous
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredicted := lImgRAz[lInc-lPredA];
+ end;
+ end; //predictor <> 7
+ if (lSegmentEnd+1) < lItems then begin
+ dec(lRawPos);
+ repeat
+ while (lRawRA[lRawPos] <> 255) do
+ inc(lRawPos);
+ inc(lRawPos);
+ until (lRawRA[lRawPos] >= $D0) and (lRawRA[lRawPos] <= $D7);
+ lCurrentBitPos := 0; //read in a new byte
+ inc(lRawPos);
+ //lCurrentBitPos := 9; //read in a new byte
+ end;
+ lSegmentEnd := lSegmentEnd + lRestartSegmentSz;
+ until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
+ end; //8<>15data type
+123:
+ FreeMem( lRawRA); //release memory buffer
+end;
+
+end.
diff --git a/dcm2nii/manifest.or b/dcm2nii/manifest.or
old mode 100644
new mode 100755
diff --git a/dcm2nii/manifest.res b/dcm2nii/manifest.res
deleted file mode 100644
index 1421866..0000000
Binary files a/dcm2nii/manifest.res and /dev/null differ
diff --git a/dcm2nii/nifti_form.dfm b/dcm2nii/nifti_form.dfm
old mode 100644
new mode 100755
diff --git a/dcm2nii/nifti_form.lfm b/dcm2nii/nifti_form.lfm
old mode 100644
new mode 100755
index a56f450..b6de3d9
--- a/dcm2nii/nifti_form.lfm
+++ b/dcm2nii/nifti_form.lfm
@@ -1,7 +1,7 @@
object NIfTIForm: TNIfTIForm
- Left = 250
+ Left = 797
Height = 266
- Top = 98
+ Top = 32
Width = 338
ActiveControl = OKBtn
BorderIcons = [biSystemMenu]
@@ -14,21 +14,21 @@ object NIfTIForm: TNIfTIForm
Constraints.MinHeight = 266
Constraints.MinWidth = 338
OnCreate = FormCreate
- LCLVersion = '0.9.29'
+ LCLVersion = '0.9.30.2'
object Label1: TLabel
Left = 8
- Height = 14
+ Height = 17
Top = 168
- Width = 79
+ Width = 102
Alignment = taCenter
Caption = 'Output Format: '
ParentColor = False
end
object Label4: TLabel
Left = 8
- Height = 14
+ Height = 17
Top = 16
- Width = 27
+ Width = 35
Alignment = taCenter
Caption = 'Task:'
ParentColor = False
@@ -56,10 +56,10 @@ object NIfTIForm: TNIfTIForm
end
object TypeCombo: TComboBox
Left = 118
- Height = 21
+ Height = 20
Top = 163
Width = 209
- ItemHeight = 13
+ ItemHeight = 0
Items.Strings = (
'SPM2 (3D Anlyze hdr/img)'
'SPM5 (3D NIfTI hdr/img)'
@@ -73,51 +73,53 @@ object NIfTIForm: TNIfTIForm
TabOrder = 2
end
object Panel1: TPanel
- Left = 40
+ Left = 8
Height = 103
- Top = 48
- Width = 275
+ Top = 59
+ Width = 312
BevelOuter = bvNone
ClientHeight = 103
- ClientWidth = 275
+ ClientWidth = 312
TabOrder = 3
object Label2: TLabel
Left = 8
- Height = 14
+ Height = 17
Top = 15
- Width = 143
+ Width = 190
Caption = 'Volumes to remove from start'
ParentColor = False
end
object Label3: TLabel
Left = 7
- Height = 14
+ Height = 17
Top = 55
- Width = 143
- Caption = 'Volumes to remove from start'
+ Width = 185
+ Caption = 'Volumes to remove from end'
ParentColor = False
end
object StartEdit: TSpinEdit
- Left = 196
- Height = 21
- Top = 6
+ Left = 224
+ Height = 16
+ Top = 13
Width = 74
+ MaxValue = 9999999
TabOrder = 0
end
object EndEdit: TSpinEdit
- Left = 196
- Height = 21
- Top = 46
+ Left = 224
+ Height = 16
+ Top = 53
Width = 74
+ MaxValue = 9999999
TabOrder = 1
end
end
object Combo4D: TComboBox
Left = 47
- Height = 21
+ Height = 20
Top = 11
- Width = 188
- ItemHeight = 13
+ Width = 280
+ ItemHeight = 0
Items.Strings = (
'Change format'
'Flip dimensions 3 and 4'
@@ -131,11 +133,11 @@ object NIfTIForm: TNIfTIForm
TabOrder = 4
end
object Combo3D: TComboBox
- Left = 74
- Height = 21
+ Left = 48
+ Height = 20
Top = 11
- Width = 188
- ItemHeight = 13
+ Width = 279
+ ItemHeight = 0
Items.Strings = (
'Change format'
'Reorient to orthogonal'
@@ -147,7 +149,7 @@ object NIfTIForm: TNIfTIForm
object ASLPanel: TPanel
Left = 40
Height = 50
- Top = 40
+ Top = 24
Width = 275
BevelOuter = bvNone
ClientHeight = 50
@@ -155,10 +157,10 @@ object NIfTIForm: TNIfTIForm
TabOrder = 6
object ASLCombo: TComboBox
Left = 16
- Height = 21
+ Height = 20
Top = 11
Width = 246
- ItemHeight = 13
+ ItemHeight = 0
Items.Strings = (
'Subtract pairs - first image tagged'
'Subtract pairs - first image control'
@@ -172,7 +174,7 @@ object NIfTIForm: TNIfTIForm
object FormulaPanel: TPanel
Left = 47
Height = 114
- Top = 37
+ Top = 56
Width = 273
BevelOuter = bvNone
ClientHeight = 114
@@ -180,25 +182,25 @@ object NIfTIForm: TNIfTIForm
TabOrder = 7
object Label5: TLabel
Left = 31
- Height = 14
+ Height = 17
Top = 17
- Width = 26
+ Width = 33
Alignment = taCenter
Caption = 'Scale'
ParentColor = False
end
object Label6: TLabel
Left = 31
- Height = 14
+ Height = 17
Top = 59
- Width = 31
+ Width = 39
Alignment = taCenter
Caption = 'Power'
ParentColor = False
end
object ScaleEdit: TFloatSpinEdit
Left = 127
- Height = 21
+ Height = 16
Top = 11
Width = 130
DecimalPlaces = 8
@@ -210,7 +212,7 @@ object NIfTIForm: TNIfTIForm
end
object PowerEdit: TFloatSpinEdit
Left = 127
- Height = 21
+ Height = 16
Top = 56
Width = 130
DecimalPlaces = 8
@@ -221,4 +223,4 @@ object NIfTIForm: TNIfTIForm
Value = 1.2E-6
end
end
-end
+end
\ No newline at end of file
diff --git a/dcm2nii/nifti_form.lrs b/dcm2nii/nifti_form.lrs
old mode 100644
new mode 100755
index b4ac49b..eb9a942
--- a/dcm2nii/nifti_form.lrs
+++ b/dcm2nii/nifti_form.lrs
@@ -1,61 +1,62 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TNIfTIForm','FORMDATA',[
- 'TPF0'#10'TNIfTIForm'#9'NIfTIForm'#4'Left'#3#250#0#6'Height'#3#10#1#3'Top'#2
- +'b'#5'Width'#3'R'#1#13'ActiveControl'#7#5'OKBtn'#11'BorderIcons'#11#12'biSys'
- +'temMenu'#0#11'BorderStyle'#7#8'bsDialog'#7'Caption'#6#18'Convert NIfTI File'
- +#12'ClientHeight'#3#10#1#11'ClientWidth'#3'R'#1#21'Constraints.MaxHeight'#3
- +#10#1#20'Constraints.MaxWidth'#3'R'#1#21'Constraints.MinHeight'#3#10#1#20'Co'
- +'nstraints.MinWidth'#3'R'#1#8'OnCreate'#7#10'FormCreate'#10'LCLVersion'#6#6
- +'0.9.29'#0#6'TLabel'#6'Label1'#4'Left'#2#8#6'Height'#2#14#3'Top'#3#168#0#5'W'
- +'idth'#2'O'#9'Alignment'#7#8'taCenter'#7'Caption'#6#15'Output Format: '#11'P'
- +'arentColor'#8#0#0#6'TLabel'#6'Label4'#4'Left'#2#8#6'Height'#2#14#3'Top'#2#16
- +#5'Width'#2#27#9'Alignment'#7#8'taCenter'#7'Caption'#6#5'Task:'#11'ParentCol'
- +'or'#8#0#0#7'TButton'#5'OKBtn'#4'Left'#3#200#0#6'Height'#2#25#3'Top'#3#208#0
- +#5'Width'#2'K'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#2'OK'#11'Modal'
- +'Result'#2#1#7'OnClick'#7#10'OKBtnClick'#8'TabOrder'#2#0#0#0#7'TButton'#9'Ca'
- +'ncelBtn'#4'Left'#2'h'#6'Height'#2#25#3'Top'#3#208#0#5'Width'#2'K'#25'Border'
- +'Spacing.InnerBorder'#2#4#7'Caption'#6#6'Cancel'#11'ModalResult'#2#2#8'TabOr'
- +'der'#2#1#0#0#9'TComboBox'#9'TypeCombo'#4'Left'#2'v'#6'Height'#2#21#3'Top'#3
- +#163#0#5'Width'#3#209#0#10'ItemHeight'#2#13#13'Items.Strings'#1#6#24'SPM2 (3'
- +'D Anlyze hdr/img)'#6#23'SPM5 (3D NIfTI hdr/img)'#6#19'SPM8 (3D NIfTI nii)'#6
- +#16'4D NIfTI hdr/img'#6#18'FSL (4D NIfTI nii)'#6#29'Compressed FSL (4D NIfTI'
- +' nii)'#6#21'MRIcron drawing (voi)'#0#5'Style'#7#14'csDropDownList'#8'TabOrd'
- +'er'#2#2#0#0#6'TPanel'#6'Panel1'#4'Left'#2'('#6'Height'#2'g'#3'Top'#2'0'#5'W'
- +'idth'#3#19#1#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'g'#11'ClientWidt'
- +'h'#3#19#1#8'TabOrder'#2#3#0#6'TLabel'#6'Label2'#4'Left'#2#8#6'Height'#2#14#3
- +'Top'#2#15#5'Width'#3#143#0#7'Caption'#6#28'Volumes to remove from start'#11
- +'ParentColor'#8#0#0#6'TLabel'#6'Label3'#4'Left'#2#7#6'Height'#2#14#3'Top'#2
- +'7'#5'Width'#3#143#0#7'Caption'#6#28'Volumes to remove from start'#11'Parent'
- +'Color'#8#0#0#9'TSpinEdit'#9'StartEdit'#4'Left'#3#196#0#6'Height'#2#21#3'Top'
- +#2#6#5'Width'#2'J'#8'TabOrder'#2#0#0#0#9'TSpinEdit'#7'EndEdit'#4'Left'#3#196
- +#0#6'Height'#2#21#3'Top'#2'.'#5'Width'#2'J'#8'TabOrder'#2#1#0#0#0#9'TComboBo'
- +'x'#7'Combo4D'#4'Left'#2'/'#6'Height'#2#21#3'Top'#2#11#5'Width'#3#188#0#10'I'
- +'temHeight'#2#13#13'Items.Strings'#1#6#13'Change format'#6#23'Flip dimension'
- +'s 3 and 4'#6#21'Clip 1st/Last Volumes'#6#21'Export as 32-bit real'#6#13'App'
- +'ly formula'#6#14'ASL conversion'#0#8'OnChange'#7#13'Combo4DChange'#5'Style'
- +#7#14'csDropDownList'#8'TabOrder'#2#4#0#0#9'TComboBox'#7'Combo3D'#4'Left'#2
- +'J'#6'Height'#2#21#3'Top'#2#11#5'Width'#3#188#0#10'ItemHeight'#2#13#13'Items'
- +'.Strings'#1#6#13'Change format'#6#22'Reorient to orthogonal'#6#17'Reorient '
- +'and crop'#0#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#5#0#0#6'TPanel'#8'A'
- +'SLPanel'#4'Left'#2'('#6'Height'#2'2'#3'Top'#2'('#5'Width'#3#19#1#10'BevelOu'
- +'ter'#7#6'bvNone'#12'ClientHeight'#2'2'#11'ClientWidth'#3#19#1#8'TabOrder'#2
- +#6#0#9'TComboBox'#8'ASLCombo'#4'Left'#2#16#6'Height'#2#21#3'Top'#2#11#5'Widt'
- +'h'#3#246#0#10'ItemHeight'#2#13#13'Items.Strings'#1#6'#Subtract pairs - firs'
- +'t image tagged'#6'$Subtract pairs - first image control'#6#15'Subtract Cust'
- +'om'#6#19'Add (odd+even) BOLD'#0#5'Style'#7#14'csDropDownList'#8'TabOrder'#2
- +#0#0#0#0#6'TPanel'#12'FormulaPanel'#4'Left'#2'/'#6'Height'#2'r'#3'Top'#2'%'#5
- +'Width'#3#17#1#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'r'#11'ClientWid'
- +'th'#3#17#1#8'TabOrder'#2#7#0#6'TLabel'#6'Label5'#4'Left'#2#31#6'Height'#2#14
- +#3'Top'#2#17#5'Width'#2#26#9'Alignment'#7#8'taCenter'#7'Caption'#6#5'Scale'
- +#11'ParentColor'#8#0#0#6'TLabel'#6'Label6'#4'Left'#2#31#6'Height'#2#14#3'Top'
- +#2';'#5'Width'#2#31#9'Alignment'#7#8'taCenter'#7'Caption'#6#5'Power'#11'Pare'
- +'ntColor'#8#0#0#14'TFloatSpinEdit'#9'ScaleEdit'#4'Left'#2#127#6'Height'#2#21
- +#3'Top'#2#11#5'Width'#3#130#0#13'DecimalPlaces'#2#8#9'Increment'#5#0#0#0#0#0
- +#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0
- +#0#0#0#0#0#8'TabOrder'#2#0#5'Value'#5#0#176#27'l'#160#175#15#161#235'?'#0#0
- +#14'TFloatSpinEdit'#9'PowerEdit'#4'Left'#2#127#6'Height'#2#21#3'Top'#2'8'#5
- +'Width'#3#130#0#13'DecimalPlaces'#2#8#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'
- +#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'Ta'
- +'bOrder'#2#1#5'Value'#5#0#176#27'l'#160#175#15#161#235'?'#0#0#0#0
-]);
+ 'TPF0'#10'TNIfTIForm'#9'NIfTIForm'#4'Left'#3#29#3#6'Height'#3#10#1#3'Top'#2' '
+ +#5'Width'#3'R'#1#13'ActiveControl'#7#5'OKBtn'#11'BorderIcons'#11#12'biSystem'
+ +'Menu'#0#11'BorderStyle'#7#8'bsDialog'#7'Caption'#6#18'Convert NIfTI File'#12
+ +'ClientHeight'#3#10#1#11'ClientWidth'#3'R'#1#21'Constraints.MaxHeight'#3#10#1
+ +#20'Constraints.MaxWidth'#3'R'#1#21'Constraints.MinHeight'#3#10#1#20'Constra'
+ +'ints.MinWidth'#3'R'#1#8'OnCreate'#7#10'FormCreate'#10'LCLVersion'#6#8'0.9.3'
+ +'0.2'#0#6'TLabel'#6'Label1'#4'Left'#2#8#6'Height'#2#17#3'Top'#3#168#0#5'Widt'
+ +'h'#2'f'#9'Alignment'#7#8'taCenter'#7'Caption'#6#15'Output Format: '#11'Pare'
+ +'ntColor'#8#0#0#6'TLabel'#6'Label4'#4'Left'#2#8#6'Height'#2#17#3'Top'#2#16#5
+ +'Width'#2'#'#9'Alignment'#7#8'taCenter'#7'Caption'#6#5'Task:'#11'ParentColor'
+ +#8#0#0#7'TButton'#5'OKBtn'#4'Left'#3#200#0#6'Height'#2#25#3'Top'#3#208#0#5'W'
+ +'idth'#2'K'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#2'OK'#11'ModalRes'
+ +'ult'#2#1#7'OnClick'#7#10'OKBtnClick'#8'TabOrder'#2#0#0#0#7'TButton'#9'Cance'
+ +'lBtn'#4'Left'#2'h'#6'Height'#2#25#3'Top'#3#208#0#5'Width'#2'K'#25'BorderSpa'
+ +'cing.InnerBorder'#2#4#7'Caption'#6#6'Cancel'#11'ModalResult'#2#2#8'TabOrder'
+ +#2#1#0#0#9'TComboBox'#9'TypeCombo'#4'Left'#2'v'#6'Height'#2#20#3'Top'#3#163#0
+ +#5'Width'#3#209#0#10'ItemHeight'#2#0#13'Items.Strings'#1#6#24'SPM2 (3D Anlyz'
+ +'e hdr/img)'#6#23'SPM5 (3D NIfTI hdr/img)'#6#19'SPM8 (3D NIfTI nii)'#6#16'4D'
+ +' NIfTI hdr/img'#6#18'FSL (4D NIfTI nii)'#6#29'Compressed FSL (4D NIfTI nii)'
+ +#6#21'MRIcron drawing (voi)'#0#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#2
+ +#0#0#6'TPanel'#6'Panel1'#4'Left'#2#8#6'Height'#2'g'#3'Top'#2';'#5'Width'#3'8'
+ +#1#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'g'#11'ClientWidth'#3'8'#1#8
+ +'TabOrder'#2#3#0#6'TLabel'#6'Label2'#4'Left'#2#8#6'Height'#2#17#3'Top'#2#15#5
+ +'Width'#3#190#0#7'Caption'#6#28'Volumes to remove from start'#11'ParentColor'
+ +#8#0#0#6'TLabel'#6'Label3'#4'Left'#2#7#6'Height'#2#17#3'Top'#2'7'#5'Width'#3
+ +#185#0#7'Caption'#6#26'Volumes to remove from end'#11'ParentColor'#8#0#0#9'T'
+ +'SpinEdit'#9'StartEdit'#4'Left'#3#224#0#6'Height'#2#16#3'Top'#2#13#5'Width'#2
+ +'J'#8'MaxValue'#4#127#150#152#0#8'TabOrder'#2#0#0#0#9'TSpinEdit'#7'EndEdit'#4
+ +'Left'#3#224#0#6'Height'#2#16#3'Top'#2'5'#5'Width'#2'J'#8'MaxValue'#4#127#150
+ +#152#0#8'TabOrder'#2#1#0#0#0#9'TComboBox'#7'Combo4D'#4'Left'#2'/'#6'Height'#2
+ +#20#3'Top'#2#11#5'Width'#3#24#1#10'ItemHeight'#2#0#13'Items.Strings'#1#6#13
+ +'Change format'#6#23'Flip dimensions 3 and 4'#6#21'Clip 1st/Last Volumes'#6
+ +#21'Export as 32-bit real'#6#13'Apply formula'#6#14'ASL conversion'#0#8'OnCh'
+ +'ange'#7#13'Combo4DChange'#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#4#0#0
+ +#9'TComboBox'#7'Combo3D'#4'Left'#2'0'#6'Height'#2#20#3'Top'#2#11#5'Width'#3
+ +#23#1#10'ItemHeight'#2#0#13'Items.Strings'#1#6#13'Change format'#6#22'Reorie'
+ +'nt to orthogonal'#6#17'Reorient and crop'#0#5'Style'#7#14'csDropDownList'#8
+ +'TabOrder'#2#5#0#0#6'TPanel'#8'ASLPanel'#4'Left'#2'('#6'Height'#2'2'#3'Top'#2
+ +#24#5'Width'#3#19#1#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'2'#11'Clie'
+ +'ntWidth'#3#19#1#8'TabOrder'#2#6#0#9'TComboBox'#8'ASLCombo'#4'Left'#2#16#6'H'
+ +'eight'#2#20#3'Top'#2#11#5'Width'#3#246#0#10'ItemHeight'#2#0#13'Items.String'
+ +'s'#1#6'#Subtract pairs - first image tagged'#6'$Subtract pairs - first imag'
+ +'e control'#6#15'Subtract Custom'#6#19'Add (odd+even) BOLD'#0#5'Style'#7#14
+ +'csDropDownList'#8'TabOrder'#2#0#0#0#0#6'TPanel'#12'FormulaPanel'#4'Left'#2
+ +'/'#6'Height'#2'r'#3'Top'#2'8'#5'Width'#3#17#1#10'BevelOuter'#7#6'bvNone'#12
+ +'ClientHeight'#2'r'#11'ClientWidth'#3#17#1#8'TabOrder'#2#7#0#6'TLabel'#6'Lab'
+ +'el5'#4'Left'#2#31#6'Height'#2#17#3'Top'#2#17#5'Width'#2'!'#9'Alignment'#7#8
+ +'taCenter'#7'Caption'#6#5'Scale'#11'ParentColor'#8#0#0#6'TLabel'#6'Label6'#4
+ +'Left'#2#31#6'Height'#2#17#3'Top'#2';'#5'Width'#2''''#9'Alignment'#7#8'taCen'
+ +'ter'#7'Caption'#6#5'Power'#11'ParentColor'#8#0#0#14'TFloatSpinEdit'#9'Scale'
+ +'Edit'#4'Left'#2#127#6'Height'#2#16#3'Top'#2#11#5'Width'#3#130#0#13'DecimalP'
+ +'laces'#2#8#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0
+ +#0#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#0#5'Value'#5#0
+ +#176#27'l'#160#175#15#161#235'?'#0#0#14'TFloatSpinEdit'#9'PowerEdit'#4'Left'
+ +#2#127#6'Height'#2#16#3'Top'#2'8'#5'Width'#3#130#0#13'DecimalPlaces'#2#8#9'I'
+ +'ncrement'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8
+ +'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#1#5'Value'#5#0#176#27'l'#160
+ +#175#15#161#235'?'#0#0#0#0
+]);
\ No newline at end of file
diff --git a/dcm2nii/nifti_form.pas b/dcm2nii/nifti_form.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/niftiutil.pas b/dcm2nii/niftiutil.pas
old mode 100644
new mode 100755
index e469306..aaca33c
--- a/dcm2nii/niftiutil.pas
+++ b/dcm2nii/niftiutil.pas
@@ -1,14 +1,14 @@
unit niftiutil;
-
+ {$Include ..\common\isgui.inc}
interface
uses
{$IFDEF FPC}
-gzio2,
+ {$IFDEF GUI}FileUtil, {$ENDIF} //FileUtil requires LResources that requires extra environment variables with tools like matlab
+gzio2, process, //FileUtil,
{$ELSE}
-gziod,
+gziod, ShellAPI,Windows,Forms,
{$ENDIF}
-
- SysUtils,Classes,define_types,filename,dicomtypes,prefs;
+ SysUtils,Classes,define_types,filename,dicomtypes,prefs,dialogs_msg;
{$H+}
const
kNIIImgOffset = 352; //header is 348 bytes, but 352 is divisible by 8...
@@ -67,7 +67,7 @@ begin
end;
kDT_SIGNED_SHORT,kDT_SIGNED_INT,kDT_FLOAT: ;//supported format
else begin
- Msg('niftiutil UnSwapImg error: datatype not supported.');
+ dcmMsg('niftiutil UnSwapImg error: datatype not supported.');
exit;
end;
end; //case
@@ -183,29 +183,41 @@ begin
end;
if lmax < 32768 then begin //lossless: unsigned range <32768 (15 bits), so can be stored in signed 16bit
lInHdr.datatype := kDT_SIGNED_SHORT;
+ dcmMsg(' brightest voxel was '+inttostr(lmax)+': data will be saved as 16-bit signed integer.');
(*next lines not required, as range 0..32767 is stored identically for WORDS and SMALLINTS, see TestUINT16
l16i := SmallIntP(@lvBuffer^[lVolOffset]);
for lv := 1 to lnv do
l16i^[lv] := l16ui^[lv]; *)
end else if not lPrefs.UINT16toFLOAT32 then begin
- Msg('Warning: unusual NIFTI format UINT16, range: '+inttostr(lMax) );
- Msg(' If you prefer compatibility, edit your preference named UINT16toFLOAT32');
+ dcmMsg('Warning: unusual NIFTI format UINT16, range: '+inttostr(lMax) );
+ dcmMsg(' If you prefer compatibility, edit your preference named UINT16toFLOAT32');
end else begin
- Msg('Warning: for compatibility, converting UINT16->FLOAT32, range: '+inttostr(lMax) );
- Msg(' If you prefer filesize over compatibility, edit your preference named UINT16toFLOAT32');
+ dcmMsg('Warning: for compatibility, converting UINT16->FLOAT32, range: '+inttostr(lMax) );
+ dcmMsg(' If you prefer filesize over compatibility, edit your preference named UINT16toFLOAT32');
lInHdr.datatype := kDT_Float;
lInHdr.bitpix := 32;
lmax := lVolOffset+ (lnv*sizeof(Word));
GetMem(lTempB,lmax);
if lByteSwap then begin
+ dcmMsg(' Swapping data to native byte order (Big vs Little Endian)');
+ for lv := 1 to lnv do
+ l16ui^[lv] := swap(l16ui^[lv]);
+ end;
+ for lv := 1 to lmax do
+ lTempB^[lv] := lvBuffer^[lv];
+ (*if lByteSwap then begin
lByteSwap := false;
+ if (lVolOffset > 0) do
+ for lv := 1 to lVolOffset do
+ lTempB^[lv] := swap(lvBuffer^[lv]);
+ xx
for lv := 1 to lmax do
lTempB^[lv] := swap(lvBuffer^[lv]);
- Msg(' Swapping data to native byte order (Big vs Little Endian)');
+ Msg(' Swapping data to native byte order (Big vs Little Endian)');
end else begin
for lv := 1 to lmax do
lTempB^[lv] := lvBuffer^[lv];
- end;
+ end;*)
freemem(lvBuffer);
GetMem(lvBuffer,lVolOffset+ (lnv*sizeof(single)));
for lv := 1 to lVolOffset do //copy header
@@ -218,6 +230,135 @@ begin
end;// if range requires conversion to 32-bit float
end; //Uint16
+
+function getPigzNameWithPath: string;
+//returns path to pigz executable, e.g. '/Users/rorden/downloads/pigz-master/pigz';
+var
+ temp, exename: string;
+begin
+ {$IFDEF ENDIAN_BIG}
+ Msg('pigz not available with PowerPC computers');
+ result := '';
+ exit;
+ {$ENDIF}
+ {$IFDEF UNIX}
+ exename := 'pigz';
+ {$IFDEF GUI}
+ result := FindDefaultExecutablePath(exename); // "which pigz"
+ if length(result) > 0 then
+ exit;
+ {$ELSE}
+ result := exename;
+ if fileexists(result) then exit;
+ result := ExtractFilePath( paramstr(0))+exename;
+ if fileexists(result) then exit;
+ result := '/usr/bin/'+exename;
+ if fileexists(result) then exit;
+ result := '/usr/local/bin/'+exename;
+ if fileexists(result) then exit;
+ {$ENDIF}
+ {$ELSE}
+ exename := 'pigz.exe';
+ {$ENDIF}
+ //result := ExtractFilePath(Application.ExeName)+'pigz';
+ result := ExtractFilePath( paramstr(0))+exename;
+ if fileexists(result) then exit;
+ {$IFDEF DARWIN}
+ temp := result;
+ result := ExtractFilePath(paramstr(0));
+ result := LeftStr(result, Pos((ExtractFileName(paramstr(0))+'.app'), result)-1)+exename;
+ if fileexists(result) then exit;
+ {$IFDEF GUI}
+ dcmMsg('File compression error: pigz does not exist in you path or '+result+' or '+temp);
+ {$ELSE}
+ dcmMsg('File compression error: to use "pigz" place it in the same folder as '+ paramstr(0));
+ {$ENDIF}
+ {$ELSE}
+ {$IFDEF GUI}
+ dcmMsg('File compression error: pigz does not exist in you path or '+result);
+ {$ELSE}
+ dcmMsg('File compression error: to use "pigz" place it in the same folder as '+ paramstr(0));
+ {$ENDIF}
+
+ {$ENDIF}
+ result := '';
+end;
+
+{$IFDEF FPC} //Freepascal has handy 'Process' for calling console applications
+function runPigz(var lImgName : string; processes: integer): boolean;
+// abs(processes): 1= default (as many as available, 2..n: use this many processors
+// if processes is a NEGATIVE value, application does not wait for Pigz to complete...
+var
+ AProcess: TProcess;
+ Acmd: string;
+ AResponse: TStringList;
+ i: integer;
+begin
+ Acmd := getPigzNameWithPath; //+' -k' //<- to KEEP original
+ if length(Acmd) < 1 then exit;
+ //Acmd := Acmd +' -v -k';//verbose, keep files
+ if abs(processes) > 1 then
+ Acmd := Acmd + ' -p '+inttostr( abs(processes) );
+ Acmd := Acmd +' '+lImgName;
+ dcmMsg('External compression: '+Acmd);
+ AProcess := TProcess.Create(nil);
+ //AProcess.Environment.Add('FSLDIR='/usr/local/fsl/); //optional
+ AProcess.CommandLine := Acmd;
+ if (processes > 0) then //wait for pgzip to complete...
+ AProcess.Options := AProcess.Options + [poWaitOnExit, poStderrToOutPut, poUsePipes]
+ else //do not wait for pigz
+ AProcess.Options := AProcess.Options + [poStderrToOutPut, poUsePipes];
+ AProcess.Execute;
+ if (processes > 0) then begin//wait for pgzip to complete...
+ AResponse := TStringList.Create;
+ AResponse.LoadFromStream(AProcess.Output);
+ if AResponse.Count > 0 then
+ for i := 1 to AResponse.Count do
+ dcmMsg(' '+AResponse.Strings[i-1]);
+ AResponse.Free;
+ end;
+ AProcess.Free;
+end;
+{$ELSE} //Delphi does not have 'Process' for calling console applications
+
+procedure ExecNewProcess(AppName, ACmd : String; WaitUntilDone: boolean);
+var
+ StartInfo : TStartupInfo;
+ ProcInfo : TProcessInformation;
+ CreateOK : Boolean;
+begin
+ { fill with known state }
+ FillChar(StartInfo,SizeOf(TStartupInfo),#0);
+ FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
+ StartInfo.cb := SizeOf(TStartupInfo);
+ CreateOK := CreateProcess(PChar(AppName),Pchar(Acmd), nil, nil,False,
+ CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,
+ nil, nil, StartInfo, ProcInfo);
+ { check to see if successful }
+ if (CreateOK) and (WaitUntilDone) then
+ WaitForSingleObject(ProcInfo.hProcess, INFINITE);
+end;
+
+function runPigz(var lImgName : string; processes: integer): boolean;
+// abs(processes): 1= default (as many as available, 2..n: use this many processors
+// if processes is a NEGATIVE value, application does not wait for Pigz to complete...
+var
+ AppName, Acmd: string;
+begin
+ AppName := getPigzNameWithPath; //+' -k' //<- to KEEP original
+ if length(AppName) < 1 then exit;
+ Acmd := '';
+ //Acmd := Acmd +' -v -k';//verbose, keep files
+ if abs(processes) > 1 then
+ Acmd := Acmd + ' -p '+inttostr( abs(processes) );
+ Acmd := Acmd +' '+lImgName;
+ dcmMsg('External compression: '+AppName+' '+Acmd);
+ Acmd := AppName+' '+Acmd;
+ ExecNewProcess(AppName, ACmd, (processes > 0));
+end;
+{$ENDIF}
+
+
function SaveNIfTICore (var lOutImgName: string; var lvBuffer: bytep; lVolOffset: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs; var lByteSwap: boolean): string;
//image data should start at lVolOffset - this should be AT LEAST kNIIImgOffset (=352) bytes for creating .nii.gz files
//important note - when converting 4D to 3D to .nii format the lvBuffer is changed :: must correct this
@@ -253,7 +394,7 @@ begin
Filemode := 2;
lVolBytes := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]*lInHdr.dim[4]*trunc(((lInHdr.bitpix)+7)/8);
if ((kNIIImgOffset+lVolBytes)> DiskFreeEx(lNoGZName)) then begin
- Msg('There is not enough free space on the destination disk to save the data. '+kCR+
+ dcmMsg('There is not enough free space on the destination disk to save the data. '+kCR+
lNoGZName+ kCR+' Bytes Required: '+inttostr(lVolBytes) );
exit;
end;
@@ -262,7 +403,7 @@ begin
lVolStart := lVolOffset-kNIIImgOffset;
lVolBytes := lVolBytes + kNIIImgOffset;
if lVolStart < 1 then begin
- Msg('SaveNIfTICore Error: '+inttostr(lVolStart));
+ dcmMsg('SaveNIfTICore Error: '+inttostr(lVolStart));
exit;
end;
@@ -280,17 +421,24 @@ begin
SaveHdrRAM (lImgName,lInHdr,lOutHdr, lByteSwap,lPrefs.SPM2);
Move(lOutHdr,lvBuffer^[lVolStart],sizeof(lOutHdr)); //move 348 byte header in place
//finally - write buffer to disk
- if lPrefs.Gzip then begin
+ if (lPrefs.Gzip) and (lPrefs.usePigz <> 0) and (length(getPigzNameWithPath) > 0) then begin
+ AssignFile(lOutF, lImgName);
+ Rewrite(lOutF,1);
+ BlockWrite(lOutF, lvBuffer^[lVolStart], lVolBytes);
+ CloseFile(lOutF);
+ runPigz(lImgName, lPrefs.usePigz);
+ //DeleteFile(lImgName);
+ end else if lPrefs.Gzip then begin
if lPrefs.VOI then
lImgName := changefileext(lNoGZName,'.voi')
else
lImgName := changefileext(lNoGZName,'.nii.gz');
- Msg('GZip...' + extractfilename(lImgName));
+ dcmMsg('GZip...' + extractfilename(lImgName));
GZipBuffer(lImgName, @lvBuffer^[lVolStart],lVolBytes,true);
end else begin //not .nii.gz -> .nii
- Msg('Saving '+lImgName);
+ dcmMsg('Saving '+lImgName);
AssignFile(lOutF, lImgName);
Rewrite(lOutF,1);
BlockWrite(lOutF, lvBuffer^[lVolStart], lVolBytes);
@@ -361,7 +509,7 @@ begin
result := false;
if loadHdr then begin
if not NIFTIhdr_LoadHdr (lFilename, lHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
end;//if we load the header from disk...
@@ -379,11 +527,11 @@ begin
else
lImgName := lFilename;
if not fileexists(lImgName) then begin
- Msg('LoadImg Error: Unable to find '+lImgName);
+ dcmMsg('LoadImg Error: Unable to find '+lImgName);
exit;
end;
if (not lGZin) and (FSize (lImgName) < ( lImgBytes+round(lHdr.vox_offset))) then begin
- Msg('LoadImg Error: File smaller than expected '+lImgName);
+ dcmMsg('LoadImg Error: File smaller than expected '+lImgName);
exit;
end;
lFileBytes := lImgBytes+ lImgOffset;
@@ -479,7 +627,7 @@ var
begin
result := false;
if not NIFTIhdr_LoadImg (lHdrName, lHdr, lImgBuffer, lImgOffset,lByteSwap) then exit;
- Msg('Changing subformat of '+lHdrName);
+ dcmMsg('Changing subformat of '+lHdrName);
lOutImgName := ChangeFilePrefix (lHdrName,'f');
if lPrefs.CustomRename then
CustomFilename(lOutImgName);
@@ -512,11 +660,11 @@ begin
lHdrSz := sizeof(TniftiHdr);
lFileSz := FSize (lFilename);
if lFileSz = 0 then begin
- Msg('Unable to find NIFTI header named '+lFilename);
+ dcmMsg('Unable to find NIFTI header named '+lFilename);
exit;
end;
if lFileSz < lHdrSz then begin
- Msg('Error in reading NIFTI header: NIfTI headers need to be at least '+inttostr(lHdrSz)+ ' bytes: '+lFilename);
+ dcmMsg('Error in reading NIFTI header: NIfTI headers need to be at least '+inttostr(lHdrSz)+ ' bytes: '+lFilename);
exit;
end;
FileMode := 0; { Set file access to read only }
@@ -530,7 +678,7 @@ begin
Reset(lHdrFile, 1);
{$I+}
if ioresult <> 0 then begin
- Msg('Error in reading NIFTI header.'+inttostr(IOResult));
+ dcmMsg('Error in reading NIFTI header.'+inttostr(IOResult));
FileMode := 2;
exit;
end;
@@ -548,11 +696,11 @@ begin
lByteSwap := true;
NIFTIhdr_SwapBytes (lHdr);
end else begin
- Msg('Warning: the header file is not in NIfTi format [the first 4 bytes do not have the value 348]. Assuming big-endian data.');
+ dcmMsg('Warning: the header file is not in NIfTi format [the first 4 bytes do not have the value 348]. Assuming big-endian data.');
exit;
end;
if (lHdr.dim[0] > 7) or (lHdr.dim[0] < 1) then begin //only 1..7 dims, so this
- Msg('Illegal NIfTI Format Header: this header does not specify 1..7 dimensions.');
+ dcmMsg('Illegal NIfTI Format Header: this header does not specify 1..7 dimensions.');
exit;
end;
if lHdr.Dim[4] < 1 then
@@ -569,7 +717,7 @@ var
begin
result := false;
if ((sizeof(TNIFTIhdr ))> DiskFreeEx(lFilename)) then begin
- Msg('There is not enough free space on the destination disk to save the header. '+kCR+
+ dcmMsg('There is not enough free space on the destination disk to save the header. '+kCR+
lFileName+ kCR+' Bytes Required: '+inttostr(sizeof(TNIFTIhdr )) );
exit;
end;
@@ -849,13 +997,13 @@ end; //Not anonymized
if lDicomData.Allocbits_per_pixel <> 8 then begin
if lDicomData.Allocbits_per_pixel = 32 then begin
lBHdr.bitpix := 32;
- if lDicomData.Float then
+ if lDicomData.FloatData then
lBHdr.datatype := 16
else
lBHdr.datatype := 8;
end else if lDicomData.Allocbits_per_pixel = 64 then begin
lBHdr.bitpix := 64;
- lBHdr.datatype := 64;;
+ lBHdr.datatype := 64;
end else begin //16bits per pixel
lBHdr.bitpix := 16;
lBHdr.datatype := kDT_SIGNED_SHORT;
@@ -884,11 +1032,11 @@ begin
kDT_SIGNED_SHORT: ;
kDT_SIGNED_INT: ;
kDT_FLOAT: begin
- Msg('NII convert to 32-bit float error: datatype already 32-bit float.');
+ dcmMsg('NII convert to 32-bit float error: datatype already 32-bit float.');
exit;
end;
else begin
- Msg('NII convert to 32-bit float error: datatype not supported.');
+ dcmMsg('NII convert to 32-bit float error: datatype not supported.');
exit;
end;
end; //case
@@ -977,7 +1125,7 @@ begin
kDT_SIGNED_INT: ;
kDT_FLOAT: ;
else begin
- Msg('NII convert to 32-bit float error: datatype not supported.');
+ dcmMsg('NII convert to 32-bit float error: datatype not supported.');
exit;
end;
end; //case
@@ -1087,7 +1235,7 @@ begin
case lSrcHdr.datatype of
kDT_UNSIGNED_CHAR,kDT_SIGNED_SHORT,kDT_SIGNED_INT,kDT_FLOAT: ;
else begin
- Msg('SumTPM error: datatype not supported.');
+ dcmMsg('SumTPM error: datatype not supported.');
exit;
end;
end; //case
@@ -1162,8 +1310,8 @@ begin
if (lAHdr.Dim[4] <> lBHdr.Dim[4]) then
result := false;
if not result then begin
- fx(1211);
- msg('Image dimensions or datatype differ');
+ //fx(1211);
+ dcmMsg('Image dimensions or datatype differ');
end;
end;
@@ -1189,7 +1337,7 @@ begin
kDT_SIGNED_INT:lBPP := 4;
kDT_FLOAT: lBPP := 4;
else begin
- Msg('Merge4DFiles error: datatype not supported.');
+ dcmMsg('Merge4DFiles error: datatype not supported.');
exit;
end;
end; //case
@@ -1237,7 +1385,7 @@ begin
kDT_SIGNED_INT:lBPP := 4;
kDT_FLOAT: lBPP := 4;
else begin
- Msg('Merge4DFiles error: datatype not supported.');
+ dcmMsg('Merge4DFiles error: datatype not supported.');
exit;
end;
end; //case
@@ -1267,7 +1415,7 @@ begin
result := false;
if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap) then exit;
if lSrcHdr.datatype <> kDT_UNSIGNED_CHAR then begin
- msg('Only able to read 8-bit data.');
+ dcmMsg('Only able to read 8-bit data.');
exit;
end;
//NIFTIhdr_UnswapImg(lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap);//interpolation requires data is in native endian
@@ -1286,7 +1434,7 @@ begin
result := '';
if not NIFTIhdr_LoadHdr (lMaskName, lMaskHdr, lMaskSwap) then exit;
if lMaskHdr.datatype <> kDT_FLOAT then begin
- msg('This function only works with 32-bit float data.');
+ dcmMsg('This function only works with 32-bit float data.');
exit;
end;
lVox := lMaskHdr.Dim[1]*lMaskHdr.Dim[2]*lMaskHdr.Dim[3];
@@ -1306,7 +1454,7 @@ begin
for lInc := 1 to lFiles.Count do begin
lFilename := lFiles.Strings[lInc-1];
if not NIFTIhdr_LoadImg8bit (lFileName, lFileHdr, lFilebuffer, lFileOffset,lFileSwap) then begin
- msg('Serious error reading '+lFilename);
+ dcmMsg('Serious error reading '+lFilename);
exit;
end;
if not (SameHdrDim(lMaskHdr,lFileHdr,false,false)) then
@@ -1383,21 +1531,21 @@ begin
result := '';
lCharPos := lDigitChar (lC1Name);
if lCharPos < 1 then begin
- msg('Error: number should be in filename.');
+ dcmMsg('Error: number should be in filename.');
exit;
end;
for lMap := 1 to kMaps do begin
lHname[lMap] := lC1Name;
lHname[lMap][lCharPos] := inttostr(lMap)[1];
if not fileexists(lHname[lMap]) then begin
- msg('Can not find '+lHname[lMap]);
+ dcmMsg('Can not find '+lHname[lMap]);
exit;
end;
end;
for lMap := 1 to kMaps do begin
if not NIFTIhdr_LoadImg8bit (lHname[lMap], lH[lMap], lHBuffer[lMap], lHOffset[lMap],lHSwap) then begin
- msg('Serious error reading '+lHname[lMap]);
+ dcmMsg('Serious error reading '+lHname[lMap]);
exit;
end;
lH8i[lMap] := (@lHBuffer[lMap]^[lHOffset[lMap]+1]);
@@ -1496,7 +1644,7 @@ begin
kDT_SIGNED_INT: ;
kDT_FLOAT: ;
else begin
- Msg('NII convert to 32-bit float error: datatype not supported.');
+ dcmMsg('NII convert to 32-bit float error: datatype not supported.');
exit;
end;
end; //case
@@ -1548,27 +1696,27 @@ var
begin
result := '';
if (not fileexists(lsource)) then begin
- msg('Can not find '+ lsource);
+ dcmMsg('Can not find '+ lsource);
exit;
end;
if (not fileexists(ltemplate)) then begin
- msg('Can not find '+ ltemplate);
+ dcmMsg('Can not find '+ ltemplate);
exit;
end;
//if not NIFTIhdr_LoadImgAs32float (lsource, lH, lHBuffer, lHOffset,lHSwap) then begin
if not NIFTIhdr_LoadImg8bit (lsource, lH, lHBuffer, lHOffset,lHSwap) then begin
- msg('Serious error reading '+lsource);
+ dcmMsg('Serious error reading '+lsource);
exit;
end;
//function NIFTIhdr_LoadImgAs32float (var lSrcName: string; var lSrcHdr: TNIFTIHdr; var lSrcBuffer: bytep; var l32f: singlep; var lSrcOffset: integer; var lByteSwap: boolean): boolean;
if not As32 (ltemplate, lT, l32fs) then begin
- msg('Serious error reading '+ltemplate);
+ dcmMsg('Serious error reading '+ltemplate);
exit;
end;
lVox := lH.Dim[1]*lH.Dim[2]*lH.Dim[3];
if not SameHdrDim (lH,lT, false, false) then begin
- msg('Image dimensions do not match: '+ltemplate+' <> '+lsource);
+ dcmMsg('Image dimensions do not match: '+ltemplate+' <> '+lsource);
goto 666;
end;
l8is := (@lHBuffer^[lHOffset+1]);
@@ -1579,7 +1727,7 @@ begin
lH.scl_slope := 1;
lH.scl_inter := 0;
lOutname := ChangeFilePrefix(lsource,'m');
- msg(lsource +' masked with '+ltemplate +' = '+lOutname);
+ dcmMsg(lsource +' masked with '+ltemplate +' = '+lOutname);
result := SaveNIfTICore (loutname, lHBuffer, lHOffset+1, lH, lPrefs,lHSwap);
666:
Freemem(l32fs);
@@ -1599,7 +1747,7 @@ begin
lSPos := lDigitChar (lC1source);
lTPos := lDigitChar (lC1template);
if (lSPos < 1) or (lTPos < 1) then begin
- msg('Error: number should be in filenames: '+lC1template+' '+ lC1source);
+ dcmMsg('Error: number should be in filenames: '+lC1template+' '+ lC1source);
exit;
end;
lSname:= lC1source;
@@ -1612,7 +1760,7 @@ begin
if ( fileexists(lTName)) and ( fileexists(lSName)) then
result := MaskImg(lTName, lSName, lPrefs, lThresh) ;
end;
- msg('Masking completed');
+ dcmMsg('Masking completed');
end;
diff --git a/dcm2nii/nii_3dto4d.pas b/dcm2nii/nii_3dto4d.pas
old mode 100644
new mode 100755
index 04d76d8..0e2e59f
--- a/dcm2nii/nii_3dto4d.pas
+++ b/dcm2nii/nii_3dto4d.pas
@@ -6,7 +6,7 @@ interface
uses
{$IFDEF FPC}gzio2,{$ENDIF}
- SysUtils,define_types,dicomtypes,niftiutil,prefs,classes;
+ SysUtils,define_types,dicomtypes,niftiutil,prefs,classes,dialogs_msg;
function Stack3Dto4D(var lStr: TStringList; lOverwrite: boolean; lPrefs: TPrefs): boolean;
function ExtractNIFTIHdrs(var lStr: TStringList): boolean;
@@ -112,11 +112,11 @@ begin
for lVol := 1 to lnVol do begin
lHdrName := lStr[lVol-1];
if not NIFTIhdr_LoadHdr (lHdrName, lHdr,lByteSwap) then
- Msg('Unable to find '+lHdrName)
+ dcmMsg('Unable to find '+lHdrName)
else
- Msg(NIIstr(lHdrName,lHdr));
+ dcmMsg(NIIstr(lHdrName,lHdr));
- //Msg( inttostr(lVol)+': '+lHdrName);
+ //dcmMsg( inttostr(lVol)+': '+lHdrName);
end;
end;
@@ -135,7 +135,7 @@ begin
result := false;
lnVol := lStr.Count;
if lnVol < 2 then begin
- Msg('Stack 3D to 4D requires >1 volume');
+ dcmMsg('Stack 3D to 4D requires >1 volume');
exit;
end;
SortStrPadded(lStr);
@@ -144,19 +144,19 @@ begin
for lVol := 1 to lnVol do begin
lHdrName := lStr[lVol-1];
if not NIFTIhdr_LoadHdr (lHdrName, lHdr2,lByteSwap) then begin
- Msg('Stack 3D to 4D unable to find '+lHdrName);
+ dcmMsg('Stack 3D to 4D unable to find '+lHdrName);
exit;
end;
if (lHdr1.dim[4] > 1) then begin
- Msg('Stack 3D to 4D aborted, image is already 4D: '+lHdrName );
+ dcmMsg('Stack 3D to 4D aborted, image is already 4D: '+lHdrName );
exit;
end;
if (lHdr1.dim[1] <> lHdr2.dim[1]) or (lHdr1.dim[2] <> lHdr2.dim[2]) or
(lHdr1.dim[3] <> lHdr2.dim[3]) or (lHdr1.datatype <> lHdr2.datatype) then begin
- Msg('Stack 3D to 4D aborted, image dimensions/datatype vary '+lHdrName + ' <> '+lStr[0]);
+ dcmMsg('Stack 3D to 4D aborted, image dimensions/datatype vary '+lHdrName + ' <> '+lStr[0]);
exit;
end;
- //Msg( inttostr(lVol)+': '+lHdrName);
+ //dcmMsg( inttostr(lVol)+': '+lHdrName);
end;
lOutHdr := lHdr1;
lOutHdr.dim[4] := lnVol;
@@ -164,14 +164,14 @@ begin
l4DVolBytes := l3DVolBytes * lnVol;
GetMem(lOutBuffer,l4DVolBytes+kNIIImgOffset);
- Msg('Order in output file:');
+ dcmMsg('Order in output file:');
lOutImgName := ChangeFilePrefix (lStr[0],'4D');
lOutPos := kNIIImgOffset + 1;
for lVol := 1 to lnVol do begin
lHdrName := lStr[lVol-1];
- Msg( inttostr(lVol)+': '+lHdrName);
+ dcmMsg( inttostr(lVol)+': '+lHdrName);
if not NIFTIhdr_LoadImg (lHdrName, lHdr2, lIBuffer, lInOffset,lByteSwap) then begin
- Msg('3D -> 4D error loading image '+lHdrName);
+ dcmMsg('3D -> 4D error loading image '+lHdrName);
goto 123;
end;
Move(lIBuffer^[lInOffset+1],lOutBuffer^[lOutPos],l3DVolBytes);
@@ -180,9 +180,9 @@ begin
end;
lPrefs4D := lPrefs;
lPrefs4D.fourD := true;
- Msg('4D image '+lOutImgName);
+ dcmMsg('4D image '+lOutImgName);
if SaveNIfTICore (lOutImgName, lOutBuffer, kNIIImgOffset+1, lOutHdr, lPrefs4D,lByteSwap) = '' then begin
- Msg('3D -> 4D Error');
+ dcmMsg('3D -> 4D Error');
goto 123;
end;
@@ -226,14 +226,14 @@ begin
lInName := lHdrName;
end;
if not fileexists(lInName) then begin
- Msg('4Dclip Error: Unable to find '+lInName);
+ dcmMsg('4Dclip Error: Unable to find '+lInName);
exit;
end;
if FSize (lInName) < ( (lInVolBytes*lHdr.dim[4])+round(lHdr.vox_offset)) then begin
- Msg('4Dclip Error: File smaller than expected (can not convert compressed) '+lInName);
+ dcmMsg('4Dclip Error: File smaller than expected (can not convert compressed) '+lInName);
exit;
end;
- Msg('Reordering image');
+ dcmMsg('Reordering image');
if not lSingleNiiFile then begin
lHdrName := changefileext(lHdrName,'.hdr');
lImgName := changefileext(lHdrName,'.img');
@@ -248,7 +248,7 @@ begin
end else begin
lHdrName := ChangeFilePrefixExt (lHdrName,'x');
lImgName := ChangeFilePrefixExt (lImgName,'x');
- Msg('saving as '+lHdrName);
+ dcmMsg('saving as '+lHdrName);
end;
AssignFile(lInF, lInName);
Reset(lInF,1);
@@ -316,17 +316,17 @@ begin
lInName := lHdrName;
end;
if not fileexists(lInName) then begin
- Msg('4Dclip Error: Unable to find '+lInName);
+ dcmMsg('4Dclip Error: Unable to find '+lInName);
exit;
end;
if FSize (lInName) < ( (lVolBytes*lHdr.dim[4])+round(lHdr.vox_offset)) then begin
- Msg('4Dclip Error: File smaller than expected (can not convert compressed) '+lInName);
+ dcmMsg('4Dclip Error: File smaller than expected (can not convert compressed) '+lInName);
exit;
end;
if (lStart > 0) or (lEnd > 0) then
- Msg('4D clip - removing first '+inttostr(lStart)+' and last '+inttostr(lEnd) +' volumes')
+ dcmMsg('4D clip - removing first '+inttostr(lStart)+' and last '+inttostr(lEnd) +' volumes')
else
- Msg('Formatting image');
+ dcmMsg('Formatting image');
if not lSingleNiiFile then begin
lGZi := false;
lHdrName := changefileext(lHdrName,'.hdr');
@@ -341,7 +341,7 @@ begin
end else begin
lHdrName := ChangeFilePrefixExt (lHdrName,'x');
lImgName := ChangeFilePrefixExt (lImgName,'x');
- Msg('Saving clipped as '+lHdrName);
+ dcmMsg('Saving clipped as '+lHdrName);
end;
AssignFile(lInF, lInName);
Reset(lInF,1);
@@ -402,14 +402,14 @@ begin
end else
lImgName := lHdrName;
if not fileexists(lImgName) then begin
- Msg('4D->3D Error: Unable to find '+lImgName);
+ dcmMsg('4D->3D Error: Unable to find '+lImgName);
exit;
end;
if FSize (lImgName) < ( (lVolBytes*lHdr.dim[4])+round(lHdr.vox_offset)) then begin
- Msg('4D->3D Error: File smaller than expected (can not convert compressed) '+lImgName);
+ dcmMsg('4D->3D Error: File smaller than expected (can not convert compressed) '+lImgName);
exit;
end;
- //Msg(inttostr(round(lHdr.vox_offset)));
+ //dcmMsg(inttostr(round(lHdr.vox_offset)));
AssignFile(lInF, lImgName);
Reset(lInF,1);
Seek(lInF,round(lHdr.vox_offset));
@@ -453,4 +453,4 @@ begin
end; *)
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/nii_4dto3d.pas b/dcm2nii/nii_4dto3d.pas
old mode 100644
new mode 100755
index 766aebc..dda2b03
--- a/dcm2nii/nii_4dto3d.pas
+++ b/dcm2nii/nii_4dto3d.pas
@@ -16,7 +16,7 @@ function Clip4D(var lHdrName: string; var lHdr: TNIFTIhdr;lOverwrite: boolean; l
function Reorder4D(var lHdrName: string; var lHdr: TNIFTIhdr; lOverwrite: boolean; lPrefs: TPrefs): boolean;
implementation
-uses dialogsx;
+uses dialogsx,dialogs_msg;
@@ -25,7 +25,7 @@ function ModifyAnalyze(lFilename: string; lPrefs: TPrefs): boolean;
var
lExt,lOutname: string;
lHdr: TNIFTIhdr;
- lFormat,lStartIn,lEndIn: integer;
+ lFormat,lStartIn,lEndIn, lMinStartIn: integer;
lByteSwap,lReorder: boolean;
lPref: TPrefs;
begin
@@ -36,24 +36,33 @@ begin
lReorder := false;
lExt := UpCaseExt(lFilename);
if not NIFTIhdr_LoadHdr (lFilename, lHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
-
-
if lPrefs.AutoCrop then begin
- Msg('Autocrop NIfTI/Analyze image '+lFileName);
+ dcmMsg('Autocrop NIfTI/Analyze image '+lFileName);
lOutname := Reorient(lFilename,lHdr, lPrefs,false,false);
if lOutname <> '' then
CropNIfTI(lOutname,lPrefs);
exit;
end;
- Msg('Adjusting NIfTI/Analyze image '+lFileName);
-
+ dcmMsg('Adjusting NIfTI/Analyze image '+lFileName);
+ if (lHdr.dim[4] > 1) then begin //if 4D input
+ if (lPrefs.BeginClip > 0) and (lPrefs.BeginClip < lHdr.dim[4]) then begin
+ lStartIn := lPrefs.BeginClip;
+ dcmMsg('Warning: removing first '+inttostr(lStartIn) + ' volumes (preference: BeginClip)');
+ end;
+ if (lStartIn <> lPrefs.BeginClip) then
+ dcmMsg('Warning preference BeginClip is being ignored (not enough volumes)');
+ if (lPrefs.LastClip > 0) and ( (lPrefs.LastClip+ lPrefs.BeginClip) < lHdr.dim[4]) then begin
+ lEndIn := lPrefs.LastClip;
+ dcmMsg('Warning: removing final '+inttostr(lEndIn) + ' volumes (preference: LastClip)');
+ end;
+ if (lEndIn <> lPrefs.LastClip) then
+ dcmMsg('Warning preference LastClip is being ignored (not enough volumes)');
+ end;//if 4D input
//next - determine output format
if not lPref.ManualNiFtiConv then begin
- lStartIn := 0;
- lEndIn := 0;
lReorder := false;
end else begin //manually specify conversion parameters
lFormat := GetInt('Output: 0=spm2,1=spm5,2=spm8,3=hdr4D,4=fsl,5=fsl.gz ', 0,DefaultOutputFormat (lPrefs),5);
@@ -79,19 +88,19 @@ begin
//next - 4D images: clip ends or flip order
if lHdr.dim[4] > 1 then begin //4D file
if (lHdr.dim[4] > 1) and (lHdr.dim[3] > 1) then begin
- Msg(' Enter a value of -1 to flip 3rd and 4th dimensions.');
- lStartIn := -1;
+ dcmMsg(' Enter a value of -1 to flip 3rd and 4th dimensions.');
+ lMinStartIn := -1;
end else
- lStartIn := 0;
- lStartIn := GetInt('Enter volumes to remove from start ', lStartIn,0,lHdr.dim[4]);
+ lMinStartIn := 0;
+ lStartIn := GetInt('Enter volumes to remove from start ', lMinStartIn,lStartIn,lHdr.dim[4]);
if lStartIn >= 0 then
- lEndIn := GetInt('Enter volumes to remove from end ' ,0,0,lHdr.dim[4]);
+ lEndIn := GetInt('Enter volumes to remove from end ' ,0,lEndIn,lHdr.dim[4]);
if ((lStartIn < 0) or (lEndIn < 0)) and (lHdr.dim[4] > 1) and (lHdr.dim[3] > 1) then
lReorder := true
else
lReorder := false;
if lHdr.dim[4] <= (lStartIn+lEndIn) then begin
- Msg('Clip Analyze aborted: unable to remove this many volumes.');
+ dcmMsg('Clip Analyze aborted: unable to remove this many volumes.');
exit;
end;
end;(* else begin //not 4D file
@@ -108,7 +117,7 @@ begin
ExtractFileParts (lFileName, lNameWOExt,lExt);
lTempName := lNameWOExt+'.nii';
Gunzip(lFileName,lTempName);
- //Msg('Unzip '+lFilename+'->'+lTempName);
+ //dcmMsg('Unzip '+lFilename+'->'+lTempName);
lFilename := lTempName;
end else //not gzip
lTempName := ''; *)
@@ -119,7 +128,7 @@ begin
//if not Reorder4D(lFileName, lHdr, lByteSwap,lSPM2,lSingleFile,lGZ, false) then exit;
end else if (lStartIn=0) and (lEndIn= 0) then begin
if not ChangeNIfTISubformat(lFileName, lHdr,lPref) then begin
- Msg('Error changing format!');
+ dcmMsg('Error changing format!');
exit;
end;
end else begin
@@ -138,7 +147,7 @@ var
begin
result := '';
if not NIFTIhdr_LoadImg (lHdrName, lHdr, lImgBuffer, lImgOffset,lByteSwap) then exit;
- Msg('4D Clipping '+lHdrName);
+ dcmMsg('4D Clipping '+lHdrName);
lOutImgName := ChangeFilePrefix (lHdrName,'f');
result := SaveNIfTICoreCrop (lOutImgName, lImgBuffer, lImgOffset+1,lStartIn,lEndIn, lHdr, lPrefs,lByteSwap);
Freemem(lImgBuffer);
@@ -167,7 +176,7 @@ begin
lSliceBytes := lHdr.dim[1]*lHdr.dim[2]*(lHdr.bitpix div 8);
lIn3DBytes := lSliceBytes*lHdr.dim[3];
l4DBytes := lIn3DBytes*lHdr.dim[4];
- Msg('Changing order of dimensions 3 and 4 of '+lHdrName);
+ dcmMsg('Changing order of dimensions 3 and 4 of '+lHdrName);
GetMem(lOutBuffer,l4DBytes+kNIIImgOffset);
lOutPos := kNIIImgOffset + 1;
for lVol := 1 to lOutHdr.dim[4] do begin
@@ -178,9 +187,9 @@ begin
lOutPos := lOutPos + lSliceBytes;
end;//for lslice
end; //for lvol
- Msg(lOutImgName);
+ dcmMsg(lOutImgName);
if SaveNIfTICore (lOutImgName, lOutBuffer, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap) = '' then begin
- Msg('Reorder Error');
+ dcmMsg('Reorder Error');
Freemem(lInBuffer);
Freemem(lOutBuffer);
exit;
@@ -219,14 +228,14 @@ begin
lInName := lHdrName;
end;
if not fileexists(lInName) then begin
- Msg('4Dclip Error: Unable to find '+lInName);
+ dcmMsg('4Dclip Error: Unable to find '+lInName);
exit;
end;
if FSize (lInName) < ( (lInVolBytes*lHdr.dim[4])+round(lHdr.vox_offset)) then begin
- Msg('4Dclip Error: File smaller than expected (can not convert compressed) '+lInName);
+ dcmMsg('4Dclip Error: File smaller than expected (can not convert compressed) '+lInName);
exit;
end;
- Msg('Reordering image');
+ dcmMsg('Reordering image');
if not lSingleNiiFile then begin
lHdrName := changefileext(lHdrName,'.hdr');
lImgName := changefileext(lHdrName,'.img');
@@ -241,7 +250,7 @@ begin
end else begin
lHdrName := ChangeFilePrefixExt (lHdrName,'x');
lImgName := ChangeFilePrefixExt (lImgName,'x');
- Msg('saving as '+lHdrName);
+ dcmMsg('saving as '+lHdrName);
end;
AssignFile(lInF, lInName);
Reset(lInF,1);
@@ -309,17 +318,17 @@ begin
lInName := lHdrName;
end;
if not fileexists(lInName) then begin
- Msg('4Dclip Error: Unable to find '+lInName);
+ dcmMsg('4Dclip Error: Unable to find '+lInName);
exit;
end;
if FSize (lInName) < ( (lVolBytes*lHdr.dim[4])+round(lHdr.vox_offset)) then begin
- Msg('4Dclip Error: File smaller than expected (can not convert compressed) '+lInName);
+ dcmMsg('4Dclip Error: File smaller than expected (can not convert compressed) '+lInName);
exit;
end;
if (lStart > 0) or (lEnd > 0) then
- Msg('4D clip - removing first '+inttostr(lStart)+' and last '+inttostr(lEnd) +' volumes')
+ dcmMsg('4D clip - removing first '+inttostr(lStart)+' and last '+inttostr(lEnd) +' volumes')
else
- Msg('Formatting image');
+ dcmMsg('Formatting image');
if not lSingleNiiFile then begin
lGZi := false;
lHdrName := changefileext(lHdrName,'.hdr');
@@ -334,7 +343,7 @@ begin
end else begin
lHdrName := ChangeFilePrefixExt (lHdrName,'x');
lImgName := ChangeFilePrefixExt (lImgName,'x');
- Msg('Saving clipped as '+lHdrName);
+ dcmMsg('Saving clipped as '+lHdrName);
end;
AssignFile(lInF, lInName);
Reset(lInF,1);
@@ -395,14 +404,14 @@ begin
end else
lImgName := lHdrName;
if not fileexists(lImgName) then begin
- Msg('4D->3D Error: Unable to find '+lImgName);
+ dcmMsg('4D->3D Error: Unable to find '+lImgName);
exit;
end;
if FSize (lImgName) < ( (lVolBytes*lHdr.dim[4])+round(lHdr.vox_offset)) then begin
- Msg('4D->3D Error: File smaller than expected (can not convert compressed) '+lImgName);
+ dcmMsg('4D->3D Error: File smaller than expected (can not convert compressed) '+lImgName);
exit;
end;
- //Msg(inttostr(round(lHdr.vox_offset)));
+ //dcmMsg(inttostr(round(lHdr.vox_offset)));
AssignFile(lInF, lImgName);
Reset(lInF,1);
Seek(lInF,round(lHdr.vox_offset));
@@ -446,4 +455,4 @@ begin
end; *)
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/nii_asl.pas b/dcm2nii/nii_asl.pas
old mode 100644
new mode 100755
index a2595d8..66113ec
--- a/dcm2nii/nii_asl.pas
+++ b/dcm2nii/nii_asl.pas
@@ -6,14 +6,14 @@ unit nii_asl;
interface
uses
-{$IFDEF FPC}gzio2,{$ENDIF}
- SysUtils,define_types,dicomtypes,niftiutil,prefs;
+//{$IFDEF FPC}gzio2,{$ENDIF}
+ SysUtils,define_types,dicomtypes,niftiutil,prefs,dialogs_msg;
function ASL_subtract(var lHdrName: string; lOverwrite: boolean; lFunction : integer; lPrefs: TPrefs): boolean;
//ASL_subtract(var lHdrName: string; lOverwrite: boolean; lFunction : integer; lPrefs: TPrefs)
implementation
-uses dialogsx,gui,dialogs;
+uses gui,dialogs;
function Parse (var lNumStr: string; var Val1,Val2: integer): boolean;
var
@@ -36,7 +36,7 @@ begin
try
Val1 := strtoint(lS);
except
- Msg('Error converting text to number '+lS);
+ dcmMsg('Error converting text to number '+lS);
end;
//next number
inc(lP);
@@ -50,7 +50,7 @@ begin
try
Val2 := strtoint(lS);
except
- Msg('Error converting text to number '+lS);
+ dcmMsg('Error converting text to number '+lS);
end;
result := true;
end;
@@ -75,7 +75,7 @@ begin
inc(R);
end;
if (R < 1) then begin
- msg('problems reading CSV: must have at least 2 columns and 1 row.');
+ dcmMsg('problems reading CSV: must have at least 2 columns and 1 row.');
exit;
end;
lnObservations := R;
@@ -159,18 +159,18 @@ begin
lSubtract := (lFunction <> 3);
result := false;
if not NIFTIhdr_LoadHdr (lHdrName, lInHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lHdrName);
+ dcmMsg('Unable to read as NifTI/Analyze' + lHdrName);
exit;
end;
case lInHdr.datatype of
{kDT_UNSIGNED_CHAR,kDT_SIGNED_SHORT,kDT_UINT16, kDT_SIGNED_INT,}kDT_FLOAT:;//Supported
else begin
- Msg('Error with ASL_subtract: image format must be 32-bit floating point values.');
+ dcmMsg('Error with ASL_subtract: image format must be 32-bit floating point values.');
exit;
end;
end;//case headertype
if (odd(lInHdr.dim[4])) or (lInHdr.dim[4] < 2) then begin
- Msg('ASL routines require an even number of volumes');
+ dcmMsg('ASL routines require an even number of volumes');
exit;
end;
@@ -208,7 +208,7 @@ begin
lResultStr := 'Subtract Even-Odd';
end else
lResultStr := 'Add Odd+Even';
- Msg('Computing '+lResultStr+' '+lHdrName);
+ dcmMsg('Computing '+lResultStr+' '+lHdrName);
lResultStr := ''; //assume error
GetMem(lBuffUnaligned ,(sizeof(single)*l4DVox) + 16+kNIIImgOffset);
{$IFDEF FPC}
@@ -249,15 +249,15 @@ begin
end; //for lImgSamples
end; //for lvol
end else if lCustom then begin //not lSplitOddEven .. if Custom
- Msg('Select a comma separated text file that describes how to subtract images.');
- Msg('For example, to subtract a six volume dataset your file could be:');
- Msg('1,6');
- Msg('2,5');
- Msg('3,4');
- Msg('The first output volume would be the first input volume minus the sixth');
- Msg('The second output volume would be the second input volume minus the fifth');
- Msg('The final output volume would be the third input volume minus the fourth');
- Msg('Your file should have '+inttostr(lOutHdr.dim[4])+' lines, one for each output volume');
+ dcmMsg('Select a comma separated text file that describes how to subtract images.');
+ dcmMsg('For example, to subtract a six volume dataset your file could be:');
+ dcmMsg('1,6');
+ dcmMsg('2,5');
+ dcmMsg('3,4');
+ dcmMsg('The first output volume would be the first input volume minus the sixth');
+ dcmMsg('The second output volume would be the second input volume minus the fifth');
+ dcmMsg('The final output volume would be the third input volume minus the fourth');
+ dcmMsg('Your file should have '+inttostr(lOutHdr.dim[4])+' lines, one for each output volume');
if not MainForm.OpenDialogExecute('Select NIfTI images you wish to modify)',true,false,kTxtFilter) then
goto 666;
@@ -266,7 +266,7 @@ end else if lCustom then begin //not lSplitOddEven .. if Custom
if not readCSV (lCSVname, lVol, lPosRA,lNegRA) then
goto 666;
if lVol < lOutHdr.dim[4] then begin
- Msg ('Only found '+inttostr(lVol)+' contrasts in '+ lCSVName+' a total of '+inttostr(lOutHdr.dim[4])+' required');
+ dcmMsg ('Only found '+inttostr(lVol)+' contrasts in '+ lCSVName+' a total of '+inttostr(lOutHdr.dim[4])+' required');
freemem(lPosRA);
freemem(lNegRA);
goto 666;
@@ -276,7 +276,7 @@ end else if lCustom then begin //not lSplitOddEven .. if Custom
lEvenVol := lNegRA^[lVol];
lOddVol := lPosRA^[lVol];
if (lEvenVol > 0) and (lOddVol > 0) and (lEvenVol <= lInHdr.dim[4]) and (lOddVol <= lInHdr.dim[4]) then begin
- Msg (inttostr(lVol) +' = '+inttostr(lOddVol)+' - '+inttostr(lEvenVol) );
+ dcmMsg (inttostr(lVol) +' = '+inttostr(lOddVol)+' - '+inttostr(lEvenVol) );
lInVolEvenOffset := (lEvenVol -1) * lImgSamples;
lInVolOddOffset := (lOddVol -1) * lImgSamples;
for lInc := 1 to lImgSamples do begin
@@ -285,7 +285,7 @@ end else if lCustom then begin //not lSplitOddEven .. if Custom
lImgBuffer^[lOutVolOffset+lInc] := lOdd - lEven;
end; //each voxel in volume
end else begin
- Msg ('Error: volumes out of range '+inttostr(lVol) +' = '+inttostr(lOddVol)+' - '+inttostr(lEvenVol) );
+ dcmMsg('Error: volumes out of range '+inttostr(lVol) +' = '+inttostr(lOddVol)+' - '+inttostr(lEvenVol) );
end;
end; //for lvol
freemem(lPosRA);
@@ -429,7 +429,7 @@ begin
lSubtract := (lFunction <> 3);
result := false;
if not NIFTIhdr_LoadHdr (lHdrName, lInHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lHdrName);
+ dcmMsg('Unable to read as NifTI/Analyze' + lHdrName);
exit;
end;
case lInHdr.datatype of
@@ -439,12 +439,12 @@ begin
exit;
end;//kDT_FLOAT
else begin
- Msg('Error with ASL_subtract: image format must be 16-bit signed integers.');
+ dcmMsg('Error with ASL_subtract: image format must be 16-bit signed integers.');
exit;
end;
end;//case headertype
if (odd(lInHdr.dim[4])) or (lInHdr.dim[4] < 2) then begin
- Msg('ASL routines require an even number of volumes');
+ dcmMsg('ASL routines require an even number of volumes');
exit;
end;
@@ -482,7 +482,7 @@ begin
lResultStr := 'Subtract Even-Odd';
end else
lResultStr := 'Add Odd+Even';
- Msg('Computing '+lResultStr+' '+lHdrName);
+ dcmMsg('Computing '+lResultStr+' '+lHdrName);
lResultStr := ''; //assume error
GetMem(lBuffUnaligned ,(sizeof(smallint)*l4DVox) + 16+kNIIImgOffset);
{$IFDEF FPC}
@@ -522,15 +522,15 @@ if lSplitOddEven then begin
end; //for lImgSamples
end; //for lvol
end else if lCustom then begin //not lSplitOddEven .. if Custom
- Msg('Select a comma separated text file that describes how to subtract images.');
- Msg('For example, to subtract a six volume dataset your file could be:');
- Msg('1,6');
- Msg('2,5');
- Msg('3,4');
- Msg('The first output volume would be the first input volume minus the sixth');
- Msg('The second output volume would be the second input volume minus the fifth');
- Msg('The final output volume would be the third input volume minus the fourth');
- Msg('Your file should have '+inttostr(lOutHdr.dim[4])+' lines, one for each output volume');
+ dcmMsg('Select a comma separated text file that describes how to subtract images.');
+ dcmMsg('For example, to subtract a six volume dataset your file could be:');
+ dcmMsg('1,6');
+ dcmMsg('2,5');
+ dcmMsg('3,4');
+ dcmMsg('The first output volume would be the first input volume minus the sixth');
+ dcmMsg('The second output volume would be the second input volume minus the fifth');
+ dcmMsg('The final output volume would be the third input volume minus the fourth');
+ dcmMsg('Your file should have '+inttostr(lOutHdr.dim[4])+' lines, one for each output volume');
if not MainForm.OpenDialogExecute('Select NIfTI images you wish to modify)',true,false,kTxtFilter) then
goto 666;
@@ -539,7 +539,7 @@ end else if lCustom then begin //not lSplitOddEven .. if Custom
if not readCSV (lCSVname, lVol, lPosRA,lNegRA) then
goto 666;
if lVol < lOutHdr.dim[4] then begin
- Msg ('Only found '+inttostr(lVol)+' contrasts in '+ lCSVName+' a total of '+inttostr(lOutHdr.dim[4])+' required');
+ dcmMsg('Only found '+inttostr(lVol)+' contrasts in '+ lCSVName+' a total of '+inttostr(lOutHdr.dim[4])+' required');
freemem(lPosRA);
freemem(lNegRA);
goto 666;
@@ -549,7 +549,7 @@ end else if lCustom then begin //not lSplitOddEven .. if Custom
lEvenVol := lNegRA^[lVol];
lOddVol := lPosRA^[lVol];
if (lEvenVol > 0) and (lOddVol > 0) and (lEvenVol <= lInHdr.dim[4]) and (lOddVol <= lInHdr.dim[4]) then begin
- Msg (inttostr(lVol) +' = '+inttostr(lOddVol)+' - '+inttostr(lEvenVol) );
+ dcmMsg(inttostr(lVol) +' = '+inttostr(lOddVol)+' - '+inttostr(lEvenVol) );
lInVolEvenOffset := (lEvenVol -1) * lImgSamples; //second, fourth
lInVolOddOffset := (lOddVol -1) * lImgSamples; //first, thired
for lInc := 1 to lImgSamples do begin
@@ -558,7 +558,7 @@ end else if lCustom then begin //not lSplitOddEven .. if Custom
lImgBuffer^[lOutVolOffset+lInc] := lOdd - lEven;
end; //each voxel in volume
end else begin
- Msg ('Error: volumes out of range '+inttostr(lVol) +' = '+inttostr(lOddVol)+' - '+inttostr(lEvenVol) );
+ dcmMsg('Error: volumes out of range '+inttostr(lVol) +' = '+inttostr(lOddVol)+' - '+inttostr(lEvenVol) );
end;
end; //for lvol
freemem(lPosRA);
@@ -602,4 +602,4 @@ end;
result := true;
end; //ASL_subtract
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/nii_crop.pas b/dcm2nii/nii_crop.pas
old mode 100644
new mode 100755
index 78b5d2f..a493647
--- a/dcm2nii/nii_crop.pas
+++ b/dcm2nii/nii_crop.pas
@@ -23,7 +23,7 @@ function CropNIfTIX(lFilename: string; lPrefs: TPrefs; lDorsalCrop, lVentralCrop
function SiemensPhase2RadiansNIfTI(lFilename: string; lPrefs: TPrefs): string;
implementation
-uses dialogsx,math;
+uses dialogsx,math,dialogs_msg;
function RemoveNIfTIscalefactor(lFilename: string; lPrefs: TPrefs): string;
//rescale data by lScale
@@ -37,17 +37,17 @@ begin
result := '';
//lExt := UpCaseExt(lFilename);
if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
case lInHdr.datatype of
kDT_UNSIGNED_CHAR,kDT_SIGNED_SHORT,kDT_UINT16, kDT_SIGNED_INT,kDT_FLOAT:;//Supported
else begin
- Msg('rescaleNIfTI unsupported datatype.');
+ dcmMsg('rescaleNIfTI unsupported datatype.');
exit;
end;
end;
- Msg('removing scale factor NIfTI/Analyze image '+lFileName);
+ dcmMsg('removing scale factor NIfTI/Analyze image '+lFileName);
lOutHdr := lInHdr;
lOutHdr.scl_slope := 1;
lOutHdr.scl_inter := 0;
@@ -58,9 +58,9 @@ begin
l1 := 1;
Move(lInBuffer^[lInOffset+l1],lOutBuffer^[kNIIImgOffset + l1],l4DBytes);
lOutname := ChangeFilePrefix (lFileName,'r');
- Msg(lOutName);
+ dcmMsg(lOutName);
if SaveNIfTICore (lOutName, lOutBuffer, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap) = '' then begin
- Msg('Remove scale error');
+ dcmMsg('Remove scale error');
Freemem(lInBuffer);
Freemem(lOutBuffer);
exit;
@@ -85,17 +85,17 @@ begin
result := '';
lExt := UpCaseExt(lFilename);
if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
case lInHdr.datatype of
kDT_UNSIGNED_CHAR,kDT_SIGNED_SHORT,kDT_UINT16, kDT_SIGNED_INT,kDT_FLOAT:;//Supported
else begin
- Msg('Error with nii_crop: unsupported datatype.');
+ dcmMsg('Error with nii_crop: unsupported datatype.');
exit;
end;
end;
- Msg('Applying formula to NIfTI/Analyze image'+lFileName);
+ dcmMsg('Applying formula to NIfTI/Analyze image'+lFileName);
lOutHdr := lInHdr;
lOutHdr.datatype := kDT_FLOAT;
lOutHdr.bitpix := 32;
@@ -147,7 +147,7 @@ begin
//invert= for lInc := 1 to lImgSamples do l32Buf[lInc] := -l32Buf[lInc];
end; //32-bit float
else begin
- Msg('Serious error: format not supported by Float32.');
+ dcmMsg('Serious error: format not supported by Float32.');
exit;
end;
end; //case
@@ -185,21 +185,21 @@ begin
result := '';
lExt := UpCaseExt(lFilename);
if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
if lInHdr.datatype = kDT_FLOAT then begin
- Msg('No need to apply Float32 : data is already 32-bit real: '+lFilename);
+ dcmMsg('No need to apply Float32 : data is already 32-bit real: '+lFilename);
exit;
end;
case lInHdr.datatype of
kDT_UNSIGNED_CHAR,kDT_SIGNED_SHORT,kDT_UINT16, kDT_SIGNED_INT,kDT_FLOAT:;//Supported
else begin
- Msg('Float32 unsupported datatype.');
+ dcmMsg('Float32 unsupported datatype.');
exit;
end;
end;
- Msg('Converting NIfTI/Analyze image to 32-bit float'+lFileName);
+ dcmMsg('Converting NIfTI/Analyze image to 32-bit float'+lFileName);
lOutHdr := lInHdr;
lOutHdr.datatype := kDT_FLOAT;
lOutHdr.bitpix := 32;
@@ -251,7 +251,7 @@ begin
//invert= for lInc := 1 to lImgSamples do l32Buf[lInc] := -l32Buf[lInc];
end; //32-bit float
else begin
- Msg('Serious error: format not supported by Float32.');
+ dcmMsg('Serious error: format not supported by Float32.');
exit;
end;
end; //case
@@ -647,42 +647,42 @@ begin
if (lDorsalCrop = 0) and (lVentralCrop = 0)
and (lLCrop = 0) and (lRCrop = 0)
and (lACrop = 0) and (lPCrop = 0) then begin
- Msg('Crop slices quitting: no need to delete slices.');
+ dcmMsg('Crop slices quitting: no need to delete slices.');
exit; //25 Sept 2008
end;
if (lDorsalCrop < 0) or (lVentralCrop < 0)
or (lLCrop < 0) or (lRCrop < 0)
or (lACrop < 0) or (lPCrop < 0) then begin
- Msg('Crop slices quitting: negative values should be impossible.');
+ dcmMsg('Crop slices quitting: negative values should be impossible.');
exit;
end;
result := '';
lExt := UpCaseExt(lFilename);
if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
//Next create reordered or trimmed image in the correct format
case lInHdr.datatype of
kDT_UNSIGNED_CHAR,kDT_SIGNED_SHORT,kDT_UINT16, kDT_SIGNED_INT,kDT_FLOAT:;//Supported
else begin
- Msg('Crop 3D unsupported datatype.');
+ dcmMsg('Crop 3D unsupported datatype.');
exit;
end;
end;
- Msg('Cropping NIfTI/Analyze image '+lFileName);
+ dcmMsg('Cropping NIfTI/Analyze image '+lFileName);
lOutHdr := lInHdr;
//lImgSamples := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3];
lBPP := (lInHdr.bitpix div 8); //bytes per pixel
if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lByteSwap) then exit;
- //Msg('Automatically Cropping image');
+ //dcmMsg('Automatically Cropping image');
lBuffer := (@lSrcBuffer^[lImgOffset+1]);
//next compute size of cropped volume
lOutHdr.Dim[1] := lInHdr.Dim[1]-lLCrop-lRCrop;
lOutHdr.Dim[2] := lInHdr.Dim[2]-lACrop-lPCrop;
lOutHdr.Dim[3] := lInHdr.Dim[3]-lDorsalCrop-lVentralCrop;
if (lOutHdr.Dim[1] < 1) or (lOutHdr.Dim[2] <12) or (lOutHdr.Dim[3] < 1) then begin
- Msg('Requested to crop more slices than available.');
+ dcmMsg('Requested to crop more slices than available.');
Freemem(lSrcBuffer);
exit;
end;
@@ -750,34 +750,34 @@ begin
result := '';
lExt := UpCaseExt(lFilename);
if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
if (lInHdr.dim[1] > lPrefs.MaxReorientMatrix) or (lInHdr.dim[2] > lPrefs.MaxReorientMatrix) or(lInHdr.dim[3] > lPrefs.MaxReorientMatrix) then begin
- Msg('This image will not be cropped (larger than MaxReorientMatrix= '+inttostr(lPrefs.MaxReorientMatrix));
+ dcmMsg('This image will not be cropped (larger than MaxReorientMatrix= '+inttostr(lPrefs.MaxReorientMatrix));
exit;
end;
//check orthogonal alignment....
if lInHdr.dim[4] > 1 then begin
- Msg('Only able to Crop 3D images (reorienting 4D could disrupt slice timing and diffusion directions.');
+ dcmMsg('Only able to Crop 3D images (reorienting 4D could disrupt slice timing and diffusion directions.');
exit;
end;
//Next create reordered or trimmed image in the correct format
case lInHdr.datatype of
kDT_UNSIGNED_CHAR,kDT_SIGNED_SHORT,kDT_UINT16, kDT_SIGNED_INT,kDT_FLOAT:;//Supported
else begin
- Msg('Crop 3D unsupported datatype.');
+ dcmMsg('Crop 3D unsupported datatype.');
exit;
end;
end;
- Msg('Cropping NIfTI/Analyze image '+lFileName);
+ dcmMsg('Cropping NIfTI/Analyze image '+lFileName);
lOutHdr := lInHdr;
lImgSamples := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3];
lBPP := (lInHdr.bitpix div 8); //bytes per pixel
//lVolBytes := lImgSamples*lBPP;
if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lByteSwap) then exit;
- //Msg('Automatically Cropping image');
+ //dcmMsg('Automatically Cropping image');
lBuffer := (@lSrcBuffer^[lImgOffset+1]);
GetMem(lBuffUnaligned ,(sizeof(single)*lImgSamples) + 16);
{$IFDEF FPC}
@@ -822,7 +822,7 @@ begin
//invert= for lInc := 1 to lImgSamples do l32Buf[lInc] := -l32Buf[lInc];
end; //32-bit float
else begin
- Msg('Serious error: format not supported by Crop3D.');
+ dcmMsg('Serious error: format not supported by Crop3D.');
exit;
end;
end; //case
@@ -834,14 +834,14 @@ begin
if (lDorsalCrop = 0) and (lVentralCrop = 0)
and (lLCrop = 0) and (lRCrop = 0)
and (lACrop = 0) and (lPCrop = 0) then begin
- Msg('Crop 3D quitting: no need to delete slices.');
+ dcmMsg('Crop 3D quitting: no need to delete slices.');
Freemem(lSrcBuffer);
exit; //25 Sept 2008
end;
if (lDorsalCrop < 0) or (lVentralCrop < 0)
or (lLCrop < 0) or (lRCrop < 0)
or (lACrop < 0) or (lPCrop < 0) then begin
- Msg('Crop 3D quitting: negative values should be impossible.');
+ dcmMsg('Crop 3D quitting: negative values should be impossible.');
beep;
Freemem(lSrcBuffer);
end;
@@ -901,12 +901,12 @@ begin
result := '';
lExt := UpCaseExt(lFilename);
if not NIFTIhdr_LoadHdr (lFilename, lHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
//check orthogonal alignment....
if lHdr.dim[4] > 1 then begin
- Msg('Only able to Crop 3D images (reorienting 4D could disrupt slice timing and diffusion directions.');
+ dcmMsg('Only able to Crop 3D images (reorienting 4D could disrupt slice timing and diffusion directions.');
exit;
end;
//next - determine output format
@@ -946,14 +946,14 @@ begin
result := '';
lExt := UpCaseExt(lFilename);
if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
if lInHdr.datatype <> kDT_SIGNED_SHORT then begin
- Msg('Unable to run SiemensPhase2Radians : input image must be 16-bit NIfTI image with intensities 0..4096 corresponding to -pi..+pi : '+lFilename);
+ dcmMsg('Unable to run SiemensPhase2Radians : input image must be 16-bit NIfTI image with intensities 0..4096 corresponding to -pi..+pi : '+lFilename);
exit;
end;
- //Msg('SiemensPhase2Radians converting 16-bit image (0..4095) to 32-bit float (-pi..+pi).'+lFileName);
+ //dcmMsg('SiemensPhase2Radians converting 16-bit image (0..4095) to 32-bit float (-pi..+pi).'+lFileName);
lOutHdr := lInHdr;
lOutHdr.datatype := kDT_FLOAT;
lOutHdr.bitpix := 32;
@@ -983,9 +983,9 @@ begin
if l16Buf^[lInc] < lMin then
lMin := l16Buf^[lInc];
if (lMin < 0) or (lMax > 4096) then
- Msg('Error: SiemensPhase2Radians expects input data with raw intensity ranging from 0..4096 (corresponding to -pi..+pi) - this image''s intensity is not in these bounds'+lFileName)
+ dcmMsg('Error: SiemensPhase2Radians expects input data with raw intensity ranging from 0..4096 (corresponding to -pi..+pi) - this image''s intensity is not in these bounds'+lFileName)
else begin
- Msg('SiemensPhase2Radians converting 0..4096 to -pi..+pi '+ lFilename);
+ dcmMsg('SiemensPhase2Radians converting 0..4096 to -pi..+pi '+ lFilename);
//Excel formula =((A1-2048)/2048)*PI()
//fx(lMin,lMax);
for lInc := 1 to lImgSamples do
@@ -1000,4 +1000,4 @@ end;
end.
-
+
\ No newline at end of file
diff --git a/dcm2nii/nii_math.pas b/dcm2nii/nii_math.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/nii_orient.pas b/dcm2nii/nii_orient.pas
old mode 100644
new mode 100755
index eaac9e7..4088e2b
--- a/dcm2nii/nii_orient.pas
+++ b/dcm2nii/nii_orient.pas
@@ -6,7 +6,7 @@ interface
uses
{$IFDEF FPC}gzio2,{$ENDIF}
- SysUtils,define_types,dicomtypes,niftiutil,GraphicsMathLibrary,prefs;
+ SysUtils,define_types,dicomtypes,niftiutil,GraphicsMathLibrary,prefs,dialogs_msg;
function Reorient(var lHdrName: string; var lHdr: TNIFTIhdr; lPrefs: TPrefs; lOverwrite,lForce: boolean): string;
//function SuperReorient(var lHdrName: string; lPrefs: TPrefs):string;
@@ -424,7 +424,7 @@ begin
lOutName := lHdrName
else
lOutName := ChangeFilePrefix (lHdrName,lPrefix);
- Msg('Reorienting as '+lOutName);
+ dcmMsg('Reorienting as '+lOutName);
if lKeepOrigHdr then
result := SaveNIfTICore (lOutName, lOBuffer, kNIIImgOffset+1, lHdr, lPrefs,lByteSwap)
else
@@ -663,11 +663,11 @@ var
begin
result := '';
if (lHdr.dim[4] > 1) or (lHdr.dim[3] < 2) then begin
- Msg('Can only orient 3D images '+inttostr(lHdr.dim[3])+' '+inttostr(lHdr.dim[4]));
+ dcmMsg('Can only orient 3D images '+inttostr(lHdr.dim[3])+' '+inttostr(lHdr.dim[4]));
exit;
end;
if (lHdr.dim[1] > lPrefs.MaxReorientMatrix) or (lHdr.dim[2] > lPrefs.MaxReorientMatrix) or(lHdr.dim[3] > lPrefs.MaxReorientMatrix) then begin
- Msg('This image will not be reoriented (larger than MaxReorientMatrix= '+inttostr(lPrefs.MaxReorientMatrix));
+ dcmMsg('This image will not be reoriented (larger than MaxReorientMatrix= '+inttostr(lPrefs.MaxReorientMatrix));
exit;
end;
lInMat := Matrix3D (
@@ -677,13 +677,13 @@ begin
0,0,0,1);
if (not lForce) and (NIfTIAlignedM (lInMat)) then begin
result := lHdrName;
- Msg('Image is already canonically oriented: '+lHdrName);
+ dcmMsg('Image is already canonically oriented: '+lHdrName);
exit;
end;
lRotMat := nifti_mat44_orthogx( lInMat,lPrefs);
if NIfTIAlignedM (lRotMat) then begin
result := lHdrName;
- Msg('According to header, image is already approximately canonically oriented');
+ dcmMsg('According to header, image is already approximately canonically oriented');
exit; //already as close as possible
end;
result := ReorientCore(lHdrName, 'o',lHdr, lPrefs, lOverwrite,false, lInMat,lRotMat);
@@ -700,11 +700,11 @@ var
begin
result := false;
if not NIFTIhdr_LoadHdr (lFilename, lHdr, lByteSwap) then begin
- Msg('Unable to read as NifTI/Analyze' + lFilename);
+ dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
if (lHdr.dim[1] > lPrefs.MaxReorientMatrix) or (lHdr.dim[2] > lPrefs.MaxReorientMatrix) or(lHdr.dim[3] > lPrefs.MaxReorientMatrix) then begin
- Msg('This image will not be reoriented (larger than MaxReorientMatrix= '+inttostr(lPrefs.MaxReorientMatrix));
+ dcmMsg('This image will not be reoriented (larger than MaxReorientMatrix= '+inttostr(lPrefs.MaxReorientMatrix));
exit;
end;
lInMat := Matrix3D (
@@ -723,4 +723,4 @@ end;
end.
-
+
\ No newline at end of file
diff --git a/dcm2nii/nii_reslice.pas b/dcm2nii/nii_reslice.pas
old mode 100644
new mode 100755
index e64269f..01e841c
--- a/dcm2nii/nii_reslice.pas
+++ b/dcm2nii/nii_reslice.pas
@@ -2,7 +2,7 @@ unit nii_reslice;
interface
{$H+}
uses
- niftiutil,define_types,sysutils,dicomtypes,prefs;
+ niftiutil,define_types,sysutils,dicomtypes,prefs,dialogs_msg;
//function ResliceImgNIfTI (lTargetImgName,lSrcImgName,lOutputName: string): boolean;
function Reslice2Targ (lSrcName,lTargetName,lDestName: string; lPrefs: TPrefs):string;
@@ -110,7 +110,7 @@ BEGIN
indxr[i] := irow;
indxc[i] := icol;
IF (a.matrix[icol,icol] = 0.0) THEN BEGIN
- Msg('pause 2 in GAUSSJ - singular matrix');
+ dcmMsg('pause 2 in GAUSSJ - singular matrix');
exit;
END;
pivinv := 1.0/a.matrix[icol,icol];
@@ -243,7 +243,7 @@ begin
kDT_SIGNED_INT:lBPP := 4;
kDT_FLOAT: lBPP := 4;
else begin
- Msg('NII reslice error: datatype not supported.');
+ dcmMsg('NII reslice error: datatype not supported.');
exit;
end;
end; //case
@@ -411,7 +411,7 @@ begin
if lPos <= (lX*lY*lZ) then begin //image not empty
result := SaveNIfTICore (lDestName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs,lByteSwap);
end else begin
- Msg('no voxels in output');
+ dcmMsg('no voxels in output');
end;
Freemem(lBuffUnaligned);
Freemem(lSrcBuffer);
@@ -446,4 +446,4 @@ begin
gBGImg.ResliceOnLoad := lReslice;
end; *)
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/notes.txt b/dcm2nii/notes.txt
old mode 100644
new mode 100755
diff --git a/dcm2nii/paramstrs.pas b/dcm2nii/paramstrs.pas
old mode 100644
new mode 100755
index 8fc45f2..a4fae11
--- a/dcm2nii/paramstrs.pas
+++ b/dcm2nii/paramstrs.pas
@@ -1,7 +1,7 @@
unit paramstrs;
{$H+}
interface
-uses prefs,define_types;
+uses prefs,define_types,dialogs_msg;
const
kVers = 'Chris Rorden''s dcm2nii :: '+kMRIcronvers;
{$Include ..\common\isgui.inc}
@@ -11,12 +11,11 @@ procedure RecursiveFolderSearch (lFolderName,lOutDir: string; var lPrefs: TPrefs
implementation
uses
-{$IFDEF GUI}gui, {$ENDIF}
+{$IFDEF GUI}gui, {$ELSE} nii_4dto3d,{$ENDIF}
{$IFNDEF UNIX}
- Windows,{$ENDIF}dialogsx, Classes,
- inifiles,SysUtils,convert,sortdicom,dicom,parconvert,filename,dicomtypes,
- nii_crop,nii_orient,nii_4dto3d,userdir;
+ Windows,{$ENDIF} Classes,
+ SysUtils,sortdicom,dicom,parconvert,filename,dicomtypes,userdir;
(*procedure RecursiveFolderSearch (lFolderName,lOutDir: string; var lPrefs: TPrefs; lDepth: integer);
var
@@ -117,7 +116,7 @@ begin
for lI := 0 to (lDirStrings.Count-1) do begin
if (lDepth = 0) and (lPrefs.RecursiveUseNameAppend) then begin
lPrefs.NameAppend := extractfilename(lDirStrings[lI])+'_';
- Msg('recursive base folder '+lPrefs.NameAppend);
+ dcmMsg('recursive base folder '+lPrefs.NameAppend);
end;
RecursiveFolderSearch(lDirStrings[lI],lOutDir,lPrefs,lDepth+1);
end;
@@ -136,7 +135,7 @@ begin
if (lExt = '.REC') or (lExt = '.PAR') then
LoadFileListPARREC(lFilename,lOutDir,lPrefs)
else if IsDicom (lFilename) then begin
- Msg('Looking for DICOM files in folder with '+lFilename);
+ dcmMsg('Looking for DICOM files in folder with '+lFilename);
LoadFileList(lFilename,lOutDir,lPrefs);
end else
lFilename := '';
@@ -165,32 +164,35 @@ end;
procedure ShowHelp (var lIniName: string; lPrefs: TPrefs);
begin
- Msg('Either drag and drop or specify command line options:');
- Msg(' '+FilenameWOExt(paramstr(0))+' <options> <sourcenames>');
- Msg('OPTIONS:');
- Msg('-a Anonymize [remove identifying information]: Y,N = '+Bool2YN(lPrefs.Anonymize));
- Msg('-b load settings from specified inifile, e.g. ''-b C:\set\t1.ini'' ');
- Msg('-c Collapse input folders: Y,N = '+Bool2YN(lPrefs.CollapseFolders));
- Msg('-d Date in filename [filename.dcm -> 20061230122032.nii]: Y,N = '+Bool2YN(lPrefs.AppendDate));
- Msg('-e events (series/acq) in filename [filename.dcm -> s002a003.nii]: Y,N = '+Bool2YN(lPrefs.AppendAcqSeries));
- Msg('-f Source filename [e.g. filename.par -> filename.nii]: Y,N = '+Bool2YN(lPrefs.AppendFilename));
- Msg('-g gzip output, filename.nii.gz [ignored if ''-n n'']: Y,N = '+Bool2YN(lPrefs.Gzip));
- Msg('-i ID in filename [filename.dcm -> johndoe.nii]: Y,N = '+Bool2YN(lPrefs.AppendPatientName));
- Msg('-m manually prompt user to specify output format [NIfTI input only]: Y,N = '+Bool2YN(lPrefs.ManualNIfTIConv));
- Msg('-n output .nii file [if no, create .hdr/.img pair]: Y,N = '+Bool2YN(lPrefs.SingleNIIFile));
- Msg('-o Output Directory, e.g. ''C:\TEMP'' (if unspecified, source directory is used)');
- Msg('-p Protocol in filename [filename.dcm -> TFE_T1.nii]: Y,N = '+Bool2YN(lPrefs.AppendProtocolName));
- Msg('-r Reorient image to nearest orthogonal: Y,N ');
- Msg('-s SPM2/Analyze not SPM5/NIfTI [ignored if ''-n y'']: Y,N = '+Bool2YN(lPrefs.SPM2));
- Msg('-v Convert every image in the directory: Y,N = '+Bool2YN(lPrefs.EveryFile));
- Msg('-x Reorient and crop 3D NIfTI images: Y,N = '+Bool2YN(lPrefs.Autocrop));
- Msg(' You can also set defaults by editing '+lIniName);
+ dcmMsg('Either drag and drop or specify command line options:');
+ dcmMsg(' '+FilenameWOExt(paramstr(0))+' <options> <sourcenames>');
+ dcmMsg('OPTIONS:');
+ dcmMsg('-4 Create 4D volumes, else DTI/fMRI saved as many 3D volumes: Y,N = '+Bool2YN(lPrefs.FourD));
+ dcmMsg('-a Anonymize [remove identifying information]: Y,N = '+Bool2YN(lPrefs.Anonymize));
+ dcmMsg('-b load settings from specified inifile, e.g. ''-b C:\set\t1.ini'' ');
+ dcmMsg('-c Collapse input folders: Y,N = '+Bool2YN(lPrefs.CollapseFolders));
+ dcmMsg('-d Date in filename [filename.dcm -> 20061230122032.nii]: Y,N = '+Bool2YN(lPrefs.AppendDate));
+ dcmMsg('-e events (series/acq) in filename [filename.dcm -> s002a003.nii]: Y,N = '+Bool2YN(lPrefs.AppendAcqSeries));
+ dcmMsg('-f Source filename [e.g. filename.par -> filename.nii]: Y,N = '+Bool2YN(lPrefs.AppendFilename));
+ dcmMsg('-g gzip output, filename.nii.gz [ignored if ''-n n'']: Y,N = '+Bool2YN(lPrefs.Gzip));
+ dcmMsg('-i ID in filename [filename.dcm -> johndoe.nii]: Y,N = '+Bool2YN(lPrefs.AppendPatientName));
+ dcmMsg('-m manually prompt user to specify output format [NIfTI input only]: Y,N = '+Bool2YN(lPrefs.ManualNIfTIConv));
+ dcmMsg('-n output .nii file [if no, create .hdr/.img pair]: Y,N = '+Bool2YN(lPrefs.SingleNIIFile));
+ dcmMsg('-o Output Directory, e.g. ''C:\TEMP'' (if unspecified, source directory is used)');
+ dcmMsg('-p Protocol in filename [filename.dcm -> TFE_T1.nii]: Y,N = '+Bool2YN(lPrefs.AppendProtocolName));
+ dcmMsg('-r Reorient image to nearest orthogonal: Y,N ');
+ dcmMsg('-s SPM2/Analyze not SPM5/NIfTI [ignored if ''-n y'']: Y,N = '+Bool2YN(lPrefs.SPM2));
+ dcmMsg('-v Convert every image in the directory: Y,N = '+Bool2YN(lPrefs.EveryFile));
+ dcmMsg('-x Reorient and crop 3D NIfTI images: Y,N = '+Bool2YN(lPrefs.Autocrop));
+ dcmMsg(' You can also set defaults by editing '+lIniName);
{$IFDEF UNIX}
- Msg('EXAMPLE: '+FilenameWOExt(paramstr(0))+' -a y /Users/Joe/Documents/dcm/IM_0116');
+ dcmMsg('EXAMPLE: '+FilenameWOExt(paramstr(0))+' -a y /Users/Joe/Documents/dcm/IM_0116');
{$ELSE}
- Msg('EXAMPLE: '+FilenameWOExt(paramstr(0))+' -a y -o C:\TEMP C:\DICOM\input1.par C:\input2.par');
- Msg('Hit <Enter> to exit.');
- MyReadLn;
+ dcmMsg('EXAMPLE: '+FilenameWOExt(paramstr(0))+' -a y -o C:\TEMP C:\DICOM\input1.par C:\input2.par');
+ dcmMsg('Hit <Enter> to exit.');
+
+ {$IFNDEF GUI}{$IFNDEF UNIX}if IsConsole then ReadLn;{$ENDIF}{$ENDIF}
+
{$ENDIF}
end; //proc ShowHelp
@@ -220,6 +222,8 @@ begin
end;
end;
+
+
procedure ProcessParamStrs;
var
lDir,lStr,lOutDir,lExt: String;
@@ -233,7 +237,11 @@ begin
if (ParamCount > 0) then
ExitCode := 1;//assume error ... will be set to 0 on successful processing of any files...
SetDefaultPrefs (lPrefs);
+ {$IFDEF FPC}
+ DefaultFormatSettings.DecimalSeparator := '.';
+ {$ELSE}
DecimalSeparator := '.';
+ {$ENDIF}
lHelpShown := false;
lAbort := false;
lSilent := false;
@@ -292,7 +300,7 @@ begin
case lCommandChar of
'4': CharBool(lStr[1],lPrefs.FourD);
'A': CharBool(lStr[1],lPrefs.Anonymize);
- 'C': CharBool(lStr[1],lPrefs.CollapseFolders);
+ 'C': CharBool(lStr[1],lPrefs.CollapseFolders);
'D': CharBool(lStr[1],lPrefs.AppendDate);
'E': CharBool(lStr[1],lPrefs.AppendAcqSeries);
'F': CharBool(lStr[1],lPrefs.AppendFilename);
@@ -310,7 +318,7 @@ begin
if fileexists(lIniName) then begin
IniFile(True,lIniName, lPrefs);
end else
- Msg('0 ERROR: unable to find '+lIniName);
+ dcmMsg('0 ERROR: unable to find '+lIniName);
end;
'O': begin //output directory
lOutDir := '';
@@ -337,7 +345,7 @@ begin
lDir := ExtractFileDir(lStr);
if lDir = '' then begin //since fileexists, file is in working directory
lDir := GetCurrentDir;
- Msg('0 files in working directory '+lDir);
+ dcmMsg('0 files in working directory '+lDir);
EnsureDirEndsWithPathDelim(lDir);
if fileexists(lDir + lStr) then
lStr := lDir+ lStr;
@@ -346,7 +354,7 @@ begin
if IsNiftiExt(lStr) then begin
{$IFDEF GUI}
MainForm.ConvertDCM2NII(lStr,lPrefs);
- //Msg('Please drag and drop NIfTI images onto dcm2niigui to convert them')
+ //dcmMsg('Please drag and drop NIfTI images onto dcm2niigui to convert them')
{$ELSE}
ModifyAnalyze(lStr,lPrefs);
{$ENDIF}
@@ -356,15 +364,15 @@ begin
exit;
end else begin
{$IFNDEF UNIX}lStartTime := GetTickCount; {$ENDIF}
- if lPrefs.everyfile then
+ if lPrefs.everyfile then
LoadFileList(lStr,lOutDir,lPrefs)
else
LoadParamFileList(lStr,lOutDir,lPrefs,I);
- {$IFNDEF UNIX}Msg('Time elapsed '+inttostr( GetTickCount-lStartTime)+'ms'); {$ENDIF}
+ {$IFNDEF UNIX}dcmMsg('Time elapsed '+inttostr( GetTickCount-lStartTime)+'ms'); {$ENDIF}
exit; //only process a single file
end;
end else if not (lSilent) then begin
- Msg('0 '+paramstr(0)+' ERROR: unable to find '+lStr);
+ dcmMsg('0 '+paramstr(0)+' ERROR: unable to find '+lStr);
if not lHelpShown then
Showhelp(lIniName, lPrefs);
lHelpShown := true;
diff --git a/dcm2nii/parconvert.pas b/dcm2nii/parconvert.pas
old mode 100644
new mode 100755
index 97d83c2..392c6ba
--- a/dcm2nii/parconvert.pas
+++ b/dcm2nii/parconvert.pas
@@ -3,11 +3,12 @@ unit parconvert;
interface
uses
{$IFDEF FPC}gzio2, {$ENDIF}
-define_types,SysUtils,dicom,dicomtypes,filename,nii_4dto3d,niftiutil,nii_orient, nii_crop,GraphicsMathLibrary,prefs;
+define_types,SysUtils,dicom,dicomtypes,filename,nii_4dto3d,niftiutil,nii_orient, nii_crop,GraphicsMathLibrary,prefs,dialogs_msg;
function LoadFileListPARREC (var lInFilename, lOutDir: string; var lPrefs: TPrefs): boolean;
implementation
-uses dialogsx;
+uses dialogsx, philips_bvec;
+
procedure PAR2DICOMstudyDate(var lDicomData: DICOMdata);
{input: lDicomData.StudyDate = 2002.12.29 / 19:48:58.0000
@@ -126,11 +127,10 @@ end;
temp := temp + a.matrix[i,k]*b.matrix[k,j];
END;
RESULT.matrix[i,j] := Defuzz(temp)
-
END
END
- ELSE Msg('MultiplyMatrices error: '+inttostr(a.size)+' <> '+inttostr(b.size))
+ ELSE dcmMsg('MultiplyMatrices error: '+inttostr(a.size)+' <> '+inttostr(b.size))
END {MultiplyMatrices};
function RealToStr(lR: double {was extended}; lDec: integer): string;
@@ -140,11 +140,11 @@ end;
procedure ReportMatrix (lStr: string;lM:TMatrix);
begin
- Msg(lStr);
- Msg( RealToStr(lM.matrix[1,1],6)+','+RealToStr(lM.matrix[1,2],6)+','+RealToStr(lM.matrix[1,3],6)+','+RealToStr(lM.matrix[1,4],6));
- Msg( RealToStr(lM.matrix[2,1],6)+','+RealToStr(lM.matrix[2,2],6)+','+RealToStr(lM.matrix[2,3],6)+','+RealToStr(lM.matrix[2,4],6));
- Msg( RealToStr(lM.matrix[3,1],6)+','+RealToStr(lM.matrix[3,2],6)+','+RealToStr(lM.matrix[3,3],6)+','+RealToStr(lM.matrix[3,4],6));
- Msg( RealToStr(lM.matrix[4,1],6)+','+RealToStr(lM.matrix[4,2],6)+','+RealToStr(lM.matrix[4,3],6)+','+RealToStr(lM.matrix[4,4],6));
+ dcmMsg(lStr);
+ dcmMsg( RealToStr(lM.matrix[1,1],6)+','+RealToStr(lM.matrix[1,2],6)+','+RealToStr(lM.matrix[1,3],6)+','+RealToStr(lM.matrix[1,4],6));
+ dcmMsg( RealToStr(lM.matrix[2,1],6)+','+RealToStr(lM.matrix[2,2],6)+','+RealToStr(lM.matrix[2,3],6)+','+RealToStr(lM.matrix[2,4],6));
+ dcmMsg( RealToStr(lM.matrix[3,1],6)+','+RealToStr(lM.matrix[3,2],6)+','+RealToStr(lM.matrix[3,3],6)+','+RealToStr(lM.matrix[3,4],6));
+ dcmMsg( RealToStr(lM.matrix[4,1],6)+','+RealToStr(lM.matrix[4,2],6)+','+RealToStr(lM.matrix[4,3],6)+','+RealToStr(lM.matrix[4,4],6));
end;
FUNCTION Diag3D (CONST m1,m2,m3,m4: DOUBLE): TMatrix;
@@ -253,7 +253,7 @@ begin
base := MultiplyMatrices(rb,rc);
base := MultiplyMatrices(ra,base);
if lOrient = 2 then begin //sagittal
- //Msg('sag');
+ //dcmMsg('sag');
lmm := Matrix3D (
0, 0, -1,0,
1, 0, 0, 0,
@@ -265,7 +265,7 @@ begin
SetLarger (lYmm,lZmm);
lXmm := lRLFOV /lZ;
end else if lOrient = 3 then begin //coronal
- //Msg('Coronal');
+ //dcmMsg('Coronal');
lmm := Matrix3D (
1, 0, 0,0,
0,0, 1, 0,
@@ -278,7 +278,7 @@ begin
lYmm := lAPFOV /lZ;
end else begin
- //Msg('Axial '+inttostr(lOrient));
+ //dcmMsg('Axial '+inttostr(lOrient));
lmm := diag3D(1, 1, 1,1);
lXmm := lRLFOV /lX;
lYmm := lAPFOV /lY;
@@ -340,7 +340,51 @@ ReportMatrix('analyze_to_dicom',analyze_to_dicom);}
dx, dy, dz, lNHdr.pixdim[0]{QFac});
end;
-procedure read_PAR2NII(var lNHdr: TNIftIHdr; var lDICOMdata: DICOMdata; var lHdrOK, lImageFormatOK,lPrecise:boolean; var lDynStr: string;var lFileName: string; lReadOffsetTables: boolean; var lOffset_pos_table: LongIntp; var lOffsetTableEntries,lRescaleEntries: integer; var lSlopeRA,lInterceptRA: Singlep; var lnum4Ddatasets: integer);
+function DTItextfiles (lImgName: string; lDTIra: TDTIra; lNumDir: integer): boolean;
+//create text files that describe output vectors
+var
+ lOutDTIname: string;
+ lTextF: TextFile;
+ lSeries,lStart,lEnd: integer;
+begin
+ result := false;
+ if lImgName = '' then exit;
+ lStart := 1;
+ lEnd := lNumDir;
+ //ensure some variability
+ lSeries := 1;
+ while (lSeries <= lEnd) and (lDTIra[1].v1 = lDTIra[lSeries].v1) and (lDTIra[1].bval = lDTIra[lSeries].bval) do
+ inc(lSeries);
+ if (lSeries > lEnd) then exit; //no variability in bvec or bval
+ //create bvec
+ lOutDTIname := changefileextX(lImgName,'.bvec');
+ assignfile(lTextF,lOutDTIname);
+ Filemode := 0;
+ rewrite(lTextF);
+ for lSeries := lStart to lEnd do
+ Write(lTextF,floattostr(lDTIra[lSeries].v1)+ ' ');
+ Writeln(lTextF);
+ for lSeries := lStart to lEnd do
+ Write(lTextF,floattostr(lDTIra[lSeries].v2)+ ' ');
+ Writeln(lTextF);
+ for lSeries := lStart to lEnd do
+ Write(lTextF,floattostr(lDTIra[lSeries].v3)+ ' ');
+ Writeln(lTextF);
+ closefile(lTextF);
+ //create bval
+ lOutDTIname := changefileextX(lOutDTIname,'.bval');
+ assignfile(lTextF,lOutDTIname);
+ Filemode := 0;
+ rewrite(lTextF);
+ for lSeries := lStart to lEnd do
+ Write(lTextF,inttostr(lDTIra[lSeries].bval)+' ');
+ Writeln(lTextF);
+ closefile(lTextF);
+ result := true;
+end;// funct DTItextfiles
+
+
+procedure read_PAR2NII(var lNHdr: TNIftIHdr; var lDICOMdata: DICOMdata; var lHdrOK, lImageFormatOK,lPrecise:boolean; var lDynStr: string;var lFileName: string; lReadOffsetTables: boolean; var lOffset_pos_table: LongIntp; var lOffsetTableEntries,lRescaleEntries: integer; var lSlopeRA,lInterceptRA: Singlep; var lnum4Ddatasets: integer; var lDTIra: TDTIra);
label 333; //1384 now reads up to 8 dimensional data....
type tRange = record
Min,Val,Max: double; //some vals are ints, others floats
@@ -376,7 +420,11 @@ const UNIXeoln = chr(10);
lSliceSz: integer = 0;
lMatOrient: boolean = false;
//lOffsetTablesRequired: boolean = false;
-var lErrorStr,lInStr,lUpCaseStr,lReportedTRStr{,lUpcase20Str}: string;
+var
+ lDTIraDyn, lDTIraDynUnSorted: array of TDTI;
+ //lDTIra: TDTIra;
+ //lHFSStr,
+ lErrorStr,lInStr,lUpCaseStr,lReportedTRStr: string;
lAPFOV,lFHFOV,lRLFOV,
lScanResX,lScanResY,lAngleA,lAngleB,lAngleC,lOffset1,lOffset2,lOffset3{,lXFOV,lYFOV}: double;
lSliceIndexRAx,lSliceSequenceRA,lSortedSliceSequence: int64P;
@@ -425,7 +473,7 @@ begin
result := strtofloat(lStr);
except
on EConvertError do begin
- Msg('read_PAR2NII: Unable to convert the string '+lStr+' to a number');
+ dcmMsg('read_PAR2NII: Unable to convert the string '+lStr+' to a number');
result := 1;
exit;
end;
@@ -442,6 +490,7 @@ begin
lIsParVers42 := false;
lSliceInfoCount := 0;
getmem(lSliceIndexRAx, kMaxnSLices* sizeof(int64));
+ setlength(lDTIraDyn,kMaxnSLices+1);//+1 since indexed from zero
for lInc := kXdim to kIndex do //initialize all values: important as PAR3 will not explicitly report all
MinMaxTRange(lRangeRA[lInc],0);
@@ -461,7 +510,7 @@ begin
GetMem (lSliceSequenceRA, kMaxnSLices*sizeof(int64)); //note: must free dynamic memory: goto 333 if any error
BlockRead(fp, lCharRA^, lFileSz, lInpos);
if lInPos <> lFileSz then begin
- Msg('read_PAR2NII: Disk error, unable to read full input file.');
+ dcmMsg('read_PAR2NII: Disk error, unable to read full input file.');
goto 333;
end;
linPos := 1;
@@ -499,14 +548,14 @@ begin
else if lUpCaseStr = '4.1' then begin
lIsParVers3 := false;
lIsParVers41 := true;
- Msg('PAR v4.1 not yet fully supported')
+ dcmMsg('PAR v4.1 not yet fully supported')
end else if lUpCaseStr = '4.2' then begin //11/2007
lIsParVers3 := false;
lIsParVers41 := true;
lIsParVers42 := true;
- Msg('PAR v4.2 not yet fully supported')
+ dcmMsg('PAR v4.2 : DTI bval/bvec support still experimental')
end else
- Msg('Warning: unknown PAR version '+lUpCaseStr);
+ dcmMsg('Warning: unknown PAR version '+lUpCaseStr);
end;
end else if (lInStr[1] = '.') or (not lHdrOK) then begin // GENERAL_INFORMATION section (line starts with '.')
@@ -518,25 +567,12 @@ begin
end; //while reading line
inc(lPos); {read equal sign in := statement}
lDynStr := lDynStr + lInStr+kCR;
- //Msg(inttostr(length(lUpCaseStr)));
+ //dcmMsg(inttostr(length(lUpCaseStr)));
if (not lHdrOK) and (lUpcaseStr = ('DATADESCRIPTIONFILE')) then begin //1389 PAR file
lHdrOK := true;
lDicomData.little_endian := 1;
end;
-
-(* if (not lHdrOK) and (length(lUpCaseStr) >= 19) then begin
- //lUpcase20Str := xx
- lUpcase20Str := '';
- for lInc := 1 to 19 do
- lUpcase20Str := lUpCase20Str + lUpcaseStr[lInc];
- //Msg(lUpcase20Str);
- if (lUpcase20Str = ('DATADESCRIPTIONFILE')) or (lUpcase20Str = ('EXPERIMENTALPRIDEDA')) then begin //PAR file
- lHdrOK := true;
- lDicomData.little_endian := 1;
- end;
- end;
- *)
if (lUpCaseStr ='REPETITIONTIME[MSEC]') or (lUpCaseStr ='REPETITIONTIME[MS]') then
lDicomData.TR := round(readParFloat);
if (lUpCaseStr ='MAXNUMBEROFSLICES/LOCATIONS') then
@@ -579,6 +615,9 @@ begin
lAngleA := (readParFloat);
lAngleB := (readParFloat);
lAngleC := (readParFloat);
+ lDicomData.AngulationAP := lAngleA;
+ lDicomData.AngulationFH := lAngleB;
+ lDicomData.AngulationRL := lAngleC;
end;
if (lUpCaseStr ='OFFCENTREMIDSLICE(APFHRL)[MM]') then begin
lOffset2 := (readParFloat);
@@ -587,13 +626,22 @@ begin
end;
if lUpCaseStr = 'PROTOCOLNAME' then
lDicomData.ProtocolName := readParStr;
+ if lUpCaseStr = 'PATIENTPOSITION' then begin
+ lDicomData.PatientPos := UpperCase (readParStr); //upcase
+ if (lDicomData.PatientPos <> 'HEAD FIRST SUPINE') then
+ dcmMsg('*WARNING: participant was not head first supine - spatial transforms may be wrong :'+lDicomData.PatientPos)
+ else
+ lDicomData.PatientPos := 'HFS';
+
+
+ end;
if lUpCaseStr = 'PATIENTNAME' then
lDicomData.PatientName := readParStr;
if lUpCaseStr ='IMAGEPIXELSIZE[8OR16BITS]' then begin
MinMaxTRange(lRangeRA[kBitsPerVoxel],readParFloat);
end;
if not lHdrOK then begin
- Msg('read_PAR2NII: Error reading header');
+ dcmMsg('read_PAR2NII: Error reading header');
goto 333;
end;
end else begin //SliceInfo: IMAGE_INFORMATION (line does NOT start with '.' or '#')
@@ -636,7 +684,12 @@ begin
if lIsParVers42 then begin
for lHdrPos := 48 to 49 do
lSliceHeaderRA[lHdrPos] := readparfloat;
- //fx( lSliceHeaderRA[49]);
+ //fx(lSliceInfoCount,lSliceHeaderRA[46],lSliceHeaderRA[47],lSliceHeaderRA[48]);
+ lDTIraDyn[lSliceInfoCount].bval := round(lSliceHeaderRA[34]);
+ //# diffusion (ap, fh, rl) (3*float) 46=AP=Y,47=FH=Z,48=RL=X
+ lDTIraDyn[lSliceInfoCount].v1 := lSliceHeaderRA[48];
+ lDTIraDyn[lSliceInfoCount].v2 := lSliceHeaderRA[46];
+ lDTIraDyn[lSliceInfoCount].v3 := lSliceHeaderRA[47];
MinMaxTRange(lRangeRA[kCardiac], ({cardiac}lSliceHeaderRA[49]*100)+ ({asl}lSliceHeaderRA[4]) );
end; //PAR42
@@ -660,7 +713,7 @@ begin
lOrient := round(lSliceHeaderRA[19])
else
lOrient := round(lSliceHeaderRA[26]);
-
+ //# slice orientation ( TRA/SAG/COR ) (integer)
matx(lNHdr,lDicomData,lAngleA,lAngleB,lAngleC,lOffset1,lOffset2,lOffset3,
lRangeRA[kXdim].Val,lRangeRA[kYdim].Val,lDicomData.XYZdim[3],
lAPFOV,lFHFOV,lRLFOV,lOrient);
@@ -673,7 +726,7 @@ begin
lDicomData.XYZdim[2] := round(lRangeRA[kYdim].Val);
lDicomData.XYZdim[3] := 1+round(lRangeRA[kSlice].Max-lRangeRA[kSlice].Min);
if (lSliceInfoCount mod lDicomData.XYZdim[3]) <> 0 then
- Msg('read_PAR2NII: Total number of slices not divisible by number of slices per volume. Reconstruction error?');
+ dcmMsg('read_PAR2NII: Total number of slices not divisible by number of slices per volume. Reconstruction error?');
if lDicomData.XYZdim[3] > 0 then
lDicomData.XYZdim[4] := lSliceInfoCount div lDicomData.XYZdim[3] //nVolumes = nSlices/nSlicePerVol
else
@@ -721,7 +774,7 @@ begin
//if we get here, the header is fine, next steps will see if image format is readable...
lHdrOK := true;
if lSliceInfoCount < 1 then begin
- Msg('No valid images found.') ;
+ dcmMsg('No valid images found.') ;
goto 333;
end;
//next: see if slices are in sequence
@@ -742,6 +795,7 @@ begin
lMaxIndex := lSliceIndexRAx^[lInc];
until (lInc = lSliceInfoCount) or (lSlicesNotInSequence);
end; //at least 2 slices
+
//Next: report any errors
lErrorStr := '';
if (lSlicesNotInSequence) and (not lReadOffsetTables) then
@@ -761,7 +815,7 @@ begin
//if any errors were encountered, report them....
if lErrorStr <> '' then begin
- Msg('read_PAR2NII: This software can not convert this Philips data:'+kCR+lErrorStr);
+ dcmMsg('read_PAR2NII: This software can not convert this Philips data:'+kCR+lErrorStr);
goto 333;
end;
//Next sort image indexes here...
@@ -772,7 +826,7 @@ begin
lOffset_pos_table^[lInc] := lInc;
ShellSortItems (1, lSliceInfoCount,lOffset_pos_table,lSliceSequenceRA, lRepeatedValues);
(* if lRepeatedValues then begin
- Msg('read_PAR2NII: fatal error, slices do not appear to have unique indexes [multiple copies of same slice]');
+ dcmMsg('read_PAR2NII: fatal error, slices do not appear to have unique indexes [multiple copies of same slice]');
FreeMem (lOffset_pos_table);
goto 333;
end; *)
@@ -792,7 +846,8 @@ begin
//PhilipsPrecise (lRSx[lInc], lRIx[lInc],lSSx[lInc], lDicomData.IntenScale,lDicomData.IntenIntercept);
//if lOffsetTablesRequired then begin
- // Msg('Image saved as 32-bit data: varying intensity scaling factors or complicated Pixel to Precise transform');
+ // dcmMsg('Image saved as 32-bit data: varying intensity scaling factors or complicated Pixel to Precise transform');
+
if (lRangeRA[kSS].min = lRangeRA[kSS].max)
and (lRangeRA[kRS].min = lRangeRA[kRS].max)
and (lRangeRA[kRI].min = lRangeRA[kRI].max) then
@@ -802,9 +857,13 @@ begin
getmem (lSlopeRA, lRescaleEntries*sizeof(single));
getmem (lInterceptRA, lRescaleEntries*sizeof(single));
if lOffsetTableEntries = lSliceInfoCount then begin //need to sort slices
+ setlength(lDTIraDynUnSorted,lSliceInfoCount+1);//+1 since indexed from zero
+ for lInc := 1 to lSliceInfoCount do
+ lDTIraDynUnSorted[lInc] := lDTIraDyn[lInc];
for lInc := 1 to lSliceInfoCount do begin
lSlopeRA^[lInc] := lSlopeRAx[lOffset_pos_table^[lInc]];
lInterceptRA^[lInc] := lInterceptRAx[lOffset_pos_table^[lInc]];
+ lDTIraDyn[lInc] := lDTIraDynUnSorted[lOffset_pos_table^[lInc]];
end;
end else begin //if sorted, else unsorted
for lInc := 1 to lSliceInfoCount do begin
@@ -823,17 +882,48 @@ begin
or (lRangeRA[kEcho].min <> lRangeRA[kEcho].max) //5D file space+time+echo
or (lRangeRA[kType].min <> lRangeRA[kType].max) //5D file space+time+echo
or (lRangeRA[kSequence].min <> lRangeRA[kSequence].max) then begin//5D file space+time+echo
- Msg('Warning: note that this image has more than 4 dimensions (multiple Cardiac/Echo/Type/Sequence)');
- Msg('Cardiac min..max '+floattostr(lRangeRA[kCardiac].min)+'..'+floattostr(lRangeRA[kCardiac].max) );
- Msg('Echo min..max '+floattostr(lRangeRA[kEcho].min)+'..'+floattostr(lRangeRA[kEcho].max) );
- Msg('Type min..max '+floattostr(lRangeRA[kType].min)+'..'+floattostr(lRangeRA[kType].max) );
- Msg('Sequence min..max '+floattostr(lRangeRA[kSequence].min)+'..'+floattostr(lRangeRA[kSequence].max) );
+ dcmMsg('Warning: note that this image has more than 4 dimensions (multiple Cardiac/Echo/Type/Sequence)');
+ dcmMsg('Cardiac min..max '+floattostr(lRangeRA[kCardiac].min)+'..'+floattostr(lRangeRA[kCardiac].max) );
+ dcmMsg('Echo min..max '+floattostr(lRangeRA[kEcho].min)+'..'+floattostr(lRangeRA[kEcho].max) );
+ dcmMsg('Type min..max '+floattostr(lRangeRA[kType].min)+'..'+floattostr(lRangeRA[kType].max) );
+ dcmMsg('Sequence min..max '+floattostr(lRangeRA[kSequence].min)+'..'+floattostr(lRangeRA[kSequence].max) );
end;
+
+
//if we get here, the Image Format is OK
lImageFormatOK := true;
lFileName := changefileextX(lFilename,'.rec'); //for Linux: case sensitive extension search '.rec' <> '.REC'
- 333: //abort clause: skips lHdrOK and lImageFormatOK
+ //next save dti b-values
+ if (lIsParVers42) and (lDicomData.XYZdim[4] <= kMaxDTIDir) and (lDicomData.XYZdim[4] > 1) then begin
+
+ for lInc := 1 to lDicomData.XYZdim[4] do
+ lDTIra[lInc] := lDTIraDyn[(lDicomData.XYZdim[3]*(lInc-1))+1];
+ //see if bval or bvec varies...
+ lInc := 1;
+ while (lInc <= lDicomData.XYZdim[4]) and (lDTIra[lInc].bval = lDTIra[1].bval) and (lDTIra[lInc].v1 = lDTIra[1].v1) do
+ inc(lInc);
+ //warn if untested orientation
+ if (lInc <= lDicomData.XYZdim[4]) and (lOrient <> 1) then
+ dcmMsg('WARNING: DTI vectors only tested for transsaxially oriented Philips data: bvec values may be inaccurate!');
+
+ (*if (lInc <= lDicomData.XYZdim[4]) then begin//bvec or bval vary
+ //# slice orientation ( TRA/SAG/COR ) (integer)
+ if lOrient <> 1 then
+ dcmMsg('WARNING: DTI vectors only tested for transsaxially oriented Philips data: bvec values may be inaccurate!');
+ PhilipsCorrectBvecs(lDICOMdata, lDTIra, lDicomData.XYZdim[4]);
+ DTItextfiles (lFileName, lDTIra, lDicomData.XYZdim[4]);
+ end; *)
+end else begin
+ //not DTI data - provide empty bvec/bval file
+ lDTIra[1].bval := 0;
+ lDTIra[1].v1 := 0;
+ lDTIra[1].v2 := 0;
+ lDTIra[1].v3 := 0;
+ for lInc := 1 to lDicomData.XYZdim[4] do
+ lDTIra[lInc] := lDTIra[1];
+end;
+333: //abort clause: skips lHdrOK and lImageFormatOK
//next: free dynamically allocated memory
FreeMem( lCharRA);
FreeMem (lSliceSequenceRA);
@@ -847,7 +937,7 @@ var
begin
result := 'DateNA';//bogus
days := (lInSec div 86400)+2451547;//+2451547 as we convert to julian
- //Msg(inttostr(days));
+ //dcmMsg(inttostr(days));
//next convert Y,M,D
l := days + 68569;
n := trunc(( 4 * l ) / 146097);
@@ -892,29 +982,25 @@ label
678;
var
//lVaryingScaleFactorsTableEntries,
- lLines,lColBytes,lRows,lRowsdiv2,lSwap,lInc,
- l4Doffset,lcurrent4Dvol,lnum4Ddatasets,
- lSlicePixelsx,
- lnSlicesx,
- lSliceSzOutx,
- lSLiceSzx,
- lRescaleEntries, lPos,lOffsetTableEntries: longint;
- lOutF,lInF: File;
- lNHdr,lAHdr: TNIFTIhdr;
- lP,lBuffer : Bytep;
- lFileName,lRECFilename,lOutImgName,lOutHdrName,lDynStr,lOutDirPath: String;
- lDICOMdata: dicomdata;
- lScaleFactorVariesInThis4DVolume,lAbort,lHdrOK, lImageFormatOK: boolean;
- lSlopeRA,lInterceptRA,
- lSingleBuffer: Singlep;
- lOffset_pos_table: LongIntp;
+ lLines,lColBytes,lRows,lRowsdiv2,lSwap,lInc,l4Doffset,lcurrent4Dvol,lnum4Ddatasets,lSlicePixelsx, lnSlicesx,
+ lSliceSzOutx,lSLiceSzx,lRescaleEntries, lPos,lOffsetTableEntries: longint;
+ lOutF,lInF: File;
+ lNHdr,lAHdr: TNIFTIhdr;
+ lP,lBuffer : Bytep;
+ lFileName,lRECFilename,lOutImgName,lOutHdrName,lDynStr,lOutDirPath: String;
+ lDICOMdata: dicomdata;
+ lScaleFactorVariesInThis4DVolume,lAbort,lHdrOK, lImageFormatOK: boolean;
+ lSlopeRA,lInterceptRA,
+ lSingleBuffer: Singlep;
+ lOffset_pos_table: LongIntp;
+ lDTIra: TDTIra;
begin
result := false;
lFileName := lInFilename;
if (lOutDir = '') then
lOutDirPath := ExtractFilePath(lFileName)//ExtractFileDirWithPathDelim(lFilename)//ExtractFilePath(lFileName)
else if not direxists(lOutDir) then begin
- Msg('Unable to find output directory '+lOutDir);
+ dcmMsg('Unable to find output directory '+lOutDir);
lOutDirPath := ExtractFilePath(lFileName)
end else
lOutDirPath := lOutDir;
@@ -922,16 +1008,16 @@ begin
lOutDirPath := lOutDirPath + pathdelim;
lAbort := false;
lRecFilename :=ChangeFileExt(lFileName,'.rec');
- Msg('input name '+ lInFilename);
- Msg('input REC name '+lRecFilename);
+ dcmMsg('input name '+ lInFilename);
+ dcmMsg('input REC name '+lRecFilename);
//Apr08 problems with filenames with . in them lRecFilename :=ExtractFilePath(lFileName)+ParseFileName(ExtractFileName(lFileName))+'.rec';
if not fileexists(lRecFilename) then //might be Linux: case sensitive extensions
lRecFilename :=ChangeFileExt(lFileName,'.REC');
// lRecFilename :=ExtractFilePath(lFileName)+ParseFileName(ExtractFileName(lFileName))+'.REC';
if not fileexists(lRecFilename) then
- Msg('Unable to find REC image data file named '+lRecFileName)
+ dcmMsg('Unable to find REC image data file named '+lRecFileName)
else if fileexists(lRecFilename) and fileexists(lFilename) then begin //convert
- read_par2NII(lNHdr,lDICOMdata,lHdrOK,lImageFormatOK,lPRefs.PhilipsPrecise, lDynStr,lFileName,true,lOffset_pos_table,lOffsetTableEntries,lRescaleEntries, lSlopeRA,lInterceptRA,lnum4Ddatasets);
+ read_par2NII(lNHdr,lDICOMdata,lHdrOK,lImageFormatOK,lPRefs.PhilipsPrecise, lDynStr,lFileName,true,lOffset_pos_table,lOffsetTableEntries,lRescaleEntries, lSlopeRA,lInterceptRA,lnum4Ddatasets,lDTIra);
if (lnum4Ddatasets > 1) and ((lDicomData.XYZdim[4] mod lnum4Ddatasets) = 0) then //break 5D files into separate 4D files
lDicomData.XYZdim[4] := lDicomData.XYZdim[4] div lnum4Ddatasets
else
@@ -949,7 +1035,7 @@ begin
repeat //for each 4D volume
inc(lcurrent4Dvol);
lOutHdrName :=lOutDirPath+{Pathdelim+}OutputFilename(lRecFilename,lDicomData,lPrefs);//Pathdelim 11/2007
- if lnum4Ddatasets > 1 then begin
+ if lnum4Ddatasets > 1 then begin
l4DOffset := (lcurrent4Dvol-1)* lnSlicesx;
lOutHdrName :=(lOutHdrName)+'x'+inttostr(lcurrent4Dvol)+'.hdr'
end else
@@ -962,7 +1048,7 @@ begin
if (lPrefs.SingleNIIFile) and (lPrefs.GZip) then begin
lOutHdrName := lOutHdrName+'.gz';
if (not UniqueFileName(lOutHdrName)) then begin
- Msg('File already exists '+lOutImgName+' '+lOutHdrName);
+ dcmMsg('File already exists '+lOutImgName+' '+lOutHdrName);
exit;
end;
@@ -971,36 +1057,46 @@ begin
lOutImgName := lOutHdrName;
end else begin
if (not UniqueFileName(lOutHdrName)) or (not UniqueFileName(lOutImgName)) then begin
- Msg('File already exists '+lOutImgName+' '+lOutHdrName);
+ dcmMsg('File already exists '+lOutImgName+' '+lOutHdrName);
exit;
end;
end;
- Msg(lFileName+' --> '+ lOutImgName);
-//exit; //trap
- {$IFDEF LINUX}
+ dcmMsg(lFileName+' -> '+ lOutImgName);
+ //exit; //trap
+ if (lDicomData.XYZdim[4] > 1) then begin //if 4D: save DTI data
+ lInc := 1;
+ while (lInc <= lDicomData.XYZdim[4]) and (lDTIra[lInc].bval = lDTIra[1].bval) and (lDTIra[lInc].v1 = lDTIra[1].v1) do
+ inc(lInc);
+ if (lInc <= lDicomData.XYZdim[4]) then begin//bvec or bval vary
+ PhilipsCorrectBvecs(lDICOMdata, lDTIra, lDicomData.XYZdim[4]);
+ DTItextfiles (lOutImgName, lDTIra, lDicomData.XYZdim[4]);
+ end;
+ end; //if 4D: save DTI data
+
+ {$IFDEF LINUX}
//perhaps the file is .REC, not .rec
if (lSliceSzx * lnSLicesx) > FSize(lFileName) then
lRecFilename := changefileext(lFileName,'.REC');
{$ENDIF}
if (lSliceSzx * lnSLicesx) > FSize(lRecFilename) then begin
- Msg('Conversion error: the REC file '+lRecFilename+ ' is not as large as described by the PAR file X*Y*Z*T*BytesPerPixel='
+ dcmMsg('Conversion error: the REC file '+lRecFilename+ ' is not as large as described by the PAR file X*Y*Z*T*BytesPerPixel='
+ inttostr(lDicomData.XYZdim[1])+'*'+inttostr(lDicomData.XYZdim[2])+'*'+inttostr(lDicomData.XYZdim[3])+'*'+inttostr(lDicomData.XYZdim[4])+'*'+inttostr(lDicomData.Allocbits_per_pixel div 8)
+' = '+ inttostr(lSliceSzx* lnSLicesx)+' <> '+inttostr(FSize(lFileName)) );
{$IFDEF LINUX}
- Msg(' Suggestion: in UNIX .REC and .rec are different files - check file extension' );
+ dcmMsg(' Suggestion: in UNIX .REC and .rec are different files - check file extension' );
{$ENDIF}
lAbort := true;
end else if ((sizeof(TNIFTIhdr)+(lSliceSzx*lnSlicesx))> DiskFreeEx(lOutImgName)) then begin
- Msg('There is not enough free space on the destination disk to save the converted image. '+kCR+
+ dcmMsg('There is not enough free space on the destination disk to save the converted image. '+kCR+
lOutImgName+ kCR+' Bytes Required: '+inttostr(sizeof(TNIFTIhdr)+(lSliceSzx*lnSlicesx)) );
lAbort := true;
end else if fileexists(lOutHdrName) or fileexists(lOutImgName) then
- Msg('Unable to convert images: file already exists named: '+lOutHdrName)
+ dcmMsg('Unable to convert images: file already exists named: '+lOutHdrName)
else if (not lHdrOK) then
- msg('Problem with header...')
+ dcmMsg('Problem with header...')
else if (not lImageFormatOK) then
- msg('Problem with image...')
+ dcmMsg('Problem with image...')
else if (lHdrOK) and (lImageFormatOK) and (lDicomData.XYZdim[3] > 0) and (lSliceSzx > 0) then begin
DICOM2AnzHdr(lAHdr,lPrefs.Anonymize,lFilename,lDICOMdata);
@@ -1096,7 +1192,7 @@ begin
inc(lPos,2);
end;
end else
- Msg('Error: can only convert 8/16bit PAR/REC files with varying scaling values.');
+ dcmMsg('Error: can only convert 8/16bit PAR/REC files with varying scaling values.');
BlockWrite(lOutF, lSingleBuffer^, lSliceSzOutx);
end else
BlockWrite(lOutF, lBuffer^, lSliceSzOutx);
@@ -1160,7 +1256,7 @@ begin
end; //1/2010
lOutDirName := ExtractFileDirWithPathDelim(lOutDirName);
if not DirWritePermission(lOutDirName) then begin // <- tested with Unix
- Msg('Error: output directory is read-only: '+lOutDirName);
+ dcmMsg('Error: output directory is read-only: '+lOutDirName);
exit;
end;
lError := false;
@@ -1182,14 +1278,14 @@ begin
end;
until (FindNext(lSearchRec) <> 0);
end else
- Msg( 'Error: Unable to find PAR files in '+lFilePath{+PathDelim}+lMaskExt); //some files found
+ dcmMsg( 'Error: Unable to find PAR files in '+lFilePath{+PathDelim}+lMaskExt); //some files found
SysUtils.FindClose(lSearchRec);
Filemode := 2;
end else begin
if FileExists(lInFilename) then begin
lError := ConvertPhilipsPARtoAnalyze(lInFilename, lOutDirName, lPrefs);
end else
- Msg( 'Unable to find PAR file named '+lInFilename); //some files found
+ dcmMsg( 'Unable to find PAR file named '+lInFilename); //some files found
end;
if lError then
result := false //at least one error
@@ -1198,4 +1294,4 @@ begin
end;
end.
-
+
\ No newline at end of file
diff --git a/dcm2nii/philips_bvec.pas b/dcm2nii/philips_bvec.pas
new file mode 100755
index 0000000..d18a2e9
--- /dev/null
+++ b/dcm2nii/philips_bvec.pas
@@ -0,0 +1,232 @@
+unit philips_bvec;
+{$ifdef fpc}{$mode delphi}{$endif}
+{$H+}
+interface
+uses
+ //StrUtils,
+ Classes, SysUtils, define_types, dicomtypes, dialogsx,GraphicsMathLibrary,dialogs_msg;
+//{$DEFINE VERBOSE_BVEC}
+
+
+procedure PhilipsCorrectBvecs(var lDICOMdata:dicomdata; var lDTIra: TDTIRA; nVec: integer);
+
+implementation
+
+//Next routines for PhilipsBVec
+ FUNCTION Vector2D (CONST xValue, yValue, zValue: DOUBLE): TVector;
+ BEGIN
+ WITH RESULT DO
+ BEGIN
+ x := xValue;
+ y := yValue;
+ z := zValue;
+ size := size2D
+ END
+ END; //Vector2D
+
+ // Assume vector contains 'extra' homogeneous coordinate -- ignore it.
+ procedure NormalizeVector2D(var u: TVector);
+ var
+ lSum: double;
+ BEGIN
+ lSum := sqrt((u.x*u.x)+(u.y*u.y)+(u.z*u.z));
+ if lSum <> 0 then
+ u := Vector2D( u.x/lSum,
+ u.y/lSum,
+ u.z/lSum)
+ END; //NormalizeVector2D
+
+FUNCTION revMat (CONST Input:TMatrix): TMatrix;//Transpose Matrix
+var
+ i,j: integer;
+begin
+ result.size := Input.size;
+ for i := 1 to Input.size do
+ for j := 1 to Input.size do
+ result.matrix[i,j] := input.matrix[j,i];
+end;
+
+
+ FUNCTION VecMatMult (CONST u: TVector; CONST a: TMatrix): TVector;
+ VAR
+ i,k : TIndex;
+ temp: DOUBLE;
+ BEGIN
+ RESULT.size := a.size;
+ IF a.size = u.size
+ THEN BEGIN
+ FOR i := 1 TO a.size DO
+ BEGIN
+ temp := 0.0;
+ FOR k := 1 TO a.size DO
+ BEGIN
+ temp := temp + u.vector[k]*a.matrix[i,k];
+ END;
+ RESULT.vector[i] := Defuzz(temp)
+ END;
+ END
+ ELSE raise EMatrixError.Create('VecMatMult error')
+ END;//VecMatMult
+
+
+procedure PhilipsCorrectBvecs(var lDICOMdata:dicomdata; var lDTIra: TDTIRA; nVec: integer);
+//Test lIn.x := 0.499997615814209; lIn.y := 0.499997615814209; lIn.z := 0.707110166549683;
+//Philips DICOM data stored in patient (LPH) space, regardless of settings in Philips user interface
+//algorithm inspired by CATNAP http://godzilla.kennedykrieger.org/~jfarrell/software_web.htm
+//http://iacl.ece.jhu.edu/~bennett/catnap/catnap.shtml
+//0018,5100. patient orientation - 'HFS'
+//2001,100B Philips slice orientation (TRANSVERSAL, AXIAL, SAGITTAL)
+//2005,1071. Philips AP angulation : -8.74086
+//2005,1072. Philips RL angulation : -3.53147
+//2005,1073. Philips FH angulation -0.387372
+(* 3/2008: updated to correct for a bug in the Johns Hopkins code:
+% July 20, 2007 | I corrected a small bug with the rotation matrices for
+% slice angulation. I had multiplied 3 matrices in the incorrect order.
+
+% A colleague (Harsh Agarwal) pointed this out while aligning different
+% MRI contrasts using the angulation parameters and the transformation
+% matrices given in the Philips document.
+%I originally had Tang = Tfh*Tap*Trl
+% which is now Tang = Trl*Tap*Tfh;
+%I originally had rev_Tang = rev_Trl*rev_Tap*rev_Tfh;
+%which is now rev_Tang = rev_Tfh*rev_Tap*rev_Trl;
+% I double checked the Philips code and this seems to be correct now.
+% I also double checked the impact on fiber tracking. The fiber tracking
+% looks good in both instances (even though the gradient tables are
+% slightly different). If 2 angulation values are zero (i.e. [AP,FH,RL]
+=
+% [0,0,20], then the old and new equations give the same result. Only
+if
+% two or more elements are non zero is the result different. I did some
+% testing with very large angulations of 20 degrees [20,20,0], [20,0,20]
+
+% and [0,20,20]and found that the fiber tracking results were almost
+% indistinguishable. THIS FIX ONLY affects yes overplus and
+% user-defined gradient tables. No overplus tables are not subject to
+% slice angulation changes
+*)
+
+var
+ lIn,lOut: TVector;
+ ltpp,lrev_tpp,ltpom,lrev_tpom,ltpo,lrev_tpo,ltrl,ltap,ltfh,
+ lmtemp1,lmtemp2 ,ltang,lrev_tang,
+ lrev_trl, lrev_tap, lrev_tfh,
+ lrev_tsom,ldtiextra: TMatrix;
+ lI: Integer;
+ lap,lfh,lrl: double;
+begin
+
+ if nVec < 1 then exit;
+ //require HFS - head first supine. See Catnap for alternate body orientations
+ // and (lDicomData.PatientPos[1] = 'H') and (lDicomData.PatientPos[2] = 'F') and (lDicomData.PatientPos[3] = 'S') then
+ if (length(lDicomData.PatientPos) < 3) then begin
+ //HFS = head-first supine
+ dcmMsg('DTI vector error: Position is not head first supine');
+ exit;
+ end;
+ if (lDicomData.PatientPos[1] = 'F') and (lDicomData.PatientPos[2] = 'F') then begin//strcmpi(patient_position,'ff')
+ ltpp := Matrix2D (0,-1,0, -1,0,0, 0,0,1);
+ //rev_Tpp = [0,-1,0;-1,0,0;0,0,-1];
+ end else if (lDicomData.PatientPos[1] = 'H') and (lDicomData.PatientPos[2] = 'F') then begin//strcmpi(patient_position,'hf')
+ ltpp := Matrix2D (0,1,0,-1,0,0, 0,0,-1);
+ //rev_Tpp = [0,-1,0;1,0,0;0,0,-1];
+ end else begin
+ dcmMsg('DTI vector error: images must be HF or FF (head or feet first) '+lDicomData.PatientPos);
+ exit;
+ end;
+ lrev_tpp := revMat(ltpp);
+
+(* http://www.dabsoft.ch/dicom/3/C.7.3.1.1.2/
+see matlab code http://godzilla.kennedykrieger.org/~jfarrell/software_web.htm#PARtoNRRD
+HFP = Head First-Prone
+HFS = Head First-Supine
+HFDR = Head First-Decubitus Right
+HFDL = Head First-Decubitus Left
+FFDR = Feet First-Decubitus Right
+FFDL = Feet First-Decubitus Left
+FFP = Feet First-Prone
+FFS = Feet First-Supine
+*)
+ if lDicomData.PatientPos[3] = 'S' then begin//supine
+ ltpo := Matrix2D (1,0,0, 0,1,0, 0,0,1);
+ //rev_Tpo = [1,0,0;0,1,0;0,0,1];
+ end else if lDicomData.PatientPos[3] = 'P' then begin //prone
+ ltpo := Matrix2D (-1,0,0, 0,-1,0, 0,0,1);
+ //rev_Tpo = [-1,0,0;0,-1,0;0,0,1];
+ end else if (length(lDicomData.PatientPos) > 3) and (lDicomData.PatientPos[3] = 'D') and (lDicomData.PatientPos[4] = 'R') then begin //rd
+ ltpo := Matrix2D (0,-1,0, 1,0,0, 0,0,1);
+ //rev_Tpo = [0,1,0;-1,0,0;0,0,1];
+ end else if (length(lDicomData.PatientPos) > 3) and (lDicomData.PatientPos[3] = 'D') and (lDicomData.PatientPos[4] = 'L') then begin //ld
+ ltpo := Matrix2D (0,1,0, -1,0,0, 0,0,1);
+ //rev_Tpo = [0,-1,0;1,0,0;0,0,1];
+ end else begin
+ dcmMsg('DTI vector error: Position is not HFS,HFP,HFDR,HFDL,FFS,FFP,FFDR, or FFDL: '+lDicomData.PatientPos);
+ exit;
+ end;
+ lrev_tpo := revMat(ltpo);
+ dcmMsg('Reorienting vectors for patient position ('+lDicomData.PatientPos+'). Please validate if you conduct DTI processing.');
+ (*
+ //Assume supine
+ ltpo := Matrix2D (1,0,0, 0,1,0, 0,0,1 );
+ lrev_tpo := revMat(ltpo);
+ //Assume head first
+ ltpp := Matrix2D (0,1,0, -1,0,0, 0,0,-1);
+ lrev_tpp := revMat(ltpp); *)
+ ltpom := MultiplyMatrices( ltpo, ltpp);
+ lrev_tpom := MultiplyMatrices( lrev_tpp,lrev_tpo );
+ lap := lDicomData.AngulationAP * PI /180;
+ lfh := lDicomData.AngulationFH * PI /180;
+ lrl := lDicomData.AngulationRL * PI /180;
+ {$IFDEF VERBOSE_BVEC}
+ msg('ap/fh/rl'+kTab+floattostr(lDicomData.AngulationAP)+kTab+floattostr(lDicomData.AngulationFH)+kTab+floattostr(lDicomData.AngulationRL));
+ for lI := 1 to nVec do
+ msg(inttostr(lI)+ kTab+floattostr(lDTIra[lI].bval)+kTab+floattostr(lDTIra[lI].v1)+kTab+floattostr(lDTIra[lI].v2)+kTab+floattostr(lDTIra[lI].v3));
+
+ {$ENDIF}
+ //lAP:=-0.152557; lFH:=-0.0616358; lRL := -0.00676092;
+
+ ltrl := Matrix2D (1,0,0, 0,cos(lrl),-sin(lrl), 0,sin(lrl),cos(lrl));
+ ltap := Matrix2D (cos(lap),0,sin(lap), 0,1,0, -sin(lap),0,cos(lap));
+ ltfh := Matrix2D (cos(lfh),-sin(lfh),0, sin(lfh),cos(lfh),0, 0,0,1);
+ lrev_trl := revMat(ltrl);
+ lrev_tap := revMat(ltap);
+ lrev_tfh := revMat(ltfh);
+ lmtemp1 := MultiplyMatrices( ltrl, ltap );
+ ltang := MultiplyMatrices( lmtemp1, ltfh );
+ lmtemp1 := MultiplyMatrices( lrev_tfh, lrev_tap );
+ lrev_tang := MultiplyMatrices( lmtemp1, lrev_trl );
+
+ if (lDicomData.PhilipsSliceOrient[1] = 'S') then //SAGITTAL
+ lrev_tsom := Matrix2D (0,0,1, 0,-1,0, -1,0,0 )
+ else if (lDicomData.PhilipsSliceOrient[1] = 'C') then //CORONAL
+ lrev_tsom := Matrix2D (0,0,1, -1,0,0, 0,1,0 )
+ else //TRANSVERSAL = AXIAL
+ lrev_tsom := Matrix2D (0,-1,0, -1,0,0, 0,0,1 );
+ ldtiextra := Matrix2D (0,-1,0, -1,0,0, 0,0,1 );
+ lmtemp2 := MultiplyMatrices( ldtiextra, lrev_tsom );
+ lmtemp1 := MultiplyMatrices (lmtemp2, lrev_tang);
+
+ for lI := 1 to nVec do begin
+
+ if (lDTIra[lI].bval <= 0) or ((lDTIra[lI].v1 = 0) and (lDTIra[lI].v2 = 0) and (lDTIra[lI].v3 = 0)) then begin
+ lDTIra[lI].v1 := 0;
+ lDTIra[lI].v2 := 0;
+ lDTIra[lI].v3 := 0;
+ end else begin
+ //lIn := Vector2D(0.7071, -0.7071, -0.0000);
+ lIn := Vector2D(-lDTIra[lI].v1,-lDTIra[lI].v2,-lDTIra[lI].v3);
+ NormalizeVector2D(lIn);
+ lout := VecMatMult (lin,lmtemp1);
+ NormalizeVector(lout);
+ lDTIra[lI].v1 := lOut.x;
+ if lOut.y = 0 then
+ lDTIra[lI].v2 := lOut.y //people dislike seeing -0
+ else
+ lDTIra[lI].v2 := -lOut.y; //flip Y component
+ lDTIra[lI].v3 := lOut.z;
+ end;
+ end; //for each vector
+end;
+
+end.
+
diff --git a/dcm2nii/pref_form.dfm b/dcm2nii/pref_form.dfm
old mode 100644
new mode 100755
diff --git a/dcm2nii/pref_form.lfm b/dcm2nii/pref_form.lfm
old mode 100644
new mode 100755
diff --git a/dcm2nii/pref_form.lrs b/dcm2nii/pref_form.lrs
old mode 100644
new mode 100755
diff --git a/dcm2nii/pref_form.pas b/dcm2nii/pref_form.pas
old mode 100644
new mode 100755
index e760b4d..503dc7f
--- a/dcm2nii/pref_form.pas
+++ b/dcm2nii/pref_form.pas
@@ -5,7 +5,9 @@ interface
uses
{$IFDEF FPC}LResources,{$ENDIF}
- {$IFDEF UNIX}Process, {$ELSE}ShellApi, Windows,{$ENDIF} Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ {$IFDEF UNIX}Process, {$ELSE}ShellApi, Windows,{$ENDIF}
+//Messages,
+SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,filename,define_types,dicomtypes,prefs, Spin, Buttons;
type
diff --git a/dcm2nii/prefs.pas b/dcm2nii/prefs.pas
old mode 100644
new mode 100755
index b8ef29d..36682ff
--- a/dcm2nii/prefs.pas
+++ b/dcm2nii/prefs.pas
@@ -10,7 +10,7 @@ uses
{$ELSE}
SelectFolder,
{$ENDIF}
- inifiles, define_types,SysUtils, userdir, dialogsx;
+ inifiles, define_types,SysUtils, userdir, dialogsx, dialogs_msg;
type
TPrefs = record
@@ -18,12 +18,13 @@ type
SingleNIIFile,Gzip,SPM2,VOI,enablereorient,createoutputfolder,
AppendDate,AppendAcqSeries,AppendProtocolName,AppendPatientName,AppendFilename,
everyfile,fourD,Swizzle4D,Stack3DImagesWithSameAcqNum,customRename,
- CollapseFolders,AutoCrop, UseGE_0021_104F, PhilipsPrecise,Verbose,DebugMode,DebugMode2,UntestedFeatures,UINT16toFLOAT32: boolean;
+ CollapseFolders,AutoCrop, UseGE_0021_104F, PhilipsPrecise,Verbose,
+ DebugMode,DebugMode2,UntestedFeatures,UINT16toFLOAT32: boolean;
- SiemensDTIUse0019If00181020atleast,
+ BeginClip, LastClip,SiemensDTIUse0019If00181020atleast,
SiemensDTINoAngulationCorrectionIf00181020atleast,
SiemensDTIStackIf00181020atleast,
- OutDirMode, MinReorientMatrix,MaxReorientMatrix,RecursiveFolderDepth
+ OutDirMode, MinReorientMatrix,MaxReorientMatrix,RecursiveFolderDepth,usePigz
: integer;
OutDir, BackupDir,NameAppend: string;
end;
@@ -141,6 +142,9 @@ begin
BackupDir := '';
WritePrefsOnQuit := true;
UINT16toFLOAT32 := true;
+ BeginClip := 0;
+ LastClip := 0;
+ usePigz := 0;
end;
end;
@@ -192,13 +196,13 @@ begin
exit;
{$IFDEF UNIX} //Uses BaseUnix;
if (lRead) and (fpAccess (lFilename,R_OK)<>0) then begin//ensure user has read-access to prefs file...
- msg('Unable to load preferences: no write access for '+lFilename);
+ dcmMsg('Unable to load preferences: no write access for '+lFilename);
exit;
end;
{$ENDIF}
if (lRead) then begin
Filemode := 0; //Readonly
- msg('reading preferences file '+lFilename);
+ dcmMsg('reading preferences file '+lFilename);
end else
Filemode := 2; //Read-Write
@@ -233,10 +237,15 @@ begin
IniBool(lRead,lIniFile,'Stack3DImagesWithSameAcqNum',lPrefs.Stack3DImagesWithSameAcqNum);
IniBool(lRead,lIniFile,'Swizzle4D',lPrefs.Swizzle4D);
IniBool(lRead,lIniFile,'UseGE_0021_104F',lPrefs.UseGE_0021_104F);
+
+ IniInt(lRead,lIniFile,'BeginClip',lPrefs.BeginClip);
+ IniInt(lRead,lIniFile,'LastClip',lPrefs.LastClip);
+ IniInt(lRead,lIniFile,'usePigz',lPrefs.usePigz);
IniInt(lRead,lIniFile,'MaxReorientMatrix',lPrefs.MaxReorientMatrix);
IniInt(lRead,lIniFile,'MinReorientMatrix',lPrefs.MinReorientMatrix);
IniInt(lRead,lIniFile,'RecursiveFolderDepth',lPrefs.RecursiveFolderDepth);
IniInt(lRead,lIniFile,'OutDirMode',lPrefs.OutDirMode);
+
IniInt(lRead,lIniFile,'SiemensDTIUse0019If00181020atleast',lPrefs.SiemensDTIUse0019If00181020atleast);
IniInt(lRead,lIniFile,'SiemensDTINoAngulationCorrectionIf00181020atleast',lPrefs.SiemensDTINoAngulationCorrectionIf00181020atleast);
IniInt(lRead,lIniFile,'SiemensDTIStackIf00181020atleast',lPrefs.SiemensDTIStackIf00181020atleast);
diff --git a/dcm2nii/readint.dfm b/dcm2nii/readint.dfm
old mode 100644
new mode 100755
diff --git a/dcm2nii/readint.lrs b/dcm2nii/readint.lrs
old mode 100644
new mode 100755
diff --git a/dcm2nii/readint.pas b/dcm2nii/readint.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/sortdicom.pas b/dcm2nii/sortdicom.pas
old mode 100644
new mode 100755
index 39fdb7e..04cb713
--- a/dcm2nii/sortdicom.pas
+++ b/dcm2nii/sortdicom.pas
@@ -4,7 +4,7 @@ unit sortdicom;
interface
uses
- SysUtils,define_types,classes,dicom,dicomtypes,convert,dicomfast,prefs,userdir;
+ SysUtils,define_types,classes,dicom,dicomtypes,convert,dicomfast,prefs,userdir,dialogs_msg;
function LoadFileList (var lInFilename, lOutDirname: string; var lPrefs: TPrefs):boolean;
@@ -70,7 +70,7 @@ end;
procedure ReportError (l,i: integer; var lDICOMra: TDICOMrap);
begin
//Msg('Error: these files have the same index '+ lDICOMra^[lPositionRA^[l]].Filename+' = '+lDICOMra^[lPositionRA^[i]].Filename);
- Msg('Error: these files have the same index '+ DICOMstr(l,lDICOMra)+' = '+DICOMstr(i,lDICOMra));
+ dcmMsg('Error: these files have the same index '+ DICOMstr(l,lDICOMra)+' = '+DICOMstr(i,lDICOMra));
end;
procedure ShellSortDCM (var Items: integer; var lDICOMra: TDICOMrap; var lRepeatedValues: boolean);
@@ -190,7 +190,7 @@ begin
if (ld1.Vers0018_1020 >= lPrefs.SiemensDTIStackIf00181020atleast) then
lStack := true; //recent Siemens scanners will have different NEx saved as different images and different directions saved as different images
if (not lStack) and (ld1.acquNum <> ld2.acquNum) then begin
- msg('Images not stacked because acquisition number changes. If you want to stack these images set Stack3DImagesWithSameAcqNum=1 in your ini file.');
+ dcmMsg('Images not stacked because acquisition number changes. If you want to stack these images set Stack3DImagesWithSameAcqNum=1 in your ini file.');
exit;
end;
(*if (ld1.PatientIDInt = ld2.PatientIDInt) and(ld1.SeriesNum = ld2.SeriesNum) and (ld1.acquNum = ld2.acquNum)
@@ -203,8 +203,10 @@ begin
if abs (ld1.orient[lI] - ld2.orient[lI]) > kTolerance then
exit;
end;
- if (ld1.IntenScale <> ld2.IntenScale) or (ld1.IntenIntercept <> ld2.IntenIntercept) then //if previous file is a 4D image, we should convert it separately
+ (*if (ld1.IntenScale <> ld2.IntenScale) or (ld1.IntenIntercept <> ld2.IntenIntercept) then begin//if previous file is a 4D image, we should convert it separately
+ msg('Warning: unable to stack images because intensity scaling varies. Names: '+ld1.Filename+' '+ld2.filename+' Slopes: '+floattostr(ld1.IntenScale)+' '+floattostr(ld2.IntenScale)+' Intercepts: '+floattostr(ld1.IntenIntercept)+' '+floattostr(ld2.IntenIntercept));
exit;
+ end; *)
result := true;
end;
@@ -248,9 +250,9 @@ begin
lFilename := lFilePath+lSearchRec.Name;
if (lFilename = '') or (length (lFilename) > 255) then begin
- Msg('Unable to convert images where the file path and name exceed 255 characters.');
- Msg('Solution: put images in a folder with a shorter path.');
- Msg(lFilename);
+ dcmMsg('Unable to convert images where the file path and name exceed 255 characters.');
+ dcmMsg('Solution: put images in a folder with a shorter path.');
+ dcmMsg(lFilename);
end else if (lFilename <> lPrev) then begin
lStringList.Add(lFileName);
//if lFilename = lPrev then
@@ -319,7 +321,7 @@ function LoadFileListInner (var lOutDirname: string; var lPrefs: TPrefs; var lSt
var
lPrevDICOM,lDicomData: DicomData;
lDICOMra: TDICOMrap;
- lRepeatLocations,lStartImg,lValidItems, lItems,lInc: integer;
+ lnumEchos,lRepeatLocations,lStartImg,lValidItems, lItems,lInc: integer;
lError,lRepeatedValues,lHdrOK,lImgOK: boolean;
lFilename,lDynStr: string;
begin
@@ -330,7 +332,7 @@ begin
exit;
end;
Filemode := 2;
- Msg('Validating '+inttostr(lItems)+' potential DICOM images.');
+ dcmMsg('Validating '+inttostr(lItems)+' potential DICOM images.');
//START ANON
if lPrefs.AnonymizeSourceDICOM then begin
@@ -356,58 +358,67 @@ begin
end; //for each item
lStringList.Free;
if lValidItems = 0 then begin
- Msg('Unable to find any DICOM files in the path '+lFileName);
+ dcmMsg('Unable to find any DICOM files in the path '+lFileName);
freemem(lDICOMra);
exit;
end;
- Msg('Found '+inttostr(lValidItems)+' DICOM images.');
+ dcmMsg('Found '+inttostr(lValidItems)+' DICOM images.');
ShellSortDCM (lValidItems,lDICOMra,lRepeatedValues);
if lRepeatedValues then begin //separate into series
- Msg('Warning: repeated image indexes in the path '+lFileName);
+ dcmMsg('Warning: repeated image indexes in the path '+lFileName);
//freemem(lDICOMra);
//exit;
end;
if lPrefs.DebugMode then begin
for lInc := 1 to lValidItems do
- Msg( DICOMstr(lInc,lDICOMra));
+ dcmMsg( DICOMstr(lInc,lDICOMra));
exit;
end;
lStartImg := 1;
lRepeatLocations := 0;
+ lnumEchos := 1;
lPrevDICOM := lDICOMra^[1];
for lInc := 1 to lValidItems do begin
//msg(lDICOMra^[lInc].Filename+','+floattostr(lDICOMra^[lInc].PatientPosX)+','+floattostr(lDICOMra^[lInc].PatientPosY)+','+floattostr(lDICOMra^[lInc].PatientPosZ) );
if (lInc > 1) and (not SameIDSeriesAcqXYZ (lPrevDICOM ,lDICOMra^[lInc],lPrefs)) then begin
//SameIDSeriesAcqXYZ2 (lPrevDICOM ,lDICOMra^[lInc]);
- Msg('Converting '+inttostr(lInc-1)+'/'+inttostr(lValidItems)+' '+inttostr(lRepeatLocations));
+ if (lRepeatLocations < 2) and (lnumEchos > 1) then
+ lRepeatLocations := lnumEchos;
+ dcmMsg('Converting '+inttostr(lInc-1)+'/'+inttostr(lValidItems)+' volumes: '+inttostr(lRepeatLocations));
result := Dicom2NII(lDICOMra,lStartImg,lInc-1,lOutDirname,lPrefs,lRepeatLocations);
if not result then
lError := true;
lPrevDICOM := lDICOMra^[lInc];
lStartImg := lInc;
lRepeatLocations := 1;
- //end else if (lDICOMra^[lInc].location = lPrevDICOM.Location) then begin
- end else if (lDICOMra^[lInc].PatientPosX = lPrevDICOM.PatientPosX) and
+ end else if //(lDICOMra^[lInc].location = lPrevDICOM.Location) and
+ (lDICOMra^[lInc].PatientPosX = lPrevDICOM.PatientPosX) and
(lDICOMra^[lInc].PatientPosY = lPrevDICOM.PatientPosY) and
(lDICOMra^[lInc].PatientPosZ = lPrevDICOM.PatientPosZ) then begin
- //fx(lRepeatLocations,lDICOMra^[lInc].location);
+ //fx(lDICOMra^[lInc].PatientPosZ , lPrevDICOM.PatientPosZ );
+ //fx(666,lRepeatLocations,lDICOMra^[lInc].location, lPrevDICOM.Location);
inc(lRepeatLocations);
- end;
+ end else if (lInc > 1) and ( (lDICOMra^[lInc].AcquNum) > (lDICOMra^[lInc-1].AcquNum+999)) then //we increment acquisition number by 1000 to denote new echo
+ inc(lnumEchos);
end; //for each valid
+ if (lRepeatLocations < 2) and (lnumEchos > 1) then
+ lRepeatLocations := lnumEchos;
+ //fx(lPrevDICOM.PatientPosX, lPrevDICOM.PatientPosY, lPrevDICOM.PatientPosZ );
//Msg( inttostr(lValidItems-lStartImg+1)+' '+ inttostr(lRepeatLocations));
+ //fx(lRepeatLocations);
if (((lValidItems-lStartImg+1) mod lRepeatLocations) <> 0) then begin
- Msg('*Warning: Number of images in series ('+inttostr(lValidItems-lStartImg+1)+') not divisible by number of volumes ('+inttostr(lRepeatLocations)+')');
- Msg('* Perhaps the selected folder only has some of the images');
+ dcmMsg('*Warning: Number of images in series ('+inttostr(lValidItems-lStartImg+1)+') not divisible by number of volumes ('+inttostr(lRepeatLocations)+')');
+ dcmMsg('* Perhaps the selected folder only has some of the images');
PartialAcquisitionError;
end;
if (lPrevDICOM.SlicesPer3DVol > 0) and (not lPrevDICOM.file4D) and ((lValidItems div lRepeatLocations) <> lPrevDICOM.SlicesPer3DVol) then begin
- Msg('Warning: Number of slices per volume ('+inttostr((lValidItems div lRepeatLocations))+')appears different than reported in DICOM header ('+inttostr(lPrevDICOM.SlicesPer3DVol)+')');
- Msg(' Perhaps the selected folder only has some of the images');
+ dcmMsg('Warning: Number of slices per volume ('+inttostr((lValidItems div lRepeatLocations))+')appears different than reported in DICOM header ('+inttostr(lPrevDICOM.SlicesPer3DVol)+')');
+ dcmMsg(' Perhaps the selected folder only has some of the images');
end;
- Msg('Converting '+inttostr(lValidItems)+'/'+inttostr(lValidItems)+' '+inttostr(lRepeatLocations));
+ dcmMsg('Converting '+inttostr(lValidItems)+'/'+inttostr(lValidItems)+' volumes: '+inttostr(lRepeatLocations));
Dicom2NII(lDICOMra,lStartImg,lValidItems,lOutDirname,lPrefs,lRepeatLocations);
if lError then
result := false //at least one error
@@ -453,13 +464,13 @@ begin
if not(DirExists(lOutDirName)) then
lOutDirName := UserDataFolder;
if lPrefs.CollapseFolders then begin
- msg('Data will be exported to '+lOutDirname);
+ dcmMsg('Data will be exported to '+lOutDirname);
ProcessRecursiveFolder (lInFilename, lStringList, 0, lPrefs);
result := true;
end else
result := ProcessSingleFolderDCM (lInFilename, lStringList);
if (not result) or (lStringList.Count < 1) then begin
- Msg('+Unable to find any images in the path '+lInFilename);
+ dcmMsg('+Unable to find any images in the path '+lInFilename);
lStringList.Free;
end else
result := LoadFileListInner (lOutDirName, lPrefs,lStringList)
@@ -481,8 +492,8 @@ begin
if ((lParamNum) < ParamCount) then
for lI := (lParamNum+1) to ParamCount do
lStringList.Add(Paramstr(lI));
- msg('Only converting files explicitly specified');
+ dcmMsg('Only converting files explicitly specified');
result := LoadFileListInner (lOutDirName, lPrefs,lStringList)
end;
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/untar.pas b/dcm2nii/untar.pas
old mode 100644
new mode 100755
index f0c994b..bb2a9a1
--- a/dcm2nii/untar.pas
+++ b/dcm2nii/untar.pas
@@ -8,7 +8,7 @@ gzio2,
{$ELSE}
gziod,
{$ENDIF}
-define_types,SysUtils,LibTar,
+define_types,SysUtils,LibTar, dialogs_msg,
gzio,dialogsx,prefs,sortdicom,classes;
function DeTGZ (lFilename: string; lPrefs: TPrefs): boolean;
@@ -324,7 +324,7 @@ begin
lOutPath := lPath+lName;
if direxists(lOutPath) then begin
- Msg('Unable to extract TGZ file - folder exists '+lOutpath);
+ dcmMsg('Unable to extract TGZ file - folder exists '+lOutpath);
exit;
end;
MkDir(lOutPath);
@@ -346,12 +346,12 @@ begin
lTempDir := lPrefs.BackupDir;
if lTempDir[length(lTempDir)] <> pathdelim then
lTempDir := lTempDir + pathdelim;
- Msg('Copying to backup folder named '+lTempDir);
+ dcmMsg('Copying to backup folder named '+lTempDir);
CopyDir(lOutPath+pathdelim, lTempDir);
- Msg('Backup completed');
+ dcmMsg('Backup completed');
end;
//Extract (lFilename,true);
result := true;
end;
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/userdir.pas b/dcm2nii/userdir.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/windowsxp.res b/dcm2nii/windowsxp.res
old mode 100644
new mode 100755
diff --git a/dcm2nii/zconf.inc b/dcm2nii/zconf.inc
old mode 100644
new mode 100755
diff --git a/dcm2nii/LibTar.pas b/dcm2nii_prePARRECDTI/LibTar.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/LibTar.pas
copy to dcm2nii_prePARRECDTI/LibTar.pas
diff --git a/dcm2nii/PARtoNRRD_Philips_RelX.zip b/dcm2nii_prePARRECDTI/PARtoNRRD_Philips_RelX.zip
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/PARtoNRRD_Philips_RelX.zip
copy to dcm2nii_prePARRECDTI/PARtoNRRD_Philips_RelX.zip
diff --git a/dcm2nii/SelectFolder.pas b/dcm2nii_prePARRECDTI/SelectFolder.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/SelectFolder.pas
copy to dcm2nii_prePARRECDTI/SelectFolder.pas
diff --git a/dcm2nii/convert.pas b/dcm2nii_prePARRECDTI/convert.pas
old mode 100644
new mode 100755
similarity index 80%
copy from dcm2nii/convert.pas
copy to dcm2nii_prePARRECDTI/convert.pas
index 65c68ec..f6095da
--- a/dcm2nii/convert.pas
+++ b/dcm2nii_prePARRECDTI/convert.pas
@@ -583,7 +583,6 @@ var
lSlice,l4DBytes,lSliceBytes,lZo,lTo,lZmax,lTmax:integer;
lTempBuffer: ByteP;
begin
-
if lDicomData.XYZdim[4] < 2 then
exit;
if MultiOrder(lDICOMdata) <> 0 then begin
@@ -1160,55 +1159,158 @@ begin
+inttostr(Pos));
end;
+function ImageScalingOrIntensityVaries(var lDICOMra: TDICOMrap; lFirstDICOM, lLastDICOM: integer): boolean;
+var
+ lIndex: integer;
+begin
+ result := false;
+ if (lFirstDICOM >= lLastDICOM) then exit; //only one image
+ result := true;
+ for lIndex := (lFirstDICOM +1) to lLastDICOM do begin
+ if lDICOMra^[lIndex].IntenIntercept <> lDICOMra^[lFirstDICOM].IntenIntercept then
+ exit; //1492
+ if lDICOMra^[lIndex].IntenScale <> lDICOMra^[lFirstDICOM].IntenScale then
+ exit; //1492
+ if lDICOMra^[lIndex].Allocbits_per_pixel <> lDICOMra^[lFirstDICOM].Allocbits_per_pixel then
+ exit;
+ end;
+ result := false;
+end;
+procedure MakeFloat (var lBuffer: bytep; var lDicomData: DICOMdata; var lSliceBytesOut: integer);
+//data is saved as RGBRGBRGB - convert to RRRR GGGG BBBB
+var
+ lRA: bytep;
+ lPix,lnPix,lnBytes: integer;
+ l8i : byteP;
+ l16ui : WordP;
+ l16i: SmallIntP;
+ l32i: LongIntP;
+ l32fo, l32f: SingleP;
+ lByteSwap: boolean;
+begin
+ if (lDicomData.XYZdim[1] < 1) or (lDicomData.XYZdim[2] < 1) or (lDicomData.XYZdim[3] < 1) then exit;
+ Msg(' Converting data to 32-bit float to correct for differences slope/intercept/precision: '+chr(9)+realtostr(lDicomData.IntenScale,8)+chr(9)+realtostr(lDicomData.IntenIntercept,8)+chr(9)+inttostr(lDicomData.Allocbits_per_pixel));
+ {$IFDEF ENDIAN_BIG}
+ lByteSwap := odd(lDICOMdata.little_endian);
+ {$ELSE}
+ lByteSwap := not odd(lDICOMdata.little_endian);
+ {$ENDIF}
+ lnPix := lDicomData.XYZdim[1]*lDicomData.XYZdim[2]*lDicomData.XYZdim[3];
+ //msg(' '+inttostr(lDicomData.XYZdim[1])+' '+inttostr(lDicomData.XYZdim[2])+' '+inttostr(lDicomData.XYZdim[3]) );
+ lnBytes := lnPix *trunc(((lDicomData.Allocbits_per_pixel)+7)/8);
+ GetMem(lRA,lnBytes );
+ Move(lBuffer^,lRA^,lnBytes); //move(src,dest,sz)
+ Freemem(lBuffer);
+ GetMem(lBuffer,lnPix * 4); //save as 32 bit float: 4 bytes per pixel
+ l32fo := SingleP(@lBuffer^[1]);
+ if lDicomData.Allocbits_per_pixel = 8 then begin //8bit - byte swapping is not a problem...
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := lRA^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //8bit
+ //next 16 bit
+ if (lDicomData.Allocbits_per_pixel = 16) and (lByteSwap) then begin //UNSWAP 16bit
+ l16ui := WordP(@lRA^[1]);
+
+ for lPix := 1 to lnPix do
+ l16ui^[lPix] := swap(l16ui^[lPix]);
+ end; //UNSWAP 16bit
+ if (lDicomData.Allocbits_per_pixel = 16) and (not lDicomData.SignedData) then begin //16bit UNSIGNED
+
+ l16ui := WordP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := l16ui^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //16bit UNSIGNED
+ if (lDicomData.Allocbits_per_pixel = 16) and (lDicomData.SignedData) then begin //16bit SIGNED
+ l16i := SmallIntP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := l16i^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //16bit SIGNED
+ //NEXT 32bit
+ if (lDicomData.Allocbits_per_pixel = 32) and (not lDicomData.FloatData) then begin //UNSWAP 32bit
+ l32i := LongIntP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ pswap4i(l32i^[lPix]);
+ end; //UNSWAP 32bit
+ if (lDicomData.Allocbits_per_pixel = 32) and (not lDicomData.FloatData) then begin //32bit INTEGER
+ l32i := LongIntP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := l32i^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //32bit INTEGER
+ if (lDicomData.Allocbits_per_pixel = 32) and ( lDicomData.FloatData) then begin //32bit FLOAT
+ l32f := SingleP(@lRA^[1]);
+ for lPix := 1 to lnPix do
+ l32fo^[lPix] := l32f^[lPix]*lDicomData.IntenScale + lDicomData.IntenIntercept;
+ end; //32bit FLOAT
+ Freemem(lRA);
+ lDicomData.Allocbits_per_pixel := 32;
+ lDicomData.FloatData := true;
+ lDicomData.IntenScale := 1;
+ lDicomData.IntenIntercept := 0;
+ lSliceBytesOut := lnPix * 4;
+end;
function Dicom2NII(var lDICOMra: TDICOMrap; lFirstDICOM, lLastDICOM: integer; var lOutDirOrig: string; var lPrefs: TPrefs; lVols: integer): boolean;
var
+ lVolBytesOut, lVolOffset, lVolOffsetInit : Int64; //2013: 64-bit support
+ //lSliceBytesOut, lvolBytesOut, lvolOffset, lvolOffsetInit: integer;
lPref: TPrefs;
lDTIra: TDTIra;
- lDTIdir,lRGB: integer;
lVolGb : double;
- lAllocSLiceSz,
- lStart,lEnd,lmosX,lmosY,lIndex,lSecondDICOM,lSeries,lnSeries,lSliceBytes,
- lBaseBitDepth,lMosaicSlices,
- lSliceBytesOut,lvolOffset,lvolOffsetInit,lvolBytesOut: integer;
- lBaseIntenScale,lBaseIntenIntercept,lDX: single;
+ lSliceBytesOut,
+ lAllocSLiceSz, lDTIdir,lRGB,
+ lStart,lEnd,lmosX,lmosY,lIndex,lSecondDICOM,lSeries,lnSeries,lSliceBytes,lMosaicSlices:integer;
+ //lBaseBitDepth,
+
+ //lBaseIntenScale,lBaseIntenIntercept,
+ lDX: single;
//lDynStr,
lDicomImgName,lOutHdrName,lOutImgName,lOutImgNameGZ,lOutDir,lOutDTIname:string;
lDICOMData:dicomdata;
- lFlip,lIntenScaleVaries,lInterleaved,lFlipMosaic,lVolSave,lByteSwap : boolean;
+ lReadOK,lFlip,lIntenScaleVaries,lInterleaved,lFlipMosaic,lVolSave,lByteSwap : boolean;
lAHdr: TNIFTIhdr;
lTextF: TextFile;
lOutF,lInF: File;
lvBuffer,lsBuffer: bytep;
begin
- result := false;
if lPrefs.DebugMode2 then begin
+
Msg( DICOMstr(1,lDICOMra,OutputFilename(lDicomImgName,lDICOMra^[lFirstDICOM],lPref)));
+ Msg(inttostr(lDICOMdata.XYZdim[1])+'x'+inttostr(lDICOMdata.XYZdim[2])+'x'+inttostr(lDICOMdata.XYZdim[3])+'x'+inttostr(lDICOMdata.XYZdim[4]));
result := true;
exit;
- end;
+ end;
+ result := false;
+
lPref := lPrefs;
CorrectPrefs(lPref);
lmosX := 1;
lmosY := 1;
lSecondDICOM := lFirstDICOM+1;
- lIntenScaleVaries := false;
+
lInterleaved := false;
lnSeries := (lLastDICOM+1) -lFirstDICOM; //e.g. first=10, last=10 means 1 image
if lnSeries < 1 then
- exit;
+ exit;
//next if magnitude and phase maps are saved in the same 4D file, extract to separate files...
if (lDICOMra^[lFirstDICOM].file4D) and (MultiOrder(lDICOMra^[lFirstDICOM]) > 0) then
lPref.fourD := false;
lDicomImgName := lDICOMra^[lFirstDICOM].Filename;
lDicomData := lDICOMra^[lFirstDICOM];
+
+
if (lDicomData.SamplesPerPixel = 3) then begin
Msg('Warning: RGB to NIfTI conversion poorly tested: '+lDicomImgName);
end;
{$IFDEF ENDIAN_BIG}
lByteSwap := odd(lDICOMdata.little_endian);
+ (*if (lDicomData.CSAImageHeaderInfoPos > 0) or (lDicomData.CSAImageHeaderInfoSz >0) then begin
+ lDicomData.CSAImageHeaderInfoPos := 0;
+ lDicomData.CSAImageHeaderInfoSz := 0;
+ Msg('Warning: Modern Siemens CSA headers not supported on obsolete big-endian PowerPC computers. DTI vectors and mosaic slice positioning may be inaccurate.');
+ end; *)
+
{$ELSE}
lByteSwap := not odd(lDICOMdata.little_endian);
{$ENDIF}
@@ -1227,7 +1329,9 @@ begin
Msg('Unable to find output directory '+lOutDir);
lOutDir := ExtractFileDirWithPathDelim2(lDicomImgName)
end; //else directory exists
- //lOutHdrName :=lOutDir+OutputFilename(lDicomImgName,lDicomData,lPrefs.AppendDate,lPrefs.AppendAcqSeries,lPrefs.AppendProtocolName,lPrefs.AppendPatientName,lPrefs.FourD,lPrefs.AppendFilename)+'.hdr';
+
+
+ //lOutHdrName :=lOutDir+OutputFilename(lDicomImgName,lDicomData,lPrefs.AppendDate,lPrefs.AppendAcqSeries,lPrefs.AppendProtocolName,lPrefs.AppendPatientName,lPrefs.FourD,lPrefs.AppendFilename)+'.hdr';
lOutHdrName :=lOutDir+OutputFilename(lDicomImgName,lDicomData,lPref)+'.hdr';
lOutImgName :=changefileext(lOutHdrName,'.img');
if lPref.SingleNIIFile then begin
@@ -1251,6 +1355,14 @@ begin
end;
Msg(extractfilename(lDicomImgName)+'->'+extractfilename(lOutImgName));
DICOM2AnzHdr(lAHdr,lPref.Anonymize,lDicomImgName,lDICOMdata);
+ if lPrefs.DebugMode2 then begin
+ Msg(inttostr(lDICOMdata.SlicesPer3DVol )+' '+inttostr(lVols)+' '+inttostr(lnSeries));
+ Msg(inttostr(lDICOMdata.XYZdim[1])+'x'+inttostr(lDICOMdata.XYZdim[2])+'x'+inttostr(lDICOMdata.XYZdim[3])+'x'+inttostr(lDICOMdata.XYZdim[4]));
+ result := true;
+ exit;
+ end;
+
+
if (lVols > 1) and ((lnSeries mod lVols)=0) then
lDICOMdata.SlicesPer3DVol := round(lnSeries/lVols);
lDTIra[1].bval := -1; //not DTI
@@ -1277,7 +1389,7 @@ begin
end else if lDICOMdata.File4D then begin//(lDicomData.XYZdim[3] > 1) and (lnSeries = 1) and (lDICOMdata.SlicesPer3DVol > 1) and ((lAHdr.dim[3] mod lDICOMdata.SlicesPer3DVol)=0) then begin
lAHdr.dim[4] := lAHdr.dim[3] div lDICOMdata.SlicesPer3DVol;
lAHdr.dim[3] := lDICOMdata.SlicesPer3DVol;
- //fx(213,lAHdr.dim[3],lAHdr.dim[4]);
+
end else if (lDicomData.XYZdim[3] > 1) then
lAHdr.dim[4] := lnSeries
else begin
@@ -1306,10 +1418,22 @@ begin
end;
end;
dicom_2_nifti(lDICOMdata,lAHdr,lMosaicSlices,lFlipmosaic);
- lBaseIntenScale := lDICOMdata.IntenScale;
+
+ //all slices in a NIFTI image must be of the same precision and have the same scaling intercept and slope - see if this applies
+ (*lBaseIntenScale := lDICOMdata.IntenScale;
lBaseIntenIntercept := lDICOMdata.IntenIntercept;
lBaseBitDepth := lDicomData.Allocbits_per_pixel;
-
+ lIntenScaleVaries := false;
+ for lSeries := 1 to lnSeries do begin
+ lIndex := Index (lSeries,lFirstDICOM,lInterleaved,lFlip,lAHdr);
+ if lDICOMra^[lIndex].IntenIntercept <> lBaseIntenIntercept then
+ lIntenscaleVaries := true; //1492
+ if lDICOMra^[lIndex].IntenScale <> lBaseIntenScale then
+ lIntenscaleVaries := true; //1492
+ if lDICOMra^[lIndex].Allocbits_per_pixel <> lBaseBitDepth then
+ lIntenscaleVaries := true;
+ end; //for lnSeries *)
+ lIntenScaleVaries := ImageScalingOrIntensityVaries(lDICOMra, lFirstDICOM, lLastDICOM);
(* for lSeries := 1 to lnSeries do begin
lIndex := Index (lSeries,lFirstDICOM,lInterleaved,lFlip,lAHdr);
@@ -1320,40 +1444,48 @@ begin
//exit;//get out of here - crucial critical -- last chance before data saved to disk
if (lAHdr.bitpix = 8) and (lDicomData.SamplesPerPixel = 3) then begin
+ if (lIntenScaleVaries) then begin
+ msg('RGB files can not have varying intensity scales!');
+ lIntenScaleVaries := false;
+ end;
lRGB := 3;
lAHdr.datatype := kDT_RGB;
lAHdr.bitpix := 24;
end else
lRGB := 1;
+ if (lIntenScaleVaries) then begin
+ lAHdr.datatype := kDT_FLOAT;
+ lAHdr.bitpix := 32;
+ Msg('Warning: images have different precision or intensity scaling - saving as 32-bit float');
+ end;
lSliceBytes := lDicomData.XYZdim[1]*lDicomData.XYZdim[2]*lDicomData.XYZdim[3]*trunc(((lDicomData.Allocbits_per_pixel)+7)/8)*lRGB;
GetMem(lsBuffer,lSliceBytes);
- //showmessage(inttostr(lSliceBytes));
- lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc(((lDicomData.Allocbits_per_pixel)+7)/8)*lRGB;
+
+ lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc((lAHdr.bitpix+7)/8)*lRGB;
lVolBytesOut := lSliceBytesOut * lAHdr.dim[4];
lVolOffset := 1;
lVolGB := (lSliceBytesOut/ 1073741824) * lAHdr.dim[4]; //bytes *1024 (kB) *1024 (Mb) * 1024 (Gb)
//note.nii files are 352bytes larger than calculated by lVolGb...
//Msg(floattostr(lVolGb)+' Gb');
- if lVolGb < 0.95 then
+ if (lPrefs.maxGb64bit = 0) or (lVolGb <= lPrefs.maxGb64bit) then //maxGb64bit
lVolSave := true
else begin
Msg('Very large volume: '+floattostr(lVolGb)+' Gb: slice-by-slice conversion required.');
- if lPref.GZip then begin
- lPref.GZip := false;
- Msg('Unable to automatically GZip such a large file.');
- end;
lVolSave := false;
end;
- if lVolSave then begin //save entire volume
- if lPref.SingleNIIFile then begin
- lVolOffset := kNIIImgOffset+1;// 353; //first 352 bytes empty
- lVolBytesOut := lVolBytesOut + lVolOffset -1;
- end else lVolOffset := 1;
- GetMem(lvBuffer,lVolBytesOut);
- //showmessage(inttostr(lVolBytesOut));
- //we could copy NIfTI header to Buffer, but this would need to be changed for
- //4D->3D images or images where we swap 3rd and 4th dimension....
- end else begin //save slice by slice - slower but low RAM usage...
+ if lVolSave then begin //save entire volume
+ if lPref.SingleNIIFile then begin
+ lVolOffset := kNIIImgOffset+1;// 353; //first 352 bytes empty
+ lVolBytesOut := lVolBytesOut + lVolOffset -1;
+ end else
+ lVolOffset := 1;
+
+ GetMem(lvBuffer,lVolBytesOut);
+
+ //showmessage(inttostr(lVolBytesOut));
+ //we could copy NIfTI header to Buffer, but this would need to be changed for
+ //4D->3D images or images where we swap 3rd and 4th dimension....
+ end else begin //save slice by slice - slower but low RAM usage...
if not SaveHdr (lOutHdrName,lAHdr, false,lPref.SPM2) then begin
Msg('Error saving data - do you have permission and space for '+lOutHdrName+'?');
exit;
@@ -1370,7 +1502,7 @@ begin
Filemode := 0; //set to read only
lVolOffsetInit := lVolOffset;
for lSeries := 1 to lnSeries do begin
- lIndex := Index (lSeries,lFirstDICOM,lInterleaved,lFlip,lAHdr);
+ lIndex := Index (lSeries,lFirstDICOM,lInterleaved,lFlip,lAHdr);
lDicomImgName := lDICOMra^[lIndex].Filename;
lDicomData := lDICOMra^[lIndex];
if (lDICOMdata.ManufacturerID = kPhilipsID) and (lDICOMdata.nDTIdir > 1) and (lAHdr.dim[4] < kMaxDTIDir) and (lDICOMdata.nDTIdir >= lAHdr.dim[4]) then begin //
@@ -1385,11 +1517,7 @@ begin
end else if (lDICOMdata.ManufacturerID = kSiemensID) and (lDTIra[1].Bval >= 0) and (lDTIdir < kMaxDTIDir) and ( ((lSeries mod lAHdr.dim[3]) = 1) or((lMosX > 1) or (lMosY > 1))) then begin //
inc(lDTIdir);
IsSiemensDTI(lDicomData,lDTIra[lDTIdir], lDicomImgName,lPrefs);
- // msgfx(lSeries, lDTIra[lDTIdir].v1,lDTIra[lDTIdir].v2,lDTIra[lDTIdir].v3);
-
- //fx(lDTI.v1,lDTI.v2,lDTI.v3,666);
- //afx(lDicomImgName, lDTIra[lDTIdir],lDTIdir);
end else if (lDICOMdata.nDTIdir = 1) and (lDICOMdata.DTI[1].Bval >= 0) and (lDTIdir < kMaxDTIDir) and ( (lSeries mod lAHdr.dim[3]) = 1) then begin //
inc(lDTIdir);
lDTIra[lDTIdir].bval := lDICOMdata.DTI[1].bval;
@@ -1397,74 +1525,93 @@ begin
lDTIra[lDTIdir].v2 := lDICOMdata.DTI[1].v2;
lDTIra[lDTIdir].v3 := lDICOMdata.DTI[1].v3;
end;
-
- if lDICOMdata.IntenIntercept <> lBaseIntenIntercept then
- lIntenscaleVaries := true; //1492
- if lDICOMdata.IntenScale <> lBaseIntenScale then
- lIntenscaleVaries := true;
- if lDicomData.Allocbits_per_pixel <> lBaseBitDepth then
- lIntenscaleVaries := true;
+ lReadOK := true;
if (lDicomData.JPEGLosslessCpt) then begin
AssignFile(lInF, lDicomImgName);
- Reset(lInF,1);
- Filemode := 0; //ReadONly
- lSliceBytesOut := lSliceBytes;
- lAllocSLiceSz := (lDICOMdata.XYZdim[1]*lDICOMdata.XYZdim[2]{height * width} * lDICOMdata.Allocbits_per_pixel+7) div 8 ;
- //fx('name='+lDicomImgName+' allocsz='+inttostr(lAllocSLiceSz)+' offset='+inttostr(lDicomData.CompressOffset)+' sz='+inttostr(lDicomData.CompressSz));
- //fx(lAllocSLiceSz,lDicomData.CompressOffset,lDICOMdata.CompressSz);
- DecodeJPEG(lInF,SmallIntP0(lsBuffer),ByteP0(lsBuffer),lAllocSliceSz,lDicomData.CompressOffset,lDICOMdata.CompressSz,false);
+ Reset(lInF,1);
+ //lDICOMdata.CompressSz := FileSize(lInF)-lDicomData.CompressOffset;
+ Filemode := 0; //ReadONly
+ //lSliceBytesOut := lSliceBytes;
+ Msg('Decoding lossless '+inttostr(lDICOMdata.XYZdim[1])+'x'+inttostr(lDICOMdata.XYZdim[2])+' JPEG starting from byte '+ inttostr(lDicomData.CompressOffset)+' with '+inttostr(lDICOMdata.CompressSz)+' bytes');
+ if ( lDicomData.XYZdim[3] > 1) or ( lDicomData.XYZdim[4] > 1) then
+ msg('*Warning: this software will only convert the first slice of this multislice lossless compressed JPEG');
+ lAllocSLiceSz := (lDICOMdata.XYZdim[1]*lDICOMdata.XYZdim[2] * lDICOMdata.Allocbits_per_pixel+7) div 8 ;
+ DecodeJPEG(lInF,SmallIntP0(lsBuffer),ByteP0(lsBuffer),lAllocSliceSz,lDicomData.CompressOffset,lDICOMdata.CompressSz,false);
CloseFile(lInF);
- FlipTB(lDICOMdata,lsBuffer);
+ (*FlipTB(lDICOMdata,lsBuffer);
if lVolSave then begin{save entire volume}
Move(lsBuffer^,lvBuffer^[lvolOffset],lSliceBytesOut);
//Msg(inttostr(lSeries));
lVolOffset := lVolOffset + lSliceBytesOut;
end else begin //save slice-by-slice
Filemode := 2; //read and write
- BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
- end;
+ BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
+ end;*)
end else if (FSize(lDicomImgName) >= (lSliceBytes+lDicomData.imagestart)) then begin
- Filemode := 0; //ReadONly
- AssignFile(lInF, lDicomImgName);
- Reset(lInF,1);
- Seek(lInF,lDicomData.imagestart);
- Filemode := 0; //ReadONly
- BlockRead(lInF, lsBuffer^, lSliceBytes);
- if (lDICOMdata.file4D) and (lPrefs.Swizzle4D) then
- SwapTime(lDICOMdata,lsBuffer);//data is stored X,Y,T,Z - swap to X,Y,Z,T
- lSliceBytesOut := lSliceBytes;
- if (lDICOMdata.PlanarConfig = 0) and (lDicomData.SamplesPerPixel = 3) then
+ Filemode := 0; //ReadONly
+ AssignFile(lInF, lDicomImgName);
+ Reset(lInF,1);
+ Seek(lInF,lDicomData.imagestart);
+ Filemode := 0; //ReadONly
+ BlockRead(lInF, lsBuffer^, lSliceBytes);
+ CloseFile(lInF);
+ (*if (lDICOMdata.file4D) and (lPrefs.Swizzle4D) then
+ SwapTime(lDICOMdata,lsBuffer);//data is stored X,Y,T,Z - swap to X,Y,Z,T
+ lSliceBytesOut := lSliceBytes;
+ if (lDICOMdata.PlanarConfig = 0) and (lDicomData.SamplesPerPixel = 3) then
MakePlanar(lsBuffer,lDICOMdata);
- if (lMosX > 1) or (lMosY > 1) then begin
- //lBuffer: bytep;lmosX,lmosY,lSlices: integer; lFlip: boolean; var lDicomData: DICOMdata);
- DeMosaic(lsBuffer,lmosX,lmosY,lMosaicSlices,lFlipMosaic,lDICOMdata);
+ if (lMosX > 1) or (lMosY > 1) then begin
+ DeMosaic(lsBuffer,lmosX,lmosY,lMosaicSlices,lFlipMosaic,lDICOMdata);
lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc(((lDicomData.Allocbits_per_pixel)+7)/8);
- end else
- FlipTB(lDICOMdata,lsBuffer);
- CloseFile(lInF);
+ end else
+ FlipTB(lDICOMdata,lsBuffer);
+
if lVolSave then begin{save entire volume}
-//showmessage('volsave'+lDicomImgName+ inttostr(lvolOffset)+':'+inttostr(lSliceBytesOut));
Move(lsBuffer^,lvBuffer^[lvolOffset],lSliceBytesOut);
lVolOffset := lVolOffset + lSliceBytesOut;
end else begin //save slice-by-slice
Filemode := 2; //read and write
- BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
- end;
+ BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
+ end; *)
end else begin
Msg('Serious error with file '+ extractfilename(lDicomImgName));
- (*Msg('Error: file ' + extractfilename(lDicomImgName)+' is '+inttostr(FSize(lDicomImgName))+
- ' with an offset of '+inttostr(lDicomData.imagestart) +' should have '+inttostr(lSliceBytes)+' bytes image data!');
- Msg(inttostr(lDicomData.XYZdim[1])+' '+inttostr(lDicomData.XYZdim[2])+' '+inttostr(lDicomData.XYZdim[3]));
- readln;*)
- end;
- end;
- freemem(lsBuffer);
- Filemode := 2; //read and write
- lOutImgNameGZ := lOutImgName;
- if lVolSave then begin{save slice-by-slice}
+ lReadOK := false;
+ end; //if JPEG else if UNCOMPRESSED else ERROR
+ if lReadOK then begin
+ lDicomData.XYZdim[4] := lAHdr.dim[4]; //do this now - depending on slice order DicomData can be first or last volume
+ if (lDICOMdata.file4D) and (lPrefs.Swizzle4D) then
+ SwapTime(lDICOMdata,lsBuffer);//data is stored X,Y,T,Z - swap to X,Y,Z,T
+ lSliceBytesOut := lSliceBytes;
+ if (lIntenScaleVaries) then begin
+
+ MakeFloat(lsBuffer,lDICOMdata, lSliceBytesOut);
+ lByteSwap := false; //Un-swapped during conversion
+ end;
+ if (lDICOMdata.PlanarConfig = 0) and (lDicomData.SamplesPerPixel = 3) then
+ MakePlanar(lsBuffer,lDICOMdata);
+ if (lMosX > 1) or (lMosY > 1) then begin
+ DeMosaic(lsBuffer,lmosX,lmosY,lMosaicSlices,lFlipMosaic,lDICOMdata);
+ lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc((lAHdr.bitpix+7)/8);
+ end else
+ FlipTB(lDICOMdata,lsBuffer);
+ //msg(inttostr(lSliceBytesOut)+ ' '+inttostr(lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc((lAHdr.bitpix+7)/8)));
+ //lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc((lAHdr.bitpix+7)/8);
+ if lVolSave then begin{save entire volume}
+ Move(lsBuffer^,lvBuffer^[lvolOffset],lSliceBytesOut);
+ lVolOffset := lVolOffset + lSliceBytesOut;
+ end else begin //save slice-by-slice
+ Filemode := 2; //read and write
+ BlockWrite(lOutF, lsBuffer^, lSliceBytesOut);
+ end;
+ end; //if lReadOK
+ end;
+ freemem(lsBuffer);
+ Filemode := 2; //read and write
+ lOutImgNameGZ := lOutImgName;
+ if lVolSave then begin{save slice-by-slice}
lOutImgNameGZ := SaveNIfTICore (lOutImgName, lvBuffer, lVolOffsetInit, lAHdr, lPref,lByteSwap)
- end else //data saved slice by slice
- CloseFile(lOutF);
+ end else //data saved slice by slice
+ CloseFile(lOutF);
//if (lPref.StartClip > 0) or (lPref.EndClip > 0) then
// Clip4D(lOutHdrName, lAHdr, false,lPref.SPM2,lPref.SingleNIIFile,lPref.GZip, true, lPref.StartClip,lPref.EndClip);
@@ -1556,14 +1703,24 @@ begin
if lVolSave then //do this AFTER DTI extraction - allows rapid cropping of Philips DTI
Freemem ( lvBuffer)
else begin
- if ((not lPref.FourD) and (lAHdr.dim[4] > 1)) or ((lPref.SingleNIIFile) and (lPref.Gzip)) then begin
+ CheckHugeUint16(lOutHdrName, false);
+ if (not lPref.FourD) and (lAHdr.dim[4] > 1) then //Convert 4D to 3D
ChangeNIfTISubformat(lOutHdrName, lAHdr,lPref) ;
- end;
+
+ if (lPref.SingleNIIFile) and (lPref.Gzip) then begin
+ if (lPref.usePigz = 0) then begin //usePigz forced for huge files ... internal unlikely 32-bit safe
+ if not runPigz(lOutHdrName, 1) then
+ msg('Warning: unable to compress '+lOutHdrName+' with pigz. Make sure pigz is installed.');
+ end else begin
+ if not runPigz(lOutHdrName, lPref.usePigz) then
+ msg('Warning: unable to compress '+lOutHdrName+' with pigz. Make sure pigz is installed.');
+ end;
+ end
end; //slice-by-slice
- if lIntenscaleVaries then begin
+ (*if lIntenscaleVaries then begin
beep;
Msg('Intensity scale/slope or bit-depth varies across slices: perhaps convert with MRIcro.');
- end;
+ end;*)
if (lPref.enablereorient) and (lDicomData.XYZdim[2] > lPref.MinReorientMatrix) and (lDicomData.XYZdim[1] > lPref.MinReorientMatrix) and (lAHdr.dim[3] > 64) and (lAHdr.dim[4] < 2) then begin
lOutImgName := Reorient(lOutImgNameGZ,lAHdr,lPref,false,false);
if (lOutImgName <> '') and (lDicomData.TE < 25) and (lDicomData.TE > 0) then //T1 image
@@ -1574,4 +1731,4 @@ begin
ExitCode := 0;
end;
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/convertsimple.pas b/dcm2nii_prePARRECDTI/convertsimple.pas
old mode 100644
new mode 100755
similarity index 96%
copy from dcm2nii/convertsimple.pas
copy to dcm2nii_prePARRECDTI/convertsimple.pas
index 619b2bb..5945cc0
--- a/dcm2nii/convertsimple.pas
+++ b/dcm2nii_prePARRECDTI/convertsimple.pas
@@ -198,7 +198,7 @@ begin
until lDone;
if lDcm.Allocbits_per_pixel = 32 then begin
result := true;
- lDcm.float := true;
+ lDcm.FloatData := true;
end else begin
Msg('Unsupported datatype: '+inttostr( lDcm.Allocbits_per_pixel)+ 'bits per pixel '+lFName);
end;
diff --git a/dcm2nii/csaread.pas b/dcm2nii_prePARRECDTI/csaread.pas
old mode 100644
new mode 100755
similarity index 94%
copy from dcm2nii/csaread.pas
copy to dcm2nii_prePARRECDTI/csaread.pas
index 03b23fe..3724eb8
--- a/dcm2nii/csaread.pas
+++ b/dcm2nii_prePARRECDTI/csaread.pas
@@ -47,7 +47,7 @@ begin
lMosaicY := lCSA.MosaicY;
lv1 := lCSA.SliceNormV1;
lv2 := lCSA.SliceNormV2;
- lv3 := lCSA.SliceNormV2;
+ lv3 := lCSA.SliceNormV3; //5/5/2013
end;
function DecodeCSA2 (lFilename: string; lCSAImageHeaderInfoPos, lCSAImageHeaderInfoSz: integer; var lCSA: TCSA): boolean;
@@ -238,7 +238,7 @@ begin //main function DecodeCSA2
result := true;
//showmsg('Success DecodeCSA2');
end else begin
- showmsg('CSAread Warning: only CSA2 format is supported: image is either corruprted, very old or new. See if a new version of this software is available.');
+ msg('CSAread Warning: '+ lFilename +' at byte '+inttostr(lCSAImageHeaderInfoPos)+' reports version "'+lVers+'": only "SV10" format is supported: image is either corruprted, very old or new. See if a new version of this software is available.');
end;
lData := nil;
end;// func DecodeCSA2
diff --git a/dcm2nii/dcm2nii.app/Contents/Info.plist b/dcm2nii_prePARRECDTI/dcm2nii.app/Contents/Info.plist
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2nii.app/Contents/Info.plist
copy to dcm2nii_prePARRECDTI/dcm2nii.app/Contents/Info.plist
diff --git a/dcm2nii/dcm2nii.app/Contents/MacOS/dcm2nii b/dcm2nii_prePARRECDTI/dcm2nii.app/Contents/MacOS/dcm2nii
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2nii.app/Contents/MacOS/dcm2nii
copy to dcm2nii_prePARRECDTI/dcm2nii.app/Contents/MacOS/dcm2nii
diff --git a/dcm2nii/dcm2niigui.app/Contents/PkgInfo b/dcm2nii_prePARRECDTI/dcm2nii.app/Contents/PkgInfo
old mode 100644
new mode 100755
similarity index 100%
rename from dcm2nii/dcm2niigui.app/Contents/PkgInfo
rename to dcm2nii_prePARRECDTI/dcm2nii.app/Contents/PkgInfo
diff --git a/dcm2nii/dcm2nii.cfg b/dcm2nii_prePARRECDTI/dcm2nii.cfg
old mode 100644
new mode 100755
similarity index 69%
copy from dcm2nii/dcm2nii.cfg
copy to dcm2nii_prePARRECDTI/dcm2nii.cfg
index b8dce01..5d9b456
--- a/dcm2nii/dcm2nii.cfg
+++ b/dcm2nii_prePARRECDTI/dcm2nii.cfg
@@ -1,4 +1,4 @@
--$A+
+-$A8
-$B-
-$C+
-$D+
@@ -31,7 +31,8 @@
-M
-$M16384,1048576
-K$00400000
--LN"c:\program files\borland\delphi4\Lib"
+-LE"c:\program files (x86)\borland\delphi7\Projects\Bpl"
+-LN"c:\program files (x86)\borland\delphi7\Projects\Bpl"
-U"..\common\;..\delphionly\"
-O"..\common\;..\delphionly\"
-I"..\common\;..\delphionly\"
diff --git a/dcm2nii/dcm2niigui.dof b/dcm2nii_prePARRECDTI/dcm2nii.dof
old mode 100644
new mode 100755
similarity index 81%
copy from dcm2nii/dcm2niigui.dof
copy to dcm2nii_prePARRECDTI/dcm2nii.dof
index 97da3dd..1026d73
--- a/dcm2nii/dcm2niigui.dof
+++ b/dcm2nii_prePARRECDTI/dcm2nii.dof
@@ -94,7 +94,7 @@ OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
-SearchPath=..\common\;C:\pas\d4\RX\Units\
+SearchPath=..\common\;..\delphionly\
Packages=Vcl40;Vclx40;VclSmp40;Qrpt40;Vcldb40;RxCtl4
Conditionals=
DebugSourceDirs=
@@ -115,7 +115,7 @@ AutoIncBuild=0
MajorVer=0
MinorVer=9
Release=0
-Build=0
+Build=1
Debug=0
PreRelease=0
Special=0
@@ -124,21 +124,20 @@ DLL=0
Locale=1033
CodePage=1252
[Version Info Keys]
-CompanyName=
-FileDescription=
-FileVersion=0.9.0.0
+CompanyName=Chris Rorden
+FileDescription=DICOM and PAR/REC converter
+FileVersion=0.9.0.1
InternalName=
-LegalCopyright=
+LegalCopyright=Copyright �
LegalTrademarks=
-OriginalFilename=
-ProductName=
-ProductVersion=1.0.0.0
+OriginalFilename=dcm2nii.exe
+ProductName=dcm2nii
+ProductVersion=0.0
Comments=
[HistoryLists\hlUnitAliases]
Count=1
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
[HistoryLists\hlSearchPath]
-Count=3
-Item0=..\common\;C:\pas\d4\RX\Units\
-Item1=..\common\;C:\pas\d4\RX\Units
-Item2=..\common\
+Count=2
+Item0=..\common\;..\delphionly\
+Item1=..\common\
diff --git a/dcm2nii/dcm2nii.dpr b/dcm2nii_prePARRECDTI/dcm2nii.dpr
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2nii.dpr
copy to dcm2nii_prePARRECDTI/dcm2nii.dpr
diff --git a/dcm2nii/dcm2nii.ico b/dcm2nii_prePARRECDTI/dcm2nii.ico
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2nii.ico
copy to dcm2nii_prePARRECDTI/dcm2nii.ico
diff --git a/dcm2nii/dcm2nii.ini b/dcm2nii_prePARRECDTI/dcm2nii.ini
old mode 100644
new mode 100755
similarity index 91%
copy from dcm2nii/dcm2nii.ini
copy to dcm2nii_prePARRECDTI/dcm2nii.ini
index 4ff9c8c..65f634a
--- a/dcm2nii/dcm2nii.ini
+++ b/dcm2nii_prePARRECDTI/dcm2nii.ini
@@ -28,6 +28,7 @@ UseGE_0021_104F=0
DebugMode=0
UntestedFeatures=0
OrthoFlipXDim=0
+UINT16toFLOAT32=1
[INT]
BeginClip=0
@@ -41,6 +42,7 @@ IgnoreDTIRotationsIf_0018_1020_atleast=15
SiemensDTIUse0019If00181020atleast=15
SiemensDTINoAngulationCorrectionIf00181020atleast=1000
SiemensDTIStackIf00181020atleast=15
+usePigz=0
[STR]
BackupDir=
diff --git a/dcm2nii/dcm2nii.lpi b/dcm2nii_prePARRECDTI/dcm2nii.lpi
old mode 100644
new mode 100755
similarity index 68%
copy from dcm2nii/dcm2nii.lpi
copy to dcm2nii_prePARRECDTI/dcm2nii.lpi
index 87cedcc..274537b
--- a/dcm2nii/dcm2nii.lpi
+++ b/dcm2nii_prePARRECDTI/dcm2nii.lpi
@@ -1,431 +1,434 @@
-<?xml version="1.0"?>
-<CONFIG>
- <ProjectOptions>
- <Version Value="9"/>
- <PathDelim Value="\"/>
- <General>
- <Flags>
- <LRSInOutputDirectory Value="False"/>
- </Flags>
- <MainUnit Value="0"/>
- <ActiveWindowIndexAtStart Value="0"/>
- </General>
- <BuildModes Count="1">
- <Item1 Name="default" Default="True"/>
- </BuildModes>
- <PublishOptions>
- <Version Value="2"/>
- <IgnoreBinaries Value="False"/>
- <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
- <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
- </PublishOptions>
- <RunParams>
- <local>
- <FormatVersion Value="1"/>
- <LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
- </local>
- </RunParams>
- <Units Count="30">
- <Unit0>
- <Filename Value="dcm2nii.lpr"/>
- <IsPartOfProject Value="True"/>
- <UnitName Value="dcm2nii"/>
- <EditorIndex Value="0"/>
- <WindowIndex Value="0"/>
- <TopLine Value="19"/>
- <CursorPos X="3" Y="32"/>
- <UsageCount Value="118"/>
- <Loaded Value="True"/>
- <LoadedDesigner Value="True"/>
- </Unit0>
- <Unit1>
- <Filename Value="convert.pas"/>
- <UnitName Value="convert"/>
- <EditorIndex Value="6"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="10"/>
- <UsageCount Value="57"/>
- <Loaded Value="True"/>
- </Unit1>
- <Unit2>
- <Filename Value="define_types.pas"/>
- <UnitName Value="define_types"/>
- <TopLine Value="317"/>
- <CursorPos X="1" Y="330"/>
- <UsageCount Value="57"/>
- </Unit2>
- <Unit3>
- <Filename Value="gzio2.pas"/>
- <UnitName Value="gzio2"/>
- <TopLine Value="1765"/>
- <CursorPos X="7" Y="1784"/>
- <UsageCount Value="57"/>
- </Unit3>
- <Unit4>
- <Filename Value="dicom.pas"/>
- <UnitName Value="dicom"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="1"/>
- <UsageCount Value="57"/>
- </Unit4>
- <Unit5>
- <Filename Value="nodialogs.pas"/>
- <UnitName Value="nodialogs"/>
- <TopLine Value="1"/>
- <CursorPos X="10" Y="5"/>
- <UsageCount Value="54"/>
- </Unit5>
- <Unit6>
- <Filename Value="lsjpeg.pas"/>
- <UnitName Value="lsjpeg"/>
- <EditorIndex Value="8"/>
- <WindowIndex Value="0"/>
- <TopLine Value="711"/>
- <CursorPos X="30" Y="741"/>
- <UsageCount Value="56"/>
- <Loaded Value="True"/>
- </Unit6>
- <Unit7>
- <Filename Value="GraphicsMathLibrary.pas"/>
- <UnitName Value="GraphicsMathLibrary"/>
- <TopLine Value="61"/>
- <CursorPos X="1" Y="66"/>
- <UsageCount Value="54"/>
- </Unit7>
- <Unit8>
- <Filename Value="sortdicom.pas"/>
- <UnitName Value="sortdicom"/>
- <TopLine Value="172"/>
- <CursorPos X="24" Y="188"/>
- <UsageCount Value="57"/>
- </Unit8>
- <Unit9>
- <Filename Value="filename.pas"/>
- <IsPartOfProject Value="True"/>
- <UnitName Value="filename"/>
- <EditorIndex Value="1"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="49" Y="5"/>
- <UsageCount Value="118"/>
- <Loaded Value="True"/>
- </Unit9>
- <Unit10>
- <Filename Value="dicomtypes.pas"/>
- <IsPartOfProject Value="True"/>
- <UnitName Value="dicomtypes"/>
- <TopLine Value="307"/>
- <CursorPos X="42" Y="320"/>
- <UsageCount Value="118"/>
- </Unit10>
- <Unit11>
- <Filename Value="parconvert.pas"/>
- <UnitName Value="parconvert"/>
- <TopLine Value="1188"/>
- <CursorPos X="44" Y="1199"/>
- <UsageCount Value="57"/>
- </Unit11>
- <Unit12>
- <Filename Value="..\..\junk\unit1.pas"/>
- <ComponentName Value="Form1"/>
- <HasResources Value="True"/>
- <UnitName Value="Unit1"/>
- <TopLine Value="1"/>
- <CursorPos X="36" Y="7"/>
- <UsageCount Value="3"/>
- </Unit12>
- <Unit13>
- <Filename Value="nii4Dto3D.pas"/>
- <UnitName Value="nii4dto3d"/>
- <TopLine Value="114"/>
- <CursorPos X="53" Y="125"/>
- <UsageCount Value="11"/>
- </Unit13>
- <Unit14>
- <Filename Value="dicomfast.pas"/>
- <UnitName Value="dicomfast"/>
- <WindowIndex Value="0"/>
- <TopLine Value="4"/>
- <CursorPos X="6" Y="14"/>
- <UsageCount Value="11"/>
- </Unit14>
- <Unit15>
- <Filename Value="dicomcompat.pas"/>
- <UnitName Value="dicomcompat"/>
- <TopLine Value="5888"/>
- <CursorPos X="31" Y="5918"/>
- <UsageCount Value="11"/>
- </Unit15>
- <Unit16>
- <Filename Value="dialogsx.pas"/>
- <UnitName Value="dialogsx"/>
- <TopLine Value="1"/>
- <CursorPos X="10" Y="2"/>
- <UsageCount Value="11"/>
- </Unit16>
- <Unit17>
- <Filename Value="nii_4dto3d.pas"/>
- <UnitName Value="nii_4dto3d"/>
- <TopLine Value="113"/>
- <CursorPos X="53" Y="124"/>
- <UsageCount Value="11"/>
- </Unit17>
- <Unit18>
- <Filename Value="nii_orient.pas"/>
- <UnitName Value="nii_orient"/>
- <EditorIndex Value="2"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="65" Y="4"/>
- <UsageCount Value="11"/>
- <Loaded Value="True"/>
- </Unit18>
- <Unit19>
- <Filename Value="nii_crop.pas"/>
- <UnitName Value="nii_crop"/>
- <TopLine Value="1"/>
- <CursorPos X="6" Y="2"/>
- <UsageCount Value="11"/>
- </Unit19>
- <Unit20>
- <Filename Value="paramstrs.pas"/>
- <UnitName Value="paramstrs"/>
- <IsVisibleTab Value="True"/>
- <EditorIndex Value="7"/>
- <WindowIndex Value="0"/>
- <TopLine Value="169"/>
- <CursorPos X="29" Y="17"/>
- <UsageCount Value="11"/>
- <Loaded Value="True"/>
- </Unit20>
- <Unit21>
- <Filename Value="readint.pas"/>
- <UnitName Value="readint"/>
- <TopLine Value="1"/>
- <CursorPos X="13" Y="6"/>
- <UsageCount Value="10"/>
- </Unit21>
- <Unit22>
- <Filename Value="userdir.pas"/>
- <UnitName Value="userdir"/>
- <TopLine Value="1"/>
- <CursorPos X="31" Y="13"/>
- <UsageCount Value="10"/>
- </Unit22>
- <Unit23>
- <Filename Value="..\common\isgui.inc"/>
- <EditorIndex Value="9"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="13" Y="1"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
- </Unit23>
- <Unit24>
- <Filename Value="..\common\define_types.pas"/>
- <UnitName Value="define_types"/>
- <EditorIndex Value="5"/>
- <WindowIndex Value="0"/>
- <TopLine Value="2"/>
- <CursorPos X="7" Y="11"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
- </Unit24>
- <Unit25>
- <Filename Value="..\common\gzio2.pas"/>
- <UnitName Value="gzio2"/>
- <TopLine Value="1809"/>
- <CursorPos X="35" Y="1849"/>
- <UsageCount Value="10"/>
- </Unit25>
- <Unit26>
- <Filename Value="..\common\GraphicsMathLibrary.pas"/>
- <UnitName Value="GraphicsMathLibrary"/>
- <TopLine Value="547"/>
- <CursorPos X="35" Y="552"/>
- <UsageCount Value="10"/>
- </Unit26>
- <Unit27>
- <Filename Value="..\common\dialogsx.pas"/>
- <UnitName Value="dialogsx"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="1"/>
- <UsageCount Value="10"/>
- </Unit27>
- <Unit28>
- <Filename Value="prefs.pas"/>
- <UnitName Value="prefs"/>
- <EditorIndex Value="3"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="24" Y="3"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
- </Unit28>
- <Unit29>
- <Filename Value="..\common\userdir.pas"/>
- <UnitName Value="userdir"/>
- <EditorIndex Value="4"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="1"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
- </Unit29>
- </Units>
- <JumpHistory Count="30" HistoryIndex="29">
- <Position1>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="228" Column="25" TopLine="203"/>
- </Position1>
- <Position2>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="231" Column="20" TopLine="217"/>
- </Position2>
- <Position3>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="253" Column="32" TopLine="239"/>
- </Position3>
- <Position4>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="259" Column="21" TopLine="239"/>
- </Position4>
- <Position5>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="266" Column="33" TopLine="239"/>
- </Position5>
- <Position6>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="280" Column="20" TopLine="266"/>
- </Position6>
- <Position7>
- <Filename Value="lsjpeg.pas"/>
- <Caret Line="9" Column="118" TopLine="1"/>
- </Position7>
- <Position8>
- <Filename Value="prefs.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position8>
- <Position9>
- <Filename Value="prefs.pas"/>
- <Caret Line="6" Column="5" TopLine="1"/>
- </Position9>
- <Position10>
- <Filename Value="prefs.pas"/>
- <Caret Line="7" Column="26" TopLine="1"/>
- </Position10>
- <Position11>
- <Filename Value="..\common\userdir.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position11>
- <Position12>
- <Filename Value="filename.pas"/>
- <Caret Line="202" Column="54" TopLine="163"/>
- </Position12>
- <Position13>
- <Filename Value="filename.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position13>
- <Position14>
- <Filename Value="prefs.pas"/>
- <Caret Line="3" Column="2" TopLine="1"/>
- </Position14>
- <Position15>
- <Filename Value="..\common\userdir.pas"/>
- <Caret Line="10" Column="39" TopLine="1"/>
- </Position15>
- <Position16>
- <Filename Value="..\common\userdir.pas"/>
- <Caret Line="35" Column="58" TopLine="1"/>
- </Position16>
- <Position17>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="11" Column="21" TopLine="1"/>
- </Position17>
- <Position18>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="20" Column="45" TopLine="1"/>
- </Position18>
- <Position19>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="2" Column="25" TopLine="1"/>
- </Position19>
- <Position20>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="10" Column="29" TopLine="1"/>
- </Position20>
- <Position21>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position21>
- <Position22>
- <Filename Value="dcm2nii.lpr"/>
- <Caret Line="16" Column="31" TopLine="1"/>
- </Position22>
- <Position23>
- <Filename Value="paramstrs.pas"/>
- <Caret Line="13" Column="1" TopLine="4"/>
- </Position23>
- <Position24>
- <Filename Value="dcm2nii.lpr"/>
- <Caret Line="66" Column="1" TopLine="40"/>
- </Position24>
- <Position25>
- <Filename Value="..\common\define_types.pas"/>
- <Caret Line="9" Column="45" TopLine="1"/>
- </Position25>
- <Position26>
- <Filename Value="filename.pas"/>
- <Caret Line="11" Column="22" TopLine="1"/>
- </Position26>
- <Position27>
- <Filename Value="filename.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position27>
- <Position28>
- <Filename Value="prefs.pas"/>
- <Caret Line="3" Column="24" TopLine="1"/>
- </Position28>
- <Position29>
- <Filename Value="filename.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
- </Position29>
- <Position30>
- <Filename Value="paramstrs.pas"/>
- <Caret Line="18" Column="28" TopLine="1"/>
- </Position30>
- </JumpHistory>
- </ProjectOptions>
- <CompilerOptions>
- <Version Value="9"/>
- <PathDelim Value="\"/>
- <SearchPaths>
- <OtherUnitFiles Value="..\common"/>
- </SearchPaths>
- <Parsing>
- <SyntaxOptions>
- <UseAnsiStrings Value="False"/>
- </SyntaxOptions>
- </Parsing>
- <CodeGeneration>
- <Optimizations>
- <OptimizationLevel Value="2"/>
- </Optimizations>
- </CodeGeneration>
- <Linking>
- <Debugging>
- <UseLineInfoUnit Value="False"/>
- <StripSymbols Value="True"/>
- </Debugging>
- <LinkSmart Value="True"/>
- </Linking>
- <Other>
- <ConfigFile>
- <CustomConfigFile Value="True"/>
- </ConfigFile>
- <CompilerPath Value="$(CompPath)"/>
- </Other>
- </CompilerOptions>
-</CONFIG>
\ No newline at end of file
+<?xml version="1.0"?>
+<CONFIG>
+ <ProjectOptions>
+ <Version Value="9"/>
+ <PathDelim Value="\"/>
+ <General>
+ <Flags>
+ <LRSInOutputDirectory Value="False"/>
+ </Flags>
+ <MainUnit Value="0"/>
+ <ActiveWindowIndexAtStart Value="0"/>
+ </General>
+ <BuildModes Count="1">
+ <Item1 Name="default" Default="True"/>
+ </BuildModes>
+ <PublishOptions>
+ <Version Value="2"/>
+ <IgnoreBinaries Value="False"/>
+ <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+ <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ <LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+ </local>
+ </RunParams>
+ <Units Count="31">
+ <Unit0>
+ <Filename Value="dcm2nii.lpr"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="dcm2nii"/>
+ <EditorIndex Value="0"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="31"/>
+ <CursorPos X="48" Y="3"/>
+ <UsageCount Value="124"/>
+ <Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
+ </Unit0>
+ <Unit1>
+ <Filename Value="convert.pas"/>
+ <UnitName Value="convert"/>
+ <EditorIndex Value="7"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1455"/>
+ <CursorPos X="103" Y="1473"/>
+ <UsageCount Value="60"/>
+ <Loaded Value="True"/>
+ </Unit1>
+ <Unit2>
+ <Filename Value="define_types.pas"/>
+ <UnitName Value="define_types"/>
+ <TopLine Value="317"/>
+ <CursorPos X="1" Y="330"/>
+ <UsageCount Value="56"/>
+ </Unit2>
+ <Unit3>
+ <Filename Value="gzio2.pas"/>
+ <UnitName Value="gzio2"/>
+ <TopLine Value="1765"/>
+ <CursorPos X="7" Y="1784"/>
+ <UsageCount Value="56"/>
+ </Unit3>
+ <Unit4>
+ <Filename Value="dicom.pas"/>
+ <UnitName Value="dicom"/>
+ <TopLine Value="1"/>
+ <CursorPos X="1" Y="1"/>
+ <UsageCount Value="56"/>
+ </Unit4>
+ <Unit5>
+ <Filename Value="nodialogs.pas"/>
+ <UnitName Value="nodialogs"/>
+ <TopLine Value="1"/>
+ <CursorPos X="10" Y="5"/>
+ <UsageCount Value="53"/>
+ </Unit5>
+ <Unit6>
+ <Filename Value="lsjpeg.pas"/>
+ <UnitName Value="lsjpeg"/>
+ <EditorIndex Value="9"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="393"/>
+ <CursorPos X="20" Y="518"/>
+ <UsageCount Value="59"/>
+ <Loaded Value="True"/>
+ </Unit6>
+ <Unit7>
+ <Filename Value="GraphicsMathLibrary.pas"/>
+ <UnitName Value="GraphicsMathLibrary"/>
+ <TopLine Value="61"/>
+ <CursorPos X="1" Y="66"/>
+ <UsageCount Value="53"/>
+ </Unit7>
+ <Unit8>
+ <Filename Value="sortdicom.pas"/>
+ <UnitName Value="sortdicom"/>
+ <TopLine Value="172"/>
+ <CursorPos X="24" Y="188"/>
+ <UsageCount Value="56"/>
+ </Unit8>
+ <Unit9>
+ <Filename Value="filename.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="filename"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="51" Y="8"/>
+ <UsageCount Value="124"/>
+ </Unit9>
+ <Unit10>
+ <Filename Value="dicomtypes.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="dicomtypes"/>
+ <TopLine Value="307"/>
+ <CursorPos X="42" Y="320"/>
+ <UsageCount Value="124"/>
+ </Unit10>
+ <Unit11>
+ <Filename Value="parconvert.pas"/>
+ <UnitName Value="parconvert"/>
+ <TopLine Value="1188"/>
+ <CursorPos X="44" Y="1199"/>
+ <UsageCount Value="56"/>
+ </Unit11>
+ <Unit12>
+ <Filename Value="..\..\junk\unit1.pas"/>
+ <ComponentName Value="Form1"/>
+ <HasResources Value="True"/>
+ <UnitName Value="Unit1"/>
+ <TopLine Value="1"/>
+ <CursorPos X="36" Y="7"/>
+ <UsageCount Value="2"/>
+ </Unit12>
+ <Unit13>
+ <Filename Value="nii4Dto3D.pas"/>
+ <UnitName Value="nii4dto3d"/>
+ <TopLine Value="114"/>
+ <CursorPos X="53" Y="125"/>
+ <UsageCount Value="10"/>
+ </Unit13>
+ <Unit14>
+ <Filename Value="dicomfast.pas"/>
+ <UnitName Value="dicomfast"/>
+ <TopLine Value="4"/>
+ <CursorPos X="6" Y="14"/>
+ <UsageCount Value="10"/>
+ </Unit14>
+ <Unit15>
+ <Filename Value="dicomcompat.pas"/>
+ <UnitName Value="dicomcompat"/>
+ <TopLine Value="5888"/>
+ <CursorPos X="31" Y="5918"/>
+ <UsageCount Value="10"/>
+ </Unit15>
+ <Unit16>
+ <Filename Value="dialogsx.pas"/>
+ <UnitName Value="dialogsx"/>
+ <TopLine Value="1"/>
+ <CursorPos X="10" Y="2"/>
+ <UsageCount Value="10"/>
+ </Unit16>
+ <Unit17>
+ <Filename Value="nii_4dto3d.pas"/>
+ <UnitName Value="nii_4dto3d"/>
+ <TopLine Value="113"/>
+ <CursorPos X="53" Y="124"/>
+ <UsageCount Value="10"/>
+ </Unit17>
+ <Unit18>
+ <Filename Value="nii_orient.pas"/>
+ <UnitName Value="nii_orient"/>
+ <EditorIndex Value="1"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="39" Y="2"/>
+ <UsageCount Value="14"/>
+ <Loaded Value="True"/>
+ </Unit18>
+ <Unit19>
+ <Filename Value="nii_crop.pas"/>
+ <UnitName Value="nii_crop"/>
+ <TopLine Value="1"/>
+ <CursorPos X="6" Y="2"/>
+ <UsageCount Value="10"/>
+ </Unit19>
+ <Unit20>
+ <Filename Value="paramstrs.pas"/>
+ <UnitName Value="paramstrs"/>
+ <EditorIndex Value="8"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="159"/>
+ <CursorPos X="20" Y="167"/>
+ <UsageCount Value="14"/>
+ <Loaded Value="True"/>
+ </Unit20>
+ <Unit21>
+ <Filename Value="readint.pas"/>
+ <UnitName Value="readint"/>
+ <TopLine Value="1"/>
+ <CursorPos X="13" Y="6"/>
+ <UsageCount Value="9"/>
+ </Unit21>
+ <Unit22>
+ <Filename Value="userdir.pas"/>
+ <UnitName Value="userdir"/>
+ <TopLine Value="1"/>
+ <CursorPos X="31" Y="13"/>
+ <UsageCount Value="9"/>
+ </Unit22>
+ <Unit23>
+ <Filename Value="..\common\isgui.inc"/>
+ <IsVisibleTab Value="True"/>
+ <EditorIndex Value="4"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="14" Y="1"/>
+ <UsageCount Value="13"/>
+ <Loaded Value="True"/>
+ </Unit23>
+ <Unit24>
+ <Filename Value="..\common\define_types.pas"/>
+ <UnitName Value="define_types"/>
+ <EditorIndex Value="6"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="23" Y="11"/>
+ <UsageCount Value="13"/>
+ <Loaded Value="True"/>
+ </Unit24>
+ <Unit25>
+ <Filename Value="..\common\gzio2.pas"/>
+ <UnitName Value="gzio2"/>
+ <TopLine Value="1809"/>
+ <CursorPos X="35" Y="1849"/>
+ <UsageCount Value="9"/>
+ </Unit25>
+ <Unit26>
+ <Filename Value="..\common\GraphicsMathLibrary.pas"/>
+ <UnitName Value="GraphicsMathLibrary"/>
+ <TopLine Value="547"/>
+ <CursorPos X="35" Y="552"/>
+ <UsageCount Value="9"/>
+ </Unit26>
+ <Unit27>
+ <Filename Value="..\common\dialogsx.pas"/>
+ <UnitName Value="dialogsx"/>
+ <EditorIndex Value="10"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="8"/>
+ <CursorPos X="55" Y="9"/>
+ <UsageCount Value="13"/>
+ <Loaded Value="True"/>
+ </Unit27>
+ <Unit28>
+ <Filename Value="prefs.pas"/>
+ <UnitName Value="prefs"/>
+ <EditorIndex Value="2"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="128"/>
+ <CursorPos X="84" Y="133"/>
+ <UsageCount Value="13"/>
+ <Loaded Value="True"/>
+ </Unit28>
+ <Unit29>
+ <Filename Value="..\common\userdir.pas"/>
+ <UnitName Value="userdir"/>
+ <EditorIndex Value="5"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="1" Y="1"/>
+ <UsageCount Value="13"/>
+ <Loaded Value="True"/>
+ </Unit29>
+ <Unit30>
+ <Filename Value="niftiutil.pas"/>
+ <UnitName Value="niftiutil"/>
+ <EditorIndex Value="3"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="505"/>
+ <CursorPos X="32" Y="515"/>
+ <UsageCount Value="13"/>
+ <Loaded Value="True"/>
+ </Unit30>
+ </Units>
+ <JumpHistory Count="29" HistoryIndex="28">
+ <Position1>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1622" Column="12" TopLine="1596"/>
+ </Position1>
+ <Position2>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1258" Column="53" TopLine="1246"/>
+ </Position2>
+ <Position3>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1442" Column="24" TopLine="1408"/>
+ </Position3>
+ <Position4>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="455" Column="41" TopLine="431"/>
+ </Position4>
+ <Position5>
+ <Filename Value="..\common\define_types.pas"/>
+ <Caret Line="174" Column="10" TopLine="153"/>
+ </Position5>
+ <Position6>
+ <Filename Value="..\common\define_types.pas"/>
+ <Caret Line="8" Column="64" TopLine="1"/>
+ </Position6>
+ <Position7>
+ <Filename Value="..\common\define_types.pas"/>
+ <Caret Line="172" Column="18" TopLine="137"/>
+ </Position7>
+ <Position8>
+ <Filename Value="..\common\define_types.pas"/>
+ <Caret Line="174" Column="18" TopLine="139"/>
+ </Position8>
+ <Position9>
+ <Filename Value="..\common\define_types.pas"/>
+ <Caret Line="922" Column="33" TopLine="900"/>
+ </Position9>
+ <Position10>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="490" Column="23" TopLine="471"/>
+ </Position10>
+ <Position11>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="6" Column="22" TopLine="1"/>
+ </Position11>
+ <Position12>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="425" Column="20" TopLine="412"/>
+ </Position12>
+ <Position13>
+ <Filename Value="..\common\define_types.pas"/>
+ <Caret Line="908" Column="11" TopLine="905"/>
+ </Position13>
+ <Position14>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="431" Column="49" TopLine="405"/>
+ </Position14>
+ <Position15>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="418" Column="11" TopLine="401"/>
+ </Position15>
+ <Position16>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="508" Column="32" TopLine="480"/>
+ </Position16>
+ <Position17>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="431" Column="19" TopLine="404"/>
+ </Position17>
+ <Position18>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="421" Column="16" TopLine="404"/>
+ </Position18>
+ <Position19>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="443" Column="4" TopLine="435"/>
+ </Position19>
+ <Position20>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="431" Column="39" TopLine="411"/>
+ </Position20>
+ <Position21>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1272" Column="57" TopLine="1265"/>
+ </Position21>
+ <Position22>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1279" Column="122" TopLine="1265"/>
+ </Position22>
+ <Position23>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1359" Column="79" TopLine="1332"/>
+ </Position23>
+ <Position24>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1360" Column="120" TopLine="1333"/>
+ </Position24>
+ <Position25>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1385" Column="126" TopLine="1358"/>
+ </Position25>
+ <Position26>
+ <Filename Value="prefs.pas"/>
+ <Caret Line="26" Column="85" TopLine="1"/>
+ </Position26>
+ <Position27>
+ <Filename Value="prefs.pas"/>
+ <Caret Line="147" Column="3" TopLine="119"/>
+ </Position27>
+ <Position28>
+ <Filename Value="prefs.pas"/>
+ <Caret Line="26" Column="97" TopLine="11"/>
+ </Position28>
+ <Position29>
+ <Filename Value="prefs.pas"/>
+ <Caret Line="146" Column="22" TopLine="119"/>
+ </Position29>
+ </JumpHistory>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="11"/>
+ <PathDelim Value="\"/>
+ <SearchPaths>
+ <OtherUnitFiles Value="..\common"/>
+ </SearchPaths>
+ <Parsing>
+ <SyntaxOptions>
+ <UseAnsiStrings Value="False"/>
+ </SyntaxOptions>
+ </Parsing>
+ <CodeGeneration>
+ <Optimizations>
+ <OptimizationLevel Value="2"/>
+ </Optimizations>
+ </CodeGeneration>
+ <Linking>
+ <Debugging>
+ <GenerateDebugInfo Value="False"/>
+ <UseLineInfoUnit Value="False"/>
+ <StripSymbols Value="True"/>
+ </Debugging>
+ <LinkSmart Value="True"/>
+ </Linking>
+ <Other>
+ <CompilerPath Value="$(CompPath)"/>
+ </Other>
+ </CompilerOptions>
+</CONFIG>
diff --git a/dcm2nii/dcm2nii.lpr b/dcm2nii_prePARRECDTI/dcm2nii.lpr
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2nii.lpr
copy to dcm2nii_prePARRECDTI/dcm2nii.lpr
diff --git a/dcm2nii/dcm2nii.or b/dcm2nii_prePARRECDTI/dcm2nii.or
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2nii.or
copy to dcm2nii_prePARRECDTI/dcm2nii.or
diff --git a/dcm2nii_prePARRECDTI/dcm2nii.res b/dcm2nii_prePARRECDTI/dcm2nii.res
new file mode 100755
index 0000000..c7fb1f5
Binary files /dev/null and b/dcm2nii_prePARRECDTI/dcm2nii.res differ
diff --git a/dcm2nii/dcm2nii48.ico b/dcm2nii_prePARRECDTI/dcm2nii48.ico
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2nii48.ico
copy to dcm2nii_prePARRECDTI/dcm2nii48.ico
diff --git a/dcm2nii/dcm2niigui.cfg b/dcm2nii_prePARRECDTI/dcm2niigui.cfg
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2niigui.cfg
copy to dcm2nii_prePARRECDTI/dcm2niigui.cfg
diff --git a/dcm2nii/dcm2niigui.dof b/dcm2nii_prePARRECDTI/dcm2niigui.dof
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2niigui.dof
copy to dcm2nii_prePARRECDTI/dcm2niigui.dof
diff --git a/dcm2nii/dcm2niigui.dpr b/dcm2nii_prePARRECDTI/dcm2niigui.dpr
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2niigui.dpr
copy to dcm2nii_prePARRECDTI/dcm2niigui.dpr
diff --git a/dcm2nii/dcm2niigui.ico b/dcm2nii_prePARRECDTI/dcm2niigui.ico
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2niigui.ico
copy to dcm2nii_prePARRECDTI/dcm2niigui.ico
diff --git a/dcm2nii/dcm2niigui.ini b/dcm2nii_prePARRECDTI/dcm2niigui.ini
old mode 100644
new mode 100755
similarity index 89%
copy from dcm2nii/dcm2niigui.ini
copy to dcm2nii_prePARRECDTI/dcm2niigui.ini
index cf8f638..99e6b8a
--- a/dcm2nii/dcm2niigui.ini
+++ b/dcm2nii_prePARRECDTI/dcm2niigui.ini
@@ -18,7 +18,7 @@ enablereorient=1
OrthoFlipXDim=0
EveryFile=1
fourD=1
-Gzip=0
+Gzip=1
ManualNIfTIConv=1
PhilipsPrecise=0
RecursiveUseNameAppend=0
@@ -29,6 +29,9 @@ Swizzle4D=1
UseGE_0021_104F=0
[INT]
+BeginClip=0
+LastClip=0
+usePigz=1
MaxReorientMatrix=1023
MinReorientMatrix=200
RecursiveFolderDepth=5
@@ -39,3 +42,4 @@ SiemensDTIStackIf00181020atleast=15
[STR]
OutDir=C:\Users\neuropsych\Documents
+
diff --git a/dcm2nii/dcm2niigui.lpi b/dcm2nii_prePARRECDTI/dcm2niigui.lpi
old mode 100644
new mode 100755
similarity index 69%
copy from dcm2nii/dcm2niigui.lpi
copy to dcm2nii_prePARRECDTI/dcm2niigui.lpi
index 8f3b0a2..061950e
--- a/dcm2nii/dcm2niigui.lpi
+++ b/dcm2nii_prePARRECDTI/dcm2niigui.lpi
@@ -13,9 +13,6 @@
<Icon Value="0"/>
<ActiveWindowIndexAtStart Value="0"/>
</General>
- <VersionInfo>
- <StringTable ProductVersion=""/>
- </VersionInfo>
<BuildModes Count="1">
<Item1 Name="default" Default="True"/>
</BuildModes>
@@ -36,27 +33,27 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
- <Units Count="44">
+ <Units Count="46">
<Unit0>
<Filename Value="dcm2niigui.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="dcm2niigui"/>
- <WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="2" Y="1"/>
- <UsageCount Value="58"/>
+ <UsageCount Value="67"/>
</Unit0>
<Unit1>
<Filename Value="gui.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
+ <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="gui"/>
- <EditorIndex Value="0"/>
+ <EditorIndex Value="7"/>
<WindowIndex Value="0"/>
- <TopLine Value="1115"/>
- <CursorPos X="7" Y="1122"/>
- <UsageCount Value="58"/>
+ <TopLine Value="1088"/>
+ <CursorPos X="91" Y="1092"/>
+ <UsageCount Value="67"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
@@ -64,17 +61,19 @@
<Filename Value="dcm2niigui.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit2>
<Unit3>
<Filename Value="nifti_form.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="NIfTIForm"/>
+ <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="nifti_form"/>
- <TopLine Value="1"/>
- <CursorPos X="102" Y="2"/>
- <UsageCount Value="58"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="65"/>
+ <CursorPos X="37" Y="10"/>
+ <UsageCount Value="67"/>
</Unit3>
<Unit4>
<Filename Value="pref_form.pas"/>
@@ -82,154 +81,156 @@
<ComponentName Value="PrefsForm"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="pref_form"/>
- <WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="101" Y="146"/>
- <UsageCount Value="58"/>
+ <UsageCount Value="67"/>
</Unit4>
<Unit5>
<Filename Value="parconvert.pas"/>
<UnitName Value="parconvert"/>
<TopLine Value="91"/>
<CursorPos X="13" Y="93"/>
- <UsageCount Value="16"/>
+ <UsageCount Value="15"/>
</Unit5>
<Unit6>
<Filename Value="pref_form.lrs"/>
<TopLine Value="1"/>
<CursorPos X="4" Y="36"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit6>
<Unit7>
<Filename Value="..\..\lcl\lresources.pp"/>
<UnitName Value="LResources"/>
<TopLine Value="2628"/>
<CursorPos X="21" Y="2642"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit7>
<Unit8>
<Filename Value="dialogsx.pas"/>
<UnitName Value="dialogsx"/>
<TopLine Value="1"/>
<CursorPos X="33" Y="9"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit8>
<Unit9>
<Filename Value="readint.pas"/>
<UnitName Value="readint"/>
<TopLine Value="1"/>
<CursorPos X="15" Y="7"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit9>
<Unit10>
<Filename Value="readint.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit10>
<Unit11>
<Filename Value="usr\local\share\lazarus\lcl\nonwin32\messages.pp"/>
<UnitName Value="Messages"/>
<TopLine Value="1"/>
<CursorPos X="90" Y="12"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit11>
<Unit12>
<Filename Value="define_types.pas"/>
<UnitName Value="define_types"/>
<TopLine Value="1"/>
<CursorPos X="40" Y="2"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit12>
<Unit13>
<Filename Value="paramstrs.pas"/>
<UnitName Value="paramstrs"/>
+ <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
- <TopLine Value="75"/>
- <CursorPos X="99" Y="92"/>
- <UsageCount Value="20"/>
+ <TopLine Value="4"/>
+ <CursorPos X="16" Y="20"/>
+ <UsageCount Value="23"/>
+ <Loaded Value="True"/>
</Unit13>
<Unit14>
<Filename Value="niftiutil.pas"/>
<UnitName Value="niftiutil"/>
+ <IsVisibleTab Value="True"/>
+ <EditorIndex Value="8"/>
<WindowIndex Value="0"/>
- <TopLine Value="162"/>
- <CursorPos X="1" Y="155"/>
- <UsageCount Value="19"/>
+ <TopLine Value="220"/>
+ <CursorPos X="6" Y="236"/>
+ <UsageCount Value="22"/>
+ <Loaded Value="True"/>
</Unit14>
<Unit15>
<Filename Value="prefs.pas"/>
<UnitName Value="prefs"/>
+ <EditorIndex Value="11"/>
<WindowIndex Value="0"/>
- <TopLine Value="184"/>
- <CursorPos X="66" Y="210"/>
- <UsageCount Value="20"/>
+ <TopLine Value="178"/>
+ <CursorPos X="66" Y="213"/>
+ <UsageCount Value="23"/>
+ <Loaded Value="True"/>
</Unit15>
<Unit16>
<Filename Value="dicom.pas"/>
<UnitName Value="dicom"/>
- <WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="13"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
</Unit16>
<Unit17>
<Filename Value="dicomtypes.pas"/>
<UnitName Value="dicomtypes"/>
- <EditorIndex Value="8"/>
+ <EditorIndex Value="12"/>
<WindowIndex Value="0"/>
- <TopLine Value="623"/>
- <CursorPos X="26" Y="653"/>
- <UsageCount Value="13"/>
+ <TopLine Value="76"/>
+ <CursorPos X="17" Y="91"/>
+ <UsageCount Value="16"/>
<Loaded Value="True"/>
</Unit17>
<Unit18>
<Filename Value="filename.pas"/>
<UnitName Value="filename"/>
- <WindowIndex Value="0"/>
<TopLine Value="118"/>
<CursorPos X="55" Y="131"/>
- <UsageCount Value="14"/>
+ <UsageCount Value="13"/>
</Unit18>
<Unit19>
<Filename Value="userdir.pas"/>
<UnitName Value="userdir"/>
- <EditorIndex Value="6"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="21" Y="11"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <CursorPos X="1" Y="3"/>
+ <UsageCount Value="9"/>
</Unit19>
<Unit20>
<Filename Value="gzio2.pas"/>
<UnitName Value="gzio2"/>
<TopLine Value="762"/>
<CursorPos X="26" Y="788"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit20>
<Unit21>
<Filename Value="nii_crop.pas"/>
<UnitName Value="nii_crop"/>
<TopLine Value="36"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit21>
<Unit22>
<Filename Value="..\common\userdir.pas"/>
<UnitName Value="userdir"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="15"/>
- <UsageCount Value="14"/>
+ <UsageCount Value="13"/>
</Unit22>
<Unit23>
<Filename Value="..\common\define_types.pas"/>
<UnitName Value="define_types"/>
- <EditorIndex Value="7"/>
+ <EditorIndex Value="0"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="23" Y="21"/>
- <UsageCount Value="18"/>
+ <TopLine Value="3"/>
+ <CursorPos X="9" Y="29"/>
+ <UsageCount Value="21"/>
<Loaded Value="True"/>
</Unit23>
<Unit24>
@@ -237,116 +238,118 @@
<UnitName Value="gziod"/>
<TopLine Value="311"/>
<CursorPos X="98" Y="322"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit24>
<Unit25>
<Filename Value="convert.pas"/>
<UnitName Value="convert"/>
- <EditorIndex Value="4"/>
+ <EditorIndex Value="9"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="49" Y="14"/>
- <UsageCount Value="17"/>
+ <TopLine Value="304"/>
+ <CursorPos X="26" Y="1498"/>
+ <UsageCount Value="20"/>
<Loaded Value="True"/>
</Unit25>
<Unit26>
<Filename Value="..\common\gzio2.pas"/>
<UnitName Value="gzio2"/>
- <WindowIndex Value="0"/>
<TopLine Value="647"/>
<CursorPos X="8" Y="667"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
</Unit26>
<Unit27>
<Filename Value="nii_asl.pas"/>
<UnitName Value="nii_asl"/>
<TopLine Value="96"/>
<CursorPos X="7" Y="212"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit27>
<Unit28>
<Filename Value="..\common\GraphicsMathLibrary.pas"/>
<UnitName Value="GraphicsMathLibrary"/>
<TopLine Value="1"/>
<CursorPos X="10" Y="27"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit28>
<Unit29>
<Filename Value="..\common\dialogsx.pas"/>
<UnitName Value="dialogsx"/>
<TopLine Value="1"/>
<CursorPos X="33" Y="2"/>
- <UsageCount Value="16"/>
+ <UsageCount Value="15"/>
</Unit29>
<Unit30>
<Filename Value="LibTar.pas"/>
<UnitName Value="LibTar"/>
<TopLine Value="246"/>
<CursorPos X="35" Y="272"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit30>
<Unit31>
<Filename Value="untar.pas"/>
<UnitName Value="untar"/>
<TopLine Value="8"/>
<CursorPos X="38" Y="12"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit31>
<Unit32>
<Filename Value="dicomfastread.pas"/>
<UnitName Value="dicomfastread"/>
<TopLine Value="427"/>
<CursorPos X="15" Y="435"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</Unit32>
<Unit33>
<Filename Value="dicomcompat.pas"/>
<UnitName Value="dicomcompat"/>
- <EditorIndex Value="3"/>
+ <EditorIndex Value="6"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="95" Y="11"/>
- <UsageCount Value="19"/>
+ <TopLine Value="4719"/>
+ <CursorPos X="29" Y="4732"/>
+ <UsageCount Value="22"/>
<Loaded Value="True"/>
</Unit33>
<Unit34>
<Filename Value="lsjpeg.pas"/>
<UnitName Value="lsjpeg"/>
- <TopLine Value="4"/>
- <CursorPos X="92" Y="13"/>
- <UsageCount Value="16"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="45" Y="7"/>
+ <UsageCount Value="15"/>
</Unit34>
<Unit35>
<Filename Value="sortdicom.pas"/>
<UnitName Value="sortdicom"/>
- <TopLine Value="399"/>
- <CursorPos X="6" Y="411"/>
- <UsageCount Value="16"/>
+ <EditorIndex Value="3"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="381"/>
+ <CursorPos X="94" Y="388"/>
+ <UsageCount Value="19"/>
+ <Loaded Value="True"/>
</Unit35>
<Unit36>
<Filename Value=""/>
- <UsageCount Value="10"/>
- <DefaultSyntaxHighlighter Value="None"/>
+ <UsageCount Value="9"/>
</Unit36>
<Unit37>
<Filename Value="nii_orient.pas"/>
<UnitName Value="nii_orient"/>
<TopLine Value="6"/>
<CursorPos X="36" Y="9"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
</Unit37>
<Unit38>
<Filename Value="gui.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="3"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
</Unit38>
<Unit39>
<Filename Value="nii_math.pas"/>
<UnitName Value="nii_math"/>
<TopLine Value="576"/>
<CursorPos X="78" Y="592"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
</Unit39>
<Unit40>
<Filename Value="C:\Documents and Settings\chris\Desktop\scripter\unit1.pas"/>
@@ -355,167 +358,183 @@
<UnitName Value="Unit1"/>
<TopLine Value="34"/>
<CursorPos X="1" Y="35"/>
- <UsageCount Value="20"/>
+ <UsageCount Value="19"/>
</Unit40>
<Unit41>
<Filename Value="..\common\nifti_hdr.pas"/>
<UnitName Value="nifti_hdr"/>
- <EditorIndex Value="1"/>
+ <EditorIndex Value="4"/>
<WindowIndex Value="0"/>
- <TopLine Value="299"/>
- <CursorPos X="25" Y="310"/>
- <UsageCount Value="10"/>
+ <TopLine Value="1286"/>
+ <CursorPos X="52" Y="1296"/>
+ <UsageCount Value="13"/>
<Loaded Value="True"/>
</Unit41>
<Unit42>
<Filename Value="..\common\isgui.inc"/>
- <EditorIndex Value="2"/>
+ <EditorIndex Value="5"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="10" Y="1"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="13"/>
<Loaded Value="True"/>
</Unit42>
<Unit43>
<Filename Value="csaread.pas"/>
<UnitName Value="csaread"/>
- <IsVisibleTab Value="True"/>
- <EditorIndex Value="5"/>
<WindowIndex Value="0"/>
- <TopLine Value="211"/>
- <CursorPos X="32" Y="236"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <TopLine Value="217"/>
+ <CursorPos X="7" Y="221"/>
+ <UsageCount Value="9"/>
</Unit43>
+ <Unit44>
+ <Filename Value="..\..\..\..\..\..\Developer\lazarus\lcl\include\customform.inc"/>
+ <EditorIndex Value="10"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="2519"/>
+ <CursorPos X="28" Y="2532"/>
+ <UsageCount Value="13"/>
+ <Loaded Value="True"/>
+ </Unit44>
+ <Unit45>
+ <Filename Value="..\..\..\..\..\..\usr\local\share\fpcsrc\rtl\objpas\sysutils\sysinth.inc"/>
+ <EditorIndex Value="1"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="113"/>
+ <CursorPos X="81" Y="134"/>
+ <UsageCount Value="12"/>
+ <Loaded Value="True"/>
+ </Unit45>
</Units>
- <JumpHistory Count="29" HistoryIndex="28">
+ <JumpHistory Count="30" HistoryIndex="29">
<Position1>
- <Filename Value="gui.pas"/>
- <Caret Line="433" Column="3" TopLine="412"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="212" Column="24" TopLine="191"/>
</Position1>
<Position2>
- <Filename Value="gui.pas"/>
- <Caret Line="779" Column="25" TopLine="767"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="215" Column="23" TopLine="191"/>
</Position2>
<Position3>
- <Filename Value="gui.pas"/>
- <Caret Line="784" Column="22" TopLine="775"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="221" Column="236" TopLine="184"/>
</Position3>
<Position4>
- <Filename Value="..\common\nifti_hdr.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="222" Column="5" TopLine="209"/>
</Position4>
<Position5>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="203" Column="75" TopLine="193"/>
+ <Caret Line="408" Column="161" TopLine="406"/>
</Position5>
<Position6>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="1510" Column="22" TopLine="1493"/>
+ <Caret Line="3201" Column="104" TopLine="3166"/>
</Position6>
<Position7>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="1543" Column="89" TopLine="1535"/>
+ <Caret Line="3910" Column="26" TopLine="3876"/>
</Position7>
<Position8>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="1548" Column="95" TopLine="1535"/>
+ <Caret Line="4736" Column="18" TopLine="4719"/>
</Position8>
<Position9>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="1637" Column="59" TopLine="1621"/>
+ <Caret Line="5229" Column="24" TopLine="5190"/>
</Position9>
<Position10>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="3181" Column="39" TopLine="3174"/>
+ <Caret Line="4514" Column="76" TopLine="4497"/>
</Position10>
<Position11>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="3191" Column="42" TopLine="3180"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="8" Column="57" TopLine="1"/>
</Position11>
<Position12>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="3870" Column="11" TopLine="3853"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="41" Column="49" TopLine="13"/>
</Position12>
<Position13>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="3871" Column="25" TopLine="3853"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="145" Column="21" TopLine="117"/>
</Position13>
<Position14>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="4769" Column="40" TopLine="4745"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="159" Column="49" TopLine="147"/>
</Position14>
<Position15>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="4773" Column="40" TopLine="4745"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="190" Column="53" TopLine="172"/>
</Position15>
<Position16>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="4774" Column="55" TopLine="4746"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="217" Column="54" TopLine="207"/>
</Position16>
<Position17>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="5272" Column="41" TopLine="5244"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="232" Column="25" TopLine="225"/>
</Position17>
<Position18>
- <Filename Value="gui.pas"/>
- <Caret Line="4" Column="33" TopLine="1"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="246" Column="1" TopLine="230"/>
</Position18>
<Position19>
- <Filename Value="gui.pas"/>
- <Caret Line="12" Column="34" TopLine="1"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="256" Column="1" TopLine="239"/>
</Position19>
<Position20>
- <Filename Value="gui.pas"/>
- <Caret Line="809" Column="70" TopLine="776"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="289" Column="23" TopLine="265"/>
</Position20>
<Position21>
- <Filename Value="gui.pas"/>
- <Caret Line="840" Column="46" TopLine="810"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="313" Column="15" TopLine="290"/>
</Position21>
<Position22>
- <Filename Value="gui.pas"/>
- <Caret Line="841" Column="38" TopLine="811"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="321" Column="19" TopLine="298"/>
</Position22>
<Position23>
- <Filename Value="userdir.pas"/>
- <Caret Line="45" Column="64" TopLine="32"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="326" Column="1" TopLine="315"/>
</Position23>
<Position24>
- <Filename Value="dicomtypes.pas"/>
- <Caret Line="618" Column="9" TopLine="605"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="232" Column="25" TopLine="225"/>
</Position24>
<Position25>
- <Filename Value="dicomtypes.pas"/>
- <Caret Line="626" Column="26" TopLine="605"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="243" Column="21" TopLine="229"/>
</Position25>
<Position26>
- <Filename Value="dicomtypes.pas"/>
- <Caret Line="627" Column="26" TopLine="605"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="265" Column="38" TopLine="252"/>
</Position26>
<Position27>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="5277" Column="26" TopLine="5266"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="258" Column="7" TopLine="242"/>
</Position27>
<Position28>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="6293" Column="30" TopLine="6275"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="287" Column="41" TopLine="268"/>
</Position28>
<Position29>
- <Filename Value="csaread.pas"/>
- <Caret Line="16" Column="19" TopLine="1"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="295" Column="40" TopLine="276"/>
</Position29>
+ <Position30>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="317" Column="40" TopLine="298"/>
+ </Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
- <Version Value="9"/>
+ <Version Value="11"/>
<PathDelim Value="\"/>
- <Target>
- <Filename ApplyConventions="False"/>
- </Target>
<SearchPaths>
<OtherUnitFiles Value="..\common"/>
- <SrcPath Value="C:\lazarus\ideintf\"/>
+ <SrcPath Value="C:\lazarus\ideintf"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
@@ -524,6 +543,7 @@
</Parsing>
<Linking>
<Debugging>
+ <GenerateDebugInfo Value="False"/>
<UseLineInfoUnit Value="False"/>
<StripSymbols Value="True"/>
</Debugging>
diff --git a/dcm2nii/dcm2niigui.lpr b/dcm2nii_prePARRECDTI/dcm2niigui.lpr
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2niigui.lpr
copy to dcm2nii_prePARRECDTI/dcm2niigui.lpr
diff --git a/dcm2nii/dcm2niigui.lrs b/dcm2nii_prePARRECDTI/dcm2niigui.lrs
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2niigui.lrs
copy to dcm2nii_prePARRECDTI/dcm2niigui.lrs
diff --git a/dcm2nii_prePARRECDTI/dcm2niigui.manifest b/dcm2nii_prePARRECDTI/dcm2niigui.manifest
new file mode 100755
index 0000000..07fb624
--- /dev/null
+++ b/dcm2nii_prePARRECDTI/dcm2niigui.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="CompanyName.ProductName.YourApp" type="win32"/>
+ <description>Your application description here.</description>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
+ </dependentAssembly>
+ </dependency>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
\ No newline at end of file
diff --git a/dcm2nii_prePARRECDTI/dcm2niigui.or b/dcm2nii_prePARRECDTI/dcm2niigui.or
new file mode 100755
index 0000000..4a3628d
Binary files /dev/null and b/dcm2nii_prePARRECDTI/dcm2niigui.or differ
diff --git a/dcm2nii_prePARRECDTI/dcm2niigui.rc b/dcm2nii_prePARRECDTI/dcm2niigui.rc
new file mode 100755
index 0000000..71b1938
--- /dev/null
+++ b/dcm2nii_prePARRECDTI/dcm2niigui.rc
@@ -0,0 +1,7 @@
+#define RT_MANIFEST 24
+#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
+#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2
+#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3
+
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "dcm2niigui.manifest"
+MAINICON ICON "dcm2niigui.ico"
diff --git a/dcm2nii/dcm2niigui.res b/dcm2nii_prePARRECDTI/dcm2niigui.res
old mode 100644
new mode 100755
similarity index 72%
copy from dcm2nii/dcm2niigui.res
copy to dcm2nii_prePARRECDTI/dcm2niigui.res
index def481f..c682074
Binary files a/dcm2nii/dcm2niigui.res and b/dcm2nii_prePARRECDTI/dcm2niigui.res differ
diff --git a/dcm2nii/dicom.pas b/dcm2nii_prePARRECDTI/dicom.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dicom.pas
copy to dcm2nii_prePARRECDTI/dicom.pas
diff --git a/dcm2nii/dicomcompat.pas b/dcm2nii_prePARRECDTI/dicomcompat.pas
old mode 100644
new mode 100755
similarity index 94%
copy from dcm2nii/dicomcompat.pas
copy to dcm2nii_prePARRECDTI/dicomcompat.pas
index 2f3a5f6..3d2f941
--- a/dcm2nii/dicomcompat.pas
+++ b/dcm2nii_prePARRECDTI/dicomcompat.pas
@@ -82,6 +82,16 @@ begin
result := sec;
end;
+function AddIndent(lIndent: integer): string;
+var
+ i: integer;
+begin
+ result := '';
+ if lIndent < 1 then
+ exit;
+ for i := 1 to lIndent do
+ result := result +'|';
+end;
procedure read_ecat_data(var lDICOMdata: DICOMdata;lVerboseRead,lReadECAToffsetTables:boolean; var lHdrOK, lImageFormatOK: boolean; var lDynStr: string;lFileName: string);
label
@@ -691,7 +701,7 @@ end else if (not lFLoat) and (lDicomData.Allocbits_per_pixel > 16) then begin
lImageFormatOK := false;
end else if (lFloat) then begin //zebra change float check
//Msg('WARNING: The image '+lFileName+' uses floating point [real] numbers. The current software can only read integer data type Interfile images.');
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
//lImageFormatOK := false;
end;
333:
@@ -829,7 +839,7 @@ repeat
end;
3:begin
lDicomData.Allocbits_per_pixel := 32;
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
end;
else begin
lHdrEnd := true;
@@ -1059,7 +1069,7 @@ until (linPos >= FileSz) or (lHdrEnd){EOF(fp)};
//xlDicomData.Rotate180deg := true;
lImageFormatOK := true;
if (lFloat) then begin //zebra change float check
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
//lImageFormatOK := false;
end;
333:
@@ -2581,7 +2591,7 @@ begin
6: lDicomData.Allocbits_per_pixel := 64; //double
end;
if (lDT0 = 5) or (lDT0 = 6) then
- lDicomData.Float := true;
+ lDicomData.FloatData := true;
//xlDicomData.Storedbits_per_pixel := lDicomData.Allocbits_per_pixel;
//lImgNC_Type := lDT0;
end;
@@ -3160,11 +3170,21 @@ begin
result := strtoint(S);
end; *)
+function ExpectedDicomBytes (var lDICOMdata: DICOMdata): integer;
+begin
+ if lDicomData.JPEGLosslessCpt then begin
+ result := 0; //actual compressed size unknown
+ exit;
+ end;
+ result := lDicomdata.XYZdim[1]*lDicomdata.XYZdim[2]*lDicomdata.XYZdim[3]*(lDicomData.Allocbits_per_pixel DIV 8);
+end;
+
procedure read_dicom_data_compat(lReadJPEGtables,lVerboseRead,lAutoDECAT7,lReadECAToffsetTables,lAutoDetectInterfile,lAutoDetectGenesis,lReadColorTables: boolean; var lDICOMdata: DICOMdata; var lHdrOK, lImageFormatOK: boolean; var lDynStr: string;var lFileName: string; var lPrefs: TPrefs);
label 666,777;
const
-kMaxTextBuf = 50000; //maximum for screen output
-kDiskCache = 16384; //size of disk buffer
+ kMaxTextBuf = 50000; //maximum for screen output
+ kDiskCache = 16384; //size of disk buffer
+ kNaNsingle : single = 1/0;
type
dicom_types = (unknown, i8, i16, i32, ui8, ui16, ui32, _string{,_float} );
@@ -3412,8 +3432,12 @@ begin
remaining := 0;
//compute Distance between current slice and 1st slice...
lDx := sqrt( sqr(lX-lDicomData.PatientPosX)+sqr(lY-lDicomData.PatientPosY)+sqr(lZ-lDicomData.PatientPosZ));
- if (lDx > 0) and (lDx < lMinDistance) then //if 0 then this is a repeat, not a new slice
- lMinDistance := lDx;
+ if (lDx > 0) and (lMinDistance = kNaNsingle) then //first value
+ lMinDistance := lDx
+ else if (lDx > 0) and (lDx < lMinDistance) then //if 0 then this is a repeat, not a new slice
+ lMinDistance := lDx
+ else
+ exit;
end;
procedure readfloats6 (var fp: file; remaining: integer; var lOutStr: string; var lf1, lf2,lf3,lf4,lf5,lf6: double; var lReadOK: boolean);
@@ -3850,12 +3874,20 @@ begin
FreeMem( buff);
dseek(fp, lStartPos);
end;
-var lPrev0020: boolean;
+label 1234;
+var lIndent: integer;
+ lprevGroup, lprevElement: uint32;
+var lInside00209113, lInside2005140F, lPhilipsWarning: boolean;//philips can list two DIFFERENT spatial positions per slice - ignore the one hidden inside 2005,140FlPrev0020: boolean;
begin
//Init
//for lnVol := 1 to kMaxOrderVal do
// lDICOMdata.OrderSlope[lDICOMdata.nOrder] := 0; //show this was not set
- lPrev0020 := false;
+ lInside00209113 := false;
+ lprevGroup := 0;
+ lprevElement := 0;
+ lPhilipsWarning := false;
+ lIndent := 0;
+ lInside2005140F := false;
lSwitchToImplicitAfterGroup0002 := false;
lGELX := false;
lByteSwap := false;
@@ -3863,7 +3895,7 @@ begin
Clear_Dicom_Data(lDICOMdataBackUp);
lDicomData.XYZdim[1] := 1;
lImagePositionPatientRead := false;// for 4D files, we need first volume
- l4DDistanceBetweenSliceCenters := maxint;
+ l4DDistanceBetweenSliceCenters := kNaNsingle;
lEchoNum := 0;
lThickness := 0;
lTestError := false;
@@ -4578,14 +4610,16 @@ end; //not first_one or explicit
if e_len = ($FFFFFFFF) then begin
e_len := 0;
end;
-if lGELX then begin
- e_len := e_len and $FFFF;
-end;
+ if lGELX then begin
+ e_len := e_len and $FFFF;
+ end;
first_one := false;
remaining := e_len;
info := '?';
tmpstr := '';
-
+ if (lIndent > 0) and (not ((group= $FFFE) and (element = $E0DD))) and (not lManufacturerIsPhilips) then
+ //Philips stores slice positioning inside 0020,9113; lice orientation inside 0020,9116 but Siemens stores thumbnails in indented subheadings
+ goto 1234;
case group of
$0001 : // group for normal reading elscint DICOM
case element of
@@ -4612,9 +4646,10 @@ end;
else TmpStr := TmpStr +('.');
FreeMem( buff);
lStr := '';
+ //Msg(TmpStr);
if TmpStr = '1.2.840.113619.5.2' then begin
lGELX := true;
- LBigSet := true;
+ LBigSet := true;
lBig := true;
end;
//
@@ -4624,6 +4659,7 @@ end;
// explicitVR := false; //china
lSwitchToImplicitAfterGroup0002 := true;
end;
+
if length(TmpStr) >= 19 then begin
if TmpStr[19] = '1' then begin
@@ -4636,20 +4672,18 @@ end;
lBig := true;
end else if TmpStr[19] = '4' then begin
if length(TmpStr) >= 21 then begin
- //lDicomData.JPEGCpt := true;
- if not lReadJPEGtables then begin
+ //Dec 2012.... dcm2nii can handle JPEG 123456
+ if {not lReadJPEGtables} false then begin
lImageFormatOK := false;
end else begin
i := strtoint(TmpStr[21]+TmpStr[22]);
- //if (TmpStr[22] <> '0') or ((TmpStr[21] <> '7') or (TmpStr[21] <> '0'))
-
-
if (i <> 57) and (i <> 70) then begin
lImageFormatOK := false;
//lDicomData.JPEGLossyCpt := true
end else begin
- //lImageFormatOK := false;//x
+
+ //lImageFormatOK := false;//123456
lDicomData.JPEGLosslessCpt := true;
end;
end;
@@ -4662,7 +4696,7 @@ end;
lImageFormatOK := false;
end;
if not lImageFormatOK then
- Msg('Unsupported Transfer Syntax '+(TmpStr)+' Solution: use MRIcro');
+ Msg('Unsupported Transfer Syntax '+(TmpStr)+' Solution: use MRIcro');
end; {length}
remaining := 0;
@@ -4692,27 +4726,27 @@ end;
end;
$01 : info := 'Length to End';
$05 : info := 'Specific Character Set';
- $08 : begin
+ $08 : begin
info := 'Image Type';
- //Only read last word, e.g. 'TYPE\MOSAIC' will be read as 'MOSAIC'
- TmpStr := '';
if dFilePos(fp) > (filesz-e_len) then goto 666;
- GetMem( buff, e_len);
- dBlockRead(fp, buff{^}, e_len, n);
- i := e_len -1;
- while (i>-1) and (Char(buff[i]) in ['a'..'z','A'..'Z',' ']) do begin
- if (Char(buff[i])) <> ' ' then //strip filler characters: DICOM elements must be padded for even length
- TmpStr := upcase(Char(buff[i]))+TmpStr;
+ lSiemensMosaic0008_0008:= false;
+ if (e_len >= 6) then begin //search for 'MOSAIC'
+ GetMem( buff, e_len);
+ dBlockRead(fp, buff{^}, e_len, n);
+ i := e_len -6;//MOSAIC
+ while (i>-1) and (not lSiemensMosaic0008_0008) do begin
+ if (upcase(Char(buff[i])) = 'M') and (upcase(Char(buff[i+1])) = 'O')
+ and (upcase(Char(buff[i+2])) = 'S') and (upcase(Char(buff[i+3])) = 'A')
+ and (upcase(Char(buff[i+4])) = 'I') and (upcase(Char(buff[i+5])) = 'C')
+ then //strip filler characters: DICOM elements must be padded for even length
+ lSiemensMosaic0008_0008 := true;
dec(i);
- end;
- FreeMem( buff);
- remaining := 0;
- e_len := 0; {use tempstr}
- if TmpStr = 'MOSAIC' then begin
- lSiemensMosaic0008_0008:= true;
- //if lMatrixSz < 1 then lMatrixSz := 64;//B13
- end;
- end;
+ end;
+ FreeMem( buff);
+ remaining := 0;
+ e_len := 0; {use tempstr}
+ end;
+ end;
$10 : info := 'Recognition Code';
$12 : info := 'Instance Creation Date';
$13 : info := 'Instance Creation Time';
@@ -4928,7 +4962,7 @@ end;
readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
if not lrOK then goto 666;
e_len := 0; remaining := 0;
- //lDicomData.kV := lFloat1;
+ lDicomData.kV := lFloat1;
end;
$70: begin t := _string; info := 'Counts Accumulated'; end;
@@ -5186,6 +5220,13 @@ $0019: begin
if lDicomData.ManufacturerID = kSiemensID then begin
case element of //1362
+ (* $100A: begin //unsigned short $100A
+ info := 'Number Of Images in Mosaic';
+ tmp := read16(fp,lrOK);
+ if not lrOK then goto 666;
+ fx(e_len,tmp,remaining);
+
+ end;*)
$000C,$100C: begin
info := 'Siemens b-value';
readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
@@ -5280,22 +5321,32 @@ $0020 :
$32 : begin
info := 'Image Position Patient';
//June 2009 - for Philips new 4D format we want value from the first slice...
- if lPrev0020 then begin //5/2012: Philips R3.2.2 can save two instances of 0020:0032 for each slice: one from voxel center, one from voxel edge.
- if not lImagePositionPatientRead then begin
- readfloats3 (fp, remaining, lDummyStr, lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ, lROK);
- //fx( lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ,56789);
- if not lrOK then goto 666;
- e_len := 0;
- remaining := 0;
- lImagePositionPatientRead := true;
- //we assume Philips reports the slice thickness correctly....
- //an alternative would be to read both 1st and 2nd ImagePositionPatient and
- //compute the function DICOMinterslicedistance
+
+ if lInside2005140F then begin
+ if not (lPhilipsWarning) then
+ Msg('*User: check slice thickness. Possible Philips R3.2.2 bug - scanner can report different 0020,0032 values for the same slice.');
+ lPhilipsWarning := true;
end else begin
+ //5/2012: Philips R3.2.2 can save two instances of 0020:0032 for each slice: one from voxel center, one from voxel edge.
+
+ if not lImagePositionPatientRead then begin
+ readfloats3 (fp, remaining, lDummyStr, lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ, lROK);
+ //fx( lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ,56789);
+ if not lrOK then goto 666;
+ e_len := 0;
+ remaining := 0;
+ lImagePositionPatientRead := true;
+ //we assume Philips reports the slice thickness correctly....
+ //an alternative would be to read both 1st and 2nd ImagePositionPatient and
+ //compute the function DICOMinterslicedistance
+ end else begin
+
CheckIntersliceDistance(l4DDistanceBetweenSliceCenters);
- end;
- end;
+ end; //not 1st read
+
+ end; //if lInside2005140F
+ //lInside2005140F := false;
end;
$35 : info := 'Image Orientation';
$37 : begin //nifti
@@ -5341,6 +5392,7 @@ $0020 :
$4000: info := 'Image Comments';
$5000: info := 'Original Image ID';
$5002: info := 'Original Image... Nomenclature';
+ //$9113: xxxx
end;
$0021:case element of
$104F: begin
@@ -5473,18 +5525,19 @@ $0028 : begin
if tmp = 8 then lDicomData.Allocbits_per_pixel := 8
else if tmp = 12 then lDicomData.Allocbits_per_pixel := 12
else if tmp = 16 then lDicomData.Allocbits_per_pixel := 16
+ else if tmp = 32 then lDicomData.Allocbits_per_pixel := 32
else if tmp = 24 then begin
//xlDicomData.SamplesPerPixel := 3;
lDicomData.Allocbits_per_pixel := 8
end else begin
lWord := tmp;
lWord := swap(lWord);
- if lWord in [8,12,16,24] then begin
+ if lWord in [8,12,16,24,32] then begin
lDicomData.Allocbits_per_pixel := tmp;
lByteSwap := true;
end else begin
if lImageFormatOK then
- Msg('This software only reads 8, 12 and 16 bit DICOM files. This file allocates '+inttostr(tmp)+' bits per voxel.');
+ Msg('This software only reads 8, 12, 16, 24 [RGB] and 32 bit DICOM files. This file allocates '+inttostr(tmp)+' bits per voxel.');
lImageFormatOK := false;
end;
end;
@@ -5787,12 +5840,16 @@ end; //$0028
case element of
$1010: begin
//lSiemensMosaic0029_1010:= true;
+ if (lDicomData.kV = 0) then begin //Siemens uses 0029:1010 for both CT and MRI, but only MRI is in CSA format
lDicomData.CSAImageHeaderInfoPos := (dFilePos(fp));
lDicomData.CSAImageHeaderInfoSz := e_len;
+ end;
info := 'Private Sequence Delimiter ['+inttostr(dFilePos(fp))+']';
- if not lImageFormatOK
+ if not lImageFormatOK then
+ time_to_quit := TRUE;
+
//x(lDicomData.RunLengthEncoding) or ( ((lDicomData.JPEGLossycpt) or (lDicomData.JPEGLosslesscpt)) and (gECATJPEG_table_entries >= lDICOMdata.XYZdim[3]))}
- then time_to_quit := TRUE;
+
dSeek(fp, dFilePos(fp) + e_len);
tmpstr := inttostr(e_len);
remaining := 0;
@@ -5911,6 +5968,10 @@ end; //$0028
//if lDicomData.ManufacturerID = kPhilipsID then Msg(inttohex(element,4));
if lDicomData.ManufacturerID = kPhilipsID then begin
case element of
+ { $140F: begin
+ lInside2005140F := true;
+
+ end;}
$100E: begin
if e_len = 4 then begin
lPhilipsScaleSlope := read32r(fp,lrOK);
@@ -5995,6 +6056,19 @@ end; //$0028
end //element 9230
end; //case element
end; //group 5200
+ $5400 : begin
+ case element of
+ $0100: begin
+ //can not convert sound files to images 12/2012
+ lImageFormatOK := false;
+ msg('Note: the DICOM file '+lFileName+' stores a waveform sequence (e.g. ECG) that will not be converted to an image');
+ info :='WaveformSequence';
+ //fx(lDICOMdata.DTI[lDICOMdata.nDTIdir].v1,lDICOMdata.DTI[lDICOMdata.nDTIdir].v2,lDICOMdata.DTI[lDICOMdata.nDTIdir].v3);
+ if not lrOK then goto 666;
+ e_len := 0; remaining := 0;
+ end //element 0100
+ end; //case element
+ end; //group 5400
$DDFF : begin
case element of
$00E0: begin
@@ -6006,6 +6080,10 @@ end; //$0028
$FFFE : begin
case element of
$E000 : begin
+ inc(lIndent);
+ lInside00209113 := (lprevGroup = $0020) and (lprevelement = $9113);
+ lInside2005140F := (lprevGroup = $2005) and (lprevelement = $140F);
+ // if (lInside00209113) then fx(333);
(*iif lJPEGEntries > 17 then
lTestError := true;
@@ -6053,9 +6131,10 @@ lProprietaryImageThumbnail := false; //1496
lFirstFragment := false;//Dec09
lDICOMdataBackUp := lDICOMData;//Dec09
- if (e_len >= (lDicomData.XYZdim[1]*lDicomData.XYZdim[2])){Apr 2011} and (lDicomData.XYZdim[1]> 1) then begin
+ if ((e_len > 1024) and ((lDicomData.JPEGLosslessCpt)) or (e_len >= (lDicomData.XYZdim[1]*lDicomData.XYZdim[2]))){Apr 2011} and (lDicomData.XYZdim[1]> 1) then begin
lDICOMdata.CompressOffset := dFilePos(fp);
lDICOMdata.CompressSz := e_len;
+
Time_To_Quit := true;
//msg('abba'+inttostr(lDICOMdata.CompressOffset)+' '+inttostr(lDICOMdata.CompressSz));
end;
@@ -6069,6 +6148,9 @@ lProprietaryImageThumbnail := false; //1496
e_len := 0;
end;
$E0DD : begin
+ if (lIndent > 0) then dec(lIndent);
+ lInside00209113 := false;
+ lInside2005140F := false;
info := 'Sequence Delimiter';
if (lDICOMdata.XYZdim[1]<lDICOMdataBackUp.XYZdim[1]) then begin
lDICOMData := lDICOMdataBackUp;
@@ -6076,7 +6158,6 @@ lProprietaryImageThumbnail := false; //1496
//lDICOMData := lDICOMdataBackUp;
end else if not lImageFormatOK then begin
//x(lDicomData.RunLengthEncoding) or ( ((lDicomData.JPEGLossycpt) or (lDicomData.JPEGLosslesscpt)) and (gECATJPEG_table_entries >= lDICOMdata.XYZdim[3])) then
-
time_to_quit := TRUE;
end;
//RLE ABBA
@@ -6111,12 +6192,13 @@ lProprietaryImageThumbnail := false; //1496
$10 : begin
info := 'Pixel Data';
TmpStr := inttostr(e_len);
- if (lDICOMdata.XYZdim[1]<lDICOMdataBackUp.XYZdim[1]) then begin
+ //Showmsg(inttostr(ExpectedDicomBytes(lDicomData) ) +' '+ inttostr(e_len));
+ if ((ExpectedDicomBytes(lDicomData) ) > e_len) or (lDICOMdata.XYZdim[1]<lDICOMdataBackUp.XYZdim[1]) then begin
lDICOMData := lDICOMdataBackUp;
- dSeek(fp, dFilePos(fp) + e_len);
- //lDICOMData := lDICOMdataBackUp;
- end else if {(not lDicomData.RunLengthEncoding) and} (not lDicomData.JPEGLossycpt) and (not lDicomData.JPEGLosslesscpt) then begin
- time_to_quit := TRUE;
+ dSeek(fp, dFilePos(fp) + e_len);
+ //lDICOMData := lDICOMdataBackUp;
+ end else if {(not lDicomData.RunLengthEncoding) and} (not lDicomData.JPEGLossycpt) and (not lDicomData.JPEGLosslesscpt) then begin
+ time_to_quit := TRUE;
//xlDicomData.ImageSz := e_len;
end;
@@ -6138,12 +6220,9 @@ lProprietaryImageThumbnail := false; //1496
end;
lStr := '';
- if group = $0020 then
- lPrev0020 := true
- else
- lPrev0020 := false;
-
-
+ 1234:
+ lprevGroup := Group;
+ lprevElement := element;
if (Time_TO_Quit) and (not lImageFormatOK) then begin
lHdrOK := true;
goto 666;
@@ -6250,7 +6329,8 @@ if length(lDynStr) > kMaxTextBuf then begin
//goto 666;
end else
lDynStr := lDynStr+IntToHex(group,4)+','+IntToHex(element,4)+','+Info+'='+lStr+kCR ;
- Msg(IntToHex(group,4)+','+IntToHex(element,4)+','+inttostr(e_len)+'@'+inttostr(dfilepos(fp))+','+Info+'='+lStr);
+
+ Msg(AddIndent(lIndent)+IntToHex(group,4)+','+IntToHex(element,4)+','+inttostr(e_len)+'@'+inttostr(dfilepos(fp))+','+Info+'='+lStr);
end; //not verbose read
end; // end for
@@ -6272,7 +6352,7 @@ if lByteSwap then begin
//xByteSwap(lDicomData.Storedbits_per_pixel);
end;
-if (lDICOMdata.ManufacturerID = kPhilipsID) and (l4DDistanceBetweenSliceCenters <> MaxInt) then //some 3D and 4D Philips files do not correctly report interslice distance in 0018,0088 and 0018,0050...
+if (lDICOMdata.ManufacturerID = kPhilipsID) and (l4DDistanceBetweenSliceCenters <> kNaNsingle) then //some 3D and 4D Philips files do not correctly report interslice distance in 0018,0088 and 0018,0050...
lDICOMdata.XYZmm[3] := (l4DDistanceBetweenSliceCenters);
if (lPrefs.PhilipsPrecise) and (lManufacturerIsPhilips) and (lPhilipsScaleSlope <> 0) then begin
PhilipsPrecise (lDicomData.IntenScale, lDICOMdata.intenIntercept,lPhilipsScaleSlope, lDicomData.IntenScale, lDICOMdata.intenIntercept,true);
@@ -6322,10 +6402,12 @@ if lManufacturerIsBruker then
if (lEchoNum > 0) and (lEchoNum < 16) then begin
lDicomData.AcquNum := lDicomData.AcquNum + (1000*lEchoNum);
-end;
+end;
+
if lVerboseRead then begin
+ // lDicomData.PatientPosX, lDicomData.PatientPosY,lDicomData.PatientPosZ
Msg ('DICOM data');
- Msg ('Image Series/Number/Xpos/YPos/ZPos:'+kTab+inttostr(lDicomData.AcquNum)+kTab+inttostr(lDicomData.ImageNum)+kTab+floattostr(lDicomData.PatientPosX)+kTab+floattostr(lDicomData.PatientPosY)+kTab+floattostr(lDicomData.PatientPosZ));
+ Msg ('Series/Acquisition/Image/Xpos/YPos/ZPos:'+kTab+inttostr(lDicomData.SeriesNum)+kTab+inttostr(lDicomData.AcquNum)+kTab+inttostr(lDicomData.ImageNum)+kTab+floattostr(lDicomData.PatientPosX)+kTab+floattostr(lDicomData.PatientPosY)+kTab+floattostr(lDicomData.PatientPosZ));
Msg ('BPP: '+inttostr(lDicomData.Allocbits_per_pixel));
Msg ('XYZ dim:' +inttostr(lDicomData.XYZdim[1])+'/'+inttostr(lDicomData.XYZdim[2])+'/'+inttostr(lDicomData.XYZdim[3]) );
Msg ('XYZ mm:'+floattostrf(lDicomData.XYZmm[1],ffFixed,8,2)+'/'+floattostrf(lDicomData.XYZmm[2],ffFixed,8,2)+'/'+floattostrf(lDicomData.XYZmm[3],ffFixed,8,2) );
@@ -6347,4 +6429,4 @@ if lVerboseRead then begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/dicomfast.pas b/dcm2nii_prePARRECDTI/dicomfast.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dicomfast.pas
copy to dcm2nii_prePARRECDTI/dicomfast.pas
diff --git a/dcm2nii/dicomfastread.pas b/dcm2nii_prePARRECDTI/dicomfastread.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dicomfastread.pas
copy to dcm2nii_prePARRECDTI/dicomfastread.pas
diff --git a/dcm2nii/dicomtypes.pas b/dcm2nii_prePARRECDTI/dicomtypes.pas
old mode 100644
new mode 100755
similarity index 96%
copy from dcm2nii/dicomtypes.pas
copy to dcm2nii_prePARRECDTI/dicomtypes.pas
index 7b2199c..8f61a4e
--- a/dcm2nii/dicomtypes.pas
+++ b/dcm2nii_prePARRECDTI/dicomtypes.pas
@@ -29,9 +29,9 @@ end;
XYZori: array [1..3] of integer;
XYZmm: array [1..3] of double;
Orient: array [1..6] of double;
- SignedData,SiemensDICOMDTICSA,SiemensDICOMDTI,Float,file4D,JPEGLossyCpt,JPEGLosslessCpt: boolean;
+ SignedData,SiemensDICOMDTICSA,SiemensDICOMDTI,FloatData,file4D,JPEGLossyCpt,JPEGLosslessCpt: boolean;
SecSinceMidnight,PatientPosX,PatientPosY,PatientPosZ,AngulationAP,AngulationFH,AngulationRL: double;
- TE, TR,IntenScale,IntenIntercept,location{,DTIv1,DTIv2,DTIv3}: single;
+ kV,TE, TR,IntenScale,IntenIntercept,location{,DTIv1,DTIv2,DTIv3}: single;
{Bval,}SlicesPer3DVol,SiemensInterleaved {0=no,1=yes,2=not defined},SiemensSlices,SiemensMosaicX,SiemensMosaicY,
nOrder,nDTIdir,AcquNum,ImageNum,SeriesNum,ImageStart,little_endian,Allocbits_per_pixel,SamplesPerPixel,
CSAImageHeaderInfoPos,CSAImageHeaderInfoSz,ManufacturerID,PlanarConfig, //ImplementationVersion,
@@ -629,6 +629,7 @@ begin
Orient[lI] := 0;
DateTime := BogusDateTime;
ManufacturerID := 0;
+ kV := 0;
//ImplementationVersion := 0;
Vers0018_1020 := 0;
AngulationFH := 0;
@@ -670,7 +671,7 @@ begin
//MaxIntensity := 0;
//MinIntensity := 0;
//MinIntensitySet := false;
- Float := false;
+ FloatData := false;
ImageNum := -1;
SlicesPer3DVol := 0;
SiemensInterleaved := 2; //0=no,1=yes,2=undefined
diff --git a/dcm2nii/diskfree.pas b/dcm2nii_prePARRECDTI/diskfree.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/diskfree.pas
copy to dcm2nii_prePARRECDTI/diskfree.pas
diff --git a/dcm2nii/extrafpc.cfg b/dcm2nii_prePARRECDTI/extrafpc.cfg
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/extrafpc.cfg
copy to dcm2nii_prePARRECDTI/extrafpc.cfg
diff --git a/dcm2nii/filename.pas b/dcm2nii_prePARRECDTI/filename.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/filename.pas
copy to dcm2nii_prePARRECDTI/filename.pas
diff --git a/dcm2nii/fpc-res.or b/dcm2nii_prePARRECDTI/fpc-res.or
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/fpc-res.or
copy to dcm2nii_prePARRECDTI/fpc-res.or
diff --git a/dcm2nii/gui.dfm b/dcm2nii_prePARRECDTI/gui.dfm
old mode 100644
new mode 100755
similarity index 91%
copy from dcm2nii/gui.dfm
copy to dcm2nii_prePARRECDTI/gui.dfm
index 3aee9ac..9961827
Binary files a/dcm2nii/gui.dfm and b/dcm2nii_prePARRECDTI/gui.dfm differ
diff --git a/dcm2nii/gui.lfm b/dcm2nii_prePARRECDTI/gui.lfm
old mode 100644
new mode 100755
similarity index 95%
copy from dcm2nii/gui.lfm
copy to dcm2nii_prePARRECDTI/gui.lfm
index 716b790..3861a66
--- a/dcm2nii/gui.lfm
+++ b/dcm2nii_prePARRECDTI/gui.lfm
@@ -1,22 +1,23 @@
object MainForm: TMainForm
- Left = 685
+ Left = 355
Height = 363
- Top = 174
+ Top = 132
Width = 598
ActiveControl = Panel1
AllowDropFiles = True
Caption = 'dcm2nii'
- ClientHeight = 344
+ ClientHeight = 363
ClientWidth = 598
Menu = MainMenu1
OnClose = FormClose
OnCreate = FormCreate
OnDropFiles = FormDropFiles
OnShow = FormShow
- LCLVersion = '0.9.30.4'
+ Position = poScreenCenter
+ LCLVersion = '1.0.8.0'
object Memo1: TMemo
Left = 4
- Height = 306
+ Height = 325
Top = 34
Width = 590
Align = alClient
@@ -50,10 +51,10 @@ object MainForm: TMainForm
end
object TypeCombo: TComboBox
Left = 160
- Height = 21
+ Height = 20
Top = 3
Width = 264
- ItemHeight = 13
+ ItemHeight = 0
Items.Strings = (
'SPM2 (3D Anlyze hdr/img)'
'SPM5 (3D NIfTI hdr/img)'
diff --git a/dcm2nii_prePARRECDTI/gui.lrs b/dcm2nii_prePARRECDTI/gui.lrs
new file mode 100755
index 0000000..8bd9c3e
--- /dev/null
+++ b/dcm2nii_prePARRECDTI/gui.lrs
@@ -0,0 +1,47 @@
+{ This is an automatically generated lazarus resource file }
+
+LazarusResources.Add('TMainForm','FORMDATA',[
+ 'TPF0'#9'TMainForm'#8'MainForm'#4'Left'#3'c'#1#6'Height'#3'k'#1#3'Top'#3#132#0
+ +#5'Width'#3'V'#2#13'ActiveControl'#7#6'Panel1'#14'AllowDropFiles'#9#7'Captio'
+ +'n'#6#7'dcm2nii'#12'ClientHeight'#3'k'#1#11'ClientWidth'#3'V'#2#4'Menu'#7#9
+ +'MainMenu1'#7'OnClose'#7#9'FormClose'#8'OnCreate'#7#10'FormCreate'#11'OnDrop'
+ +'Files'#7#13'FormDropFiles'#6'OnShow'#7#8'FormShow'#8'Position'#7#14'poScree'
+ +'nCenter'#10'LCLVersion'#6#7'1.0.8.0'#0#5'TMemo'#5'Memo1'#4'Left'#2#4#6'Heig'
+ +'ht'#3'E'#1#3'Top'#2'"'#5'Width'#3'N'#2#5'Align'#7#8'alClient'#18'BorderSpac'
+ +'ing.Left'#2#4#19'BorderSpacing.Right'#2#4#20'BorderSpacing.Bottom'#2#4#10'S'
+ +'crollBars'#7#14'ssAutoVertical'#8'TabOrder'#2#0#0#0#6'TPanel'#6'Panel1'#4'L'
+ +'eft'#2#0#6'Height'#2'"'#3'Top'#2#0#5'Width'#3'V'#2#5'Align'#7#5'alTop'#10'B'
+ +'evelOuter'#7#6'bvNone'#12'ClientHeight'#2'"'#11'ClientWidth'#3'V'#2#8'TabOr'
+ +'der'#2#1#0#6'TLabel'#6'Label1'#4'Left'#2#1#6'Height'#2#26#3'Top'#2#5#5'Widt'
+ +'h'#3#140#0#9'Alignment'#7#14'taRightJustify'#7'Anchors'#11#6'akLeft'#0#8'Au'
+ +'toSize'#8#7'Caption'#6#16'Output Format: '#6'Layout'#7#8'tlCenter'#11'Pare'
+ +'ntColor'#8#0#0#9'TComboBox'#9'TypeCombo'#4'Left'#3#160#0#6'Height'#2#20#3'T'
+ +'op'#2#3#5'Width'#3#8#1#10'ItemHeight'#2#0#13'Items.Strings'#1#6#24'SPM2 (3D'
+ +' Anlyze hdr/img)'#6#23'SPM5 (3D NIfTI hdr/img)'#6#19'SPM8 (3D NIfTI nii)'#6
+ +#16'4D NIfTI hdr/img'#6#23'FSL/SPM8 (4D NIfTI nii)'#6#29'Compressed FSL (4D '
+ +'NIfTI nii)'#0#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#0#0#0#0#11'TOpenD'
+ +'ialog'#10'OpenHdrDlg'#11'FilterIndex'#2#0#4'left'#2#24#3'top'#2'0'#0#0#9'TM'
+ +'ainMenu'#9'MainMenu1'#4'left'#2'X'#3'top'#2'0'#0#9'TMenuItem'#5'File1'#7'Ca'
+ +'ption'#6#4'File'#0#9'TMenuItem'#13'DICOMtoNIfTI1'#7'Caption'#6#14'DICOM to '
+ +'NIfTI'#8'ShortCut'#3'D@'#7'OnClick'#7#15'dcm2niiBtnClick'#0#0#9'TMenuItem'
+ +#12'ModifyNIfTI1'#7'Caption'#6#12'Modify NIfTI'#7'OnClick'#7#17'ModifyNIfTI1'
+ +'Click'#0#0#9'TMenuItem'#10'NIfTI3D4D1'#7'Caption'#6#14'NIfTI 3D -> 4D'#7'On'
+ +'Click'#7#15'NIfTI3D4D1Click'#0#0#9'TMenuItem'#15'AnonymizeDICOM1'#7'Caption'
+ +#6#15'Anonymize DICOM'#7'OnClick'#7#20'AnonymizeDICOM1Click'#0#0#9'TMenuItem'
+ +#5'Exit1'#7'Caption'#6#4'Exit'#7'OnClick'#7#10'Exit1Click'#0#0#0#9'TMenuItem'
+ +#5'Edit1'#7'Caption'#6#4'Edit'#0#9'TMenuItem'#5'Copy1'#7'Caption'#6#4'Copy'#7
+ +'OnClick'#7#10'Copy1Click'#0#0#0#9'TMenuItem'#12'UntestedMenu'#7'Caption'#6#8
+ +'Untested'#0#9'TMenuItem'#17'MirrorXdimension1'#7'Caption'#6#18'Mirror X-dim'
+ +'ension'#7'OnClick'#7#22'MirrorXdimension1Click'#0#0#9'TMenuItem'#7'SumTPM1'
+ +#7'Caption'#6#7'Sum TPM'#7'OnClick'#7#12'SumTPM1Click'#0#0#9'TMenuItem'#17'E'
+ +'xtractDICOMdims1'#7'Caption'#6#18'Extract DICOM dims'#7'OnClick'#7#22'Extra'
+ +'ctDICOMdims1Click'#0#0#9'TMenuItem'#16'ExtractDICOMhdr1'#7'Caption'#6#20'Ex'
+ +'tract DICOM header'#7'OnClick'#7#21'ExtractDICOMhdr1Click'#0#0#9'TMenuItem'
+ +#17'ExtractNIfTIhdrs1'#7'Caption'#6#20'Extract NIfTI header'#7'OnClick'#7#22
+ +'ExtractNIfTIhdrs1Click'#0#0#9'TMenuItem'#10'HalveMenu1'#7'Caption'#6#25'Hal'
+ +'ve dimensions in-plane'#7'OnClick'#7#15'HalveMenu1Click'#0#0#0#9'TMenuItem'
+ +#5'Help1'#7'Caption'#6#4'Help'#0#9'TMenuItem'#12'Preferences1'#7'Caption'#6
+ +#11'Preferences'#7'OnClick'#7#17'Preferences1Click'#0#0#9'TMenuItem'#6'About'
+ +'1'#7'Caption'#6#4'Help'#7'OnClick'#7#11'About1Click'#0#0#0#0#22'TSelectDire'
+ +'ctoryDialog'#22'SelectDirectoryDialog1'#4'left'#3#159#0#3'top'#2'6'#0#0#0
+]);
diff --git a/dcm2nii/gui.pas b/dcm2nii_prePARRECDTI/gui.pas
old mode 100644
new mode 100755
similarity index 95%
copy from dcm2nii/gui.pas
copy to dcm2nii_prePARRECDTI/gui.pas
index f548fda..6627c27
--- a/dcm2nii/gui.pas
+++ b/dcm2nii_prePARRECDTI/gui.pas
@@ -2,7 +2,7 @@ unit gui;
{$IFDEF FPC}{$mode objfpc}{$H+}{$ENDIF}
interface
uses
-{$IFDEF FPC}LResources,{$ENDIF}
+{$IFDEF FPC}LResources,LCLIntf, {$ENDIF}
{$IFNDEF UNIX} Windows,ShellAPI,ShlObj,
{$ELSE}
BaseUnix,LCLType,
@@ -175,6 +175,8 @@ begin
result := NiftiForm.Combo3D.ItemIndex;
end;
+
+
procedure ProcessNIfTI(lFilenames : TStrings; lPrefs: TPrefs);
var
l4D, lPrev4D, lByteSwap: boolean;
@@ -183,6 +185,8 @@ var
lHdr: TNIFTIhdr;
begin
if lFilenames.Count < 1 then exit;
+ //CheckHugeUint16(lFilenames.Strings[0], false);
+
lPrev4D := false; //ignored in if statement - set only to avoid compiler warning
lProcess := 0; //always set in if statement - set only to avoid compiler warning
for lInc := 1 to lFilenames.Count do begin
@@ -256,11 +260,16 @@ begin
PromptOutput ( lPrefs);
result := true;
//3/2011... do not clear here, so we can look across images... Memo1.lines.clear;
- MsgX(kVers);
- refresh;
+ //MsgX(kVers);
Memo1.lines.add('Converting '+lFilename);
+ Memo1.Repaint;
+ MainForm.Repaint;
+ MainForm.Update;
+ refresh;
+
+
lOutDir := extractfiledir(lFilename);
- {$IFNDEF UNIX}lStartTime := GetTickCount;{$ENDIF}
+ lStartTime := GetTickCount;
if DirExists(lFilename) then begin
RecursiveFolderSearch(lFilename,lFilename,lPrefs,0);
lPrefs.NameAppend := '';
@@ -287,10 +296,7 @@ begin
lPrefs.NameAppend := '';
end;
end;
- {$IFNDEF UNIX}Memo1.lines.add('Conversion completed in '+inttostr(GetTickCount-lStartTime)+' ms');
- {$ELSE}
- Memo1.lines.add('Conversion completed');
- {$ENDIF}
+ Memo1.lines.add('Conversion completed in '+inttostr(GetTickCount-lStartTime)+' ms');
end;
function ShowHeader (lFilename: string): boolean;
@@ -473,6 +479,14 @@ begin
//Memo1.Lines.Add(kVers);
DecimalSeparator := '.';
Application.HintHidePause := 30000;
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+ DICOMtoNIfTI1.ShortCut := ShortCut(Word('D'), [ssMeta]);
+ Copy1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ Preferences1.ShortCut := ShortCut(Word('P'), [ssMeta]);
+ About1.ShortCut := ShortCut(Word('A'), [ssMeta]);
+ {$ENDIF}//Carbon
+ {$ENDIF}//Darwin
end;
@@ -1104,6 +1118,7 @@ begin
exit;
lDirName := extractfiledir( OpenHdrDlg.Filename);
{$ENDIF}
+ Memo1.lines.Clear;
ConvertDCM2NII(lDirName,lPrefs);
end;
@@ -1148,4 +1163,4 @@ finalization
{$ENDIF}
end.
-
+
\ No newline at end of file
diff --git a/dcm2nii/guii.lrs b/dcm2nii_prePARRECDTI/guii.lrs
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/guii.lrs
copy to dcm2nii_prePARRECDTI/guii.lrs
diff --git a/dcm2nii/lsjpeg.pas b/dcm2nii_prePARRECDTI/lsjpeg.pas
old mode 100644
new mode 100755
similarity index 73%
copy from dcm2nii/lsjpeg.pas
copy to dcm2nii_prePARRECDTI/lsjpeg.pas
index 2ed121f..30dc1bb
--- a/dcm2nii/lsjpeg.pas
+++ b/dcm2nii_prePARRECDTI/lsjpeg.pas
@@ -1,751 +1,777 @@
-unit lsjpeg;
-{//$DEFINE Stream}
-//rev13: changes by CR and JGS
-//rev19: uses Lookup table for decoding Huffman table: this doubles the speed
-interface
- {$H+}
-
-uses
-dialogsx,
-{$IFNDEF UNIX}
- //windows,
-{$ENDIF}
- sysutils,define_types,classes;
-type
- HufRA = record
- HufSz,HufCode,HufVal: Integer;
- end;
-{$IFDEF Stream}
- procedure DecodeJPEG(var lStream: TMemoryStream; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
-{$ELSE}
- procedure DecodeJPEG(var infp: file; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
-{$ENDIF}
-implementation
-
-{$IFDEF Stream}
- procedure DecodeJPEG(var lStream: TMemoryStream; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
-{$ELSE}
-procedure DecodeJPEG(var infp: file; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
-{$ENDIF}
-const
- kmaxFrames = 4;
-label
- 666 {EOF};
- var
- lRawRA: bytep;
- lImgRA: WordP;
- lHufVal,lAbba,lOffset,lLineStart,lPredicted,lPredictedG,lPredictedB,lRestartSegmentSz,
- lSz,k,Code,Si,lIncX,lIncY,lInc,lPredA,lPredB,lPredC,lCurrentBitPos,btS1,btS2, btMarkerType,
- DHTnLi,DHTtcth,SOFprecision,SOSpttrans, SOFnf,SOFarrayPos,SOSns,SOSarrayPos,SOSss,SOSse,SOSahal:integer;//byte;
- lHufTable,lnHufTables,{lDecode,}lImgStart,lRawSz,lRawPos,lItems,SOFydim, SOFxdim: integer;
- lMaxHufSi,lMaxHufVal: array [1..kmaxFrames] of integer;
- DHTLiRA,DHTstartRA: array [1..kmaxFrames,0..31] of integer;//byte;
- lBitMask: array [1..17] of integer;
- lSSSSszRA: array [1..kMaxFrames,0..17] of byte;
- lLookUpRA: array [1..kMaxFrames,0..255] of byte; //lists all possible SSSS with <= 8bits
- lHufRA: array [1..kMaxFrames,0..31] of HufRA;
- lFrameCount,lSegmentLength,lSegmentEnd,lI: integer;
- lImgTypeC3,lHdrOK: boolean;
-function ReadBit: integer; //Read the next single bit
-begin
- result := (lRawRA^[lRawPos] shr (7-lCurrentBitPos)) and 1;
- lCurrentBitPos := lCurrentBitPos + 1;
- if (lCurrentBitPos = 8) then begin
- lRawPos := 1+lRawPos;
- lCurrentBitPos := 0;
- end;
-end;
-
-
-
-function ReadBits ( lNum: integer): integer; //lNum: bits to read, not to exceed 16
-begin
- result := lRawRA^[lRawPos];
- result := result shl 8 + lRawRA^[lRawPos+1];
- result := result shl 8 + lRawRA^[lRawPos+2];
- result := (result shr (24-lCurrentBitPos-lNum)) and lBitMask[lNum]; //lCurrentBitPos is incremented from 1, so -1
- lCurrentBitPos := lCurrentBitPos + lNum;
- if (lCurrentBitPos > 7) then begin
- lRawPos := lRawPos+(lCurrentBitPos shr 3);
- lCurrentBitPos := (lCurrentBitPos and 7);
- end;
-end;
-
-function DecodePixelDifference( lFrame: integer): integer;//Red/Green/Blue each a separate 'Frame': can have unique huffman tables
-var
- lByte,lHufValSSSS,lInput,lInputbits,lDiff,lI: integer;
-begin
- // read one byte from the stream, without modifying the pointer
- lByte := (lRawRA^[lRawPos] shl lCurrentBitPos) + (lRawRA^[lRawPos+1] shr (8-lCurrentBitPos));
- lByte := lByte and 255;
- lHufValSSSS := lLookUpRA[lFrame,lByte];
- //lLookUpRA: array [1..kMaxFrames,0..255] of byte; //lists all possible SSSS with <= 8bits
- if lHufValSSSS < 255 then begin
- lCurrentBitPos := lSSSSszRA[lFrame,lHufValSSSS] + lCurrentBitPos;
- lRawPos := lRawPos + (lCurrentBitpos shr 3);
- lCurrentBitpos := lCurrentBitpos and 7;
- //AdvanceBitPos(lSSSSszRA[lFrame,lSSSS]), but inlined;
- end else begin //full SSSS is not in the first 8-bits
- if (lByte < 0) or (lByte > 255) then msg('lsjeg error');
- lInput := lByte;
- lInputBits := 8;
- inc(lRawPos); // forward 8 bits = precisely 1 byte
- repeat
- Inc(lInputBits);
- lInput := lInput shl 1 + ReadBit;
- if DHTLiRA[lFrame,lInputBits] <> 0 then begin //if any entires with this length
- for lI := DHTstartRA[lFrame,lInputBits] to (DHTstartRA[lFrame,lInputBits]+DHTLiRA[lFrame,lInputBits]-1) do begin
- if (lInput = lHufRA[lFrame,lI].HufCode) then
- lHufValSSSS := lHufRA[lFrame,lI].HufVal;
- end; //check each code
- end; //if any entires with this length
- if (lInputBits >= lMaxHufSi[lFrame]) and (lHufValSSSS > 254) then begin//exhausted options CR: added rev13
- lHufValSSSS := lMaxHufVal[lFrame];
- end;
- until (lHufValSSSS < 255);
- end; //answer in first 8 bits
- //The HufVal is referred to as the SSSS in the Codec, so it is called 'lHufValSSSS'
- case lHufValSSSS of
- 0: result:= 0;
- 1: if ReadBit = 0 then result := -1 else result := 1;
- (*BELOW only a tiny bit faster to separate 2..15 into 2..9 and 10..15, requires extra procedure and more
- 2..9: begin //see 10..15 for explanation
- lDiff := ReadBits2_9(lHufValSSSS);
- if (lDiff > (lBitMask[lHufValSSSS-1])) then //add
- result := lDiff
- else //negation
- result := lDiff - lBitMask[lHufValSSSS];
- end; //2..9 *)
- 2..15: begin
- //Osiris includes extra bits after SSSS=16...a violation of the standard See "TABLE H.2 - Difference categories for lossless Huffman coding" of the codec ITU-T81
- //According to the Codec H.1.2.2 "No extra bits are appended after SSSS = 16 is encoded."
- //To patch for Osiris Change case from 2..15 to 2..16
- // This will work for Osiris images, but will break non-Osiris images
- lDiff := ReadBits(lHufValSSSS);
- if (lDiff > (lBitMask[lHufValSSSS-1])) then //add
- result := lDiff
- // this is slightly unintuitive: the positive bit is identical to the offset shown in TABLE H.2, a slower but more intuitive way to do this is:
- //result := (lDiff and lBitMask[lHufVal-1]) + (1 shl (lHufval-1));
- //where you clip off the sign bit and then SHL appropriately
- else //negation
- result := lDiff - lBitMask[lHufValSSSS];
- //NEXT to lines are a bit more intuitive:
- //lDiff := lBitMask[lHufVal-1]- lDiff;
- //result := -(lDiff + (1 shl (lHufval-1)));//negation
- end; //10..15
- else //16, not osiris
- result := 32768;
- end; //case HuffVal
-end; //func DecodePixelDifference
-
-procedure ReadByte(var lByte: integer);
-begin
- inc(lRawPos);
- lByte := lRawRA^[lRawPos];
-end;
-
-function ReadWord: word;
-var
- lbtL1, lbtL2: byte;
-begin
- inc(lRawPos);
- lbtL1 := lRawRA^[lRawPos];
- inc(lRawPos);
- lbtL2 := lRawRA^[lRawPos];
- result := (256 * lbtL1 + lbtL2)
-end;
-//NEXT: main procedure
- begin
- lAbba := 4;
- lnHufTables := 0;
- lRawSz := lCptSize;
- lRawPos := 0;
- lRestartSegmentSz := 0;
- lImgTypeC3 := false;
- SOFxdim:= 1;
- if lRawSz < 32 then goto 666;
- for lFrameCount := 1 to kMaxFrames do
- for lInc := 1 to 16 do
- DHTstartRA[lFrameCount,lInc] := 0;
- SOFydim := 1;
- SOSpttrans := 0;
- lHdrOK := false;
- SOFnf := 0;
- SOSns := 0;
- GetMem( lRawRA, lRawSz);
-{$IFDEF Stream}
- lStream.Seek(lCptPosition, soFromBeginning);
- lStream.readBuffer(lRawRA^, lRawSz);
-{$ELSE}
- Seek(infp,lCptPosition);
- BlockRead(infp, lRawRA^, lRawSz);
-{$ENDIF}
- ReadByte(btS1);
- ReadByte(btS1);
- repeat
- repeat
- if lRawPos <= lRawSz then ReadByte(btS1);
- if btS1 <> $FF then begin
- goto 666;
- end;
- if lRawPos <= lRawSz then ReadByte( btMarkerType);
- case btMarkerType of //only process segments with length fields
- $0,$1,$D0..$D7,$FF: btMarkerType := 0; //0&FF = fillers, $1=TEM,$D0..D7=resync
- end;
- until (lRawPos >= lRawSz) or (btMarkerType <> 0);
- lSegmentLength := ReadWord;
- lSegmentEnd := lRawPos+(lSegmentLength - 2);
- if lSegmentEnd > lRawSz then goto 666;
- if (btMarkerType = $C3) then
- lImgTypeC3 := true;
- if lverbose then msg( inttohex(btMarkerType,2));
- case btMarkerType of
- $0: ; //filler - ignore
- $C0..$C3,$C5..$CB,$CD..$CF: begin //read SOF FrameHeader
- ReadByte(SOFprecision);
- SOFydim := ReadWord;
- SOFxdim:= ReadWord;
- ReadByte(SOFnf);
- if lverbose then msg('[precision:'+inttostr(SOFprecision)+' X*Y:'+inttostr(SOFxdim)+'*'+inttostr(SOFydim)+'nFrames:'+inttostr(SOFnf)+'] ');
- if (not lImgTypeC3) or ((SOFnf <> 1) and (SOFnf <> 3)) then begin
- msg('Unable to extract this file format.');
- end;
- SOFarrayPos := lRawPos;
- lRawPos := (lSegmentEnd);
- end; //SOF FrameHeader
- $C4: begin //DHT Huffman
- if lverbose then msg( 'HuffmanLength'+inttostr(lSegmentLength)+':');
- //if SOFnf <1 then SOFnf := 1; //we may not know SOFnf yet!
- lFrameCount := 1;
- repeat
- ReadByte( DHTtcth);
- //msg(inttostr(lFrameCount)+'@'+inttostr(DHTtcth and 15)+'x'+inttostr(DHTtcth ));
- DHTnLi := 0;
- for lInc := 1 to 16 do begin
- ReadByte(DHTliRA[lFrameCount,lInc]);
- DHTnLi := DHTnLi + DHTliRA[lFrameCount,lInc];
- if DHTliRA[lFrameCount,lInc] <> 0 then lMaxHufSi[lFrameCount] := lInc;
- //msg(inttostr(DHTliRA[lFrameCount,lInc])+'@'+inttostr(lMaxHufSi));
- end;
- if DHTnLi > 17 then begin
- msg('Huffman table corrupted.');
- goto 666;
- end;
- lIncY := 0; //frequency
-
- for lInc := 0 to 31 do begin
- lHufRA[lFrameCount, lInc].HufVal := -1;
- lHufRA[lFrameCount, lInc].HufSz := -1;
- lHufRA[lFrameCount, lInc].HufCode := -1;
- end;
-
- for lInc := 1 to 16 do begin //set the huffman size values
- if DHTliRA[lFrameCount,lInc]> 0 then begin
- DHTstartRA[lFrameCount,lInc] := lIncY+1;
- for lIncX := 1 to DHTliRA[lFrameCount,lInc] do begin
- inc(lIncY);
- ReadByte(btS1);
- lHufRA[lFrameCount,lIncY].HufVal := btS1;
- lMaxHufVal[lFrameCount] := btS1;
- if (btS1 >= 0) and (btS1 <= 16) then
- lHufRA[lFrameCount,lIncY].HufSz := lInc
- else begin
- msg('Huffman size array corrupted.');
- goto 666;
- end;
- end;
- end; //Length of size lInc > 0
- end;
- //msg('Max bits:'+inttostr(lMaxHufSi)+' SSSS:'+inttostr(lMaxHufVal));
- K := 1;
- Code := 0;
- Si := lHufRA[lFrameCount,K].HufSz;//HuffSizeRA[1];
- repeat
- while (Si = lHufRA[lFrameCount,K].HufSz) do begin
- lHufRA[lFrameCount,K].HufCode := Code;
- //msg('bits: '+inttostr(Si)+' NthEntry:'+inttostr(K)+' Code:'+inttostr(Code));
- Code := Code + 1;
- Inc(K);
- end;
- if K <= DHTnLi then begin
- while lHufRA[lFrameCount,K].HufSz > Si do begin
- Code := Code Shl 1;
- Si := Si + 1;
- end; //while Si
- end; //K <= 17
- until K > DHTnLi;// JGS added rev13
- inc(lFrameCount);
- until (lSegmentEnd-lRawPos) < 18;
- lnHufTables := lFrameCount - 1;
- //msg(inttostr(lnHufTables));
- lRawPos := (lSegmentEnd);
- end; //$C4: DHT Huffman
- $DD: begin //Define Restart
- lRestartSegmentSz := Readword;
- lRawPos := (lSegmentEnd);
- end;
- $DA: begin //read SOS Scan Header
- if SOSns > 0 then goto 666; //multiple SOS!
- ReadByte(SOSns);
- //if Ns = 1 then NOT interleaved, else interleaved: see B.2.3
- SOSarrayPos := lRawPos;
- if SOSns > 0 then begin
- for lInc := 1 to SOSns do begin
- ReadByte( btS1); //component identifier 1=Y,2=Cb,3=Cr,4=I,5=Q
- ReadByte(btS2); //horizontal and vertical sampling factors
- end;
- end;
- ReadByte(SOSss); //predictor selection B.3
- ReadByte( SOSse);
- ReadByte( SOSahal); //lower 4bits= pointtransform
- SOSpttrans := SOSahal and 16;
- if lverbose then
- msg('[Predictor: '+inttostr(SOSss)+' PointTransform:'+inttostr(SOSahal)+'] ');
- lRawPos := (lSegmentEnd);
- end; //$DA SOS - Scan Header
- else begin //skip marker segment;
- lRawPos := (lSegmentEnd);
- end;
- end; //case markertype
- until (lRawPos >= lRawSz) or (btMarkerType = $DA); {hexDA=Start of scan}
- lHdrOK := true; //errors goto label 666, so are NOT OK
- lImgStart := lRawPos;
-666:
- if not lHdrOK then begin
- msg('Unable to read this file - is this really a JPEG image?');
- exit;
- end;
- if (not lImgTypeC3) then exit; //lossless compressed huffman tables
- //NEXT: unpad data - delete byte that follows $FF
- lINc := lRawPos;
- lIncX := lRawPos;
- repeat
- lRawRA^[lIncX] := lRawRA^[lInc];
- if lRawRA^[lInc] = 255 then begin
- if (lRawRA^[lInc+1] = $00) then
- lInc := lInc+1
- else begin
- //msg(inttostr(lRawRA^[lInc+1]));
- if (lRawRA^[lInc+1] = $D9) then //end of image
- lIncX := -666; //end of padding
- end;
- end;
- inc(lInc);
- inc(lIncX);
- until lIncX < 0;
- //End: Data unpadding
- //NEXT: Create Huffman LookupTable.
- //We will compute all possible outcomes for an 8-bit value, while less intuitive than
- //reading Huffman 1 bit at a time, it doubles the decompression speed
- lBitMask[1]:= 1;
- lBitMask[2]:= 3;
- lBitMask[3]:= 7;
- lBitMask[4]:= 15;
- lBitMask[5]:= 31;
- lBitMask[6]:= 63;
- lBitMask[7]:= 127;
- lBitMask[8]:= 255;
- lBitMask[9]:= 511;
- lBitMask[10]:= 1023;
- lBitMask[11]:= 2047;
- lBitMask[12]:= 4095;
- lBitMask[13]:= 8191;
- lBitMask[14]:= 16383;
- lBitMask[15]:= 32767;
- lBitMask[16]:= 65535;
- lBitMask[17]:= 131071; //ONLY required for Osiris corrupted images, see DecodePixelDifference for details
- //NEXT: some RGB images use only a single Huffman table for all 3 colour planes. In this case, replicate the correct values
- if (lnHufTables < SOFnf) then begin //use single Hufman table for each frame
- //msg('generating tables'+inttostr(SOFnf));
- if lnHufTables < 1 then begin
- msg('Lossless JPEG decoding error: no Huffman tables.');
- exit;
- end;
- for lFrameCount := 2 to SOFnf do begin
- for lInc := 1 to 16 do
- DHTstartRA[lFrameCount,lInc] := DHTstartRA[1,lInc];
- for lInc := 0 to 31 do begin
- lHufRA[lFrameCount,lInc].HufCode := lHufRA[1,lInc].HufCode;
- lHufRA[lFrameCount,lInc].HufVal := lHufRA[1,lInc].HufVal;
- lHufRA[lFrameCount,lInc].HufSz := lHufRA[1,lInc].HufSz;
- DHTliRA[lFrameCount,lInc] := DHTliRA[1,lInc];
- end; //for each table entry
- end; //for each frame xx
- end;// if lnHufTables < SOFnf
- for lFrameCount := 1 to kMaxFrames do
- for lInc := 0 to 17 do
- lSSSSszRA[lFrameCount,lInc] := 123; //Impossible value for SSSS, suggests 8-bits can not describe answer
- for lFrameCount := 1 to kMaxFrames do
- for lInc := 0 to 255 do
- lLookUpRA[lFrameCount,lInc] := 255; //Impossible value for SSSS, suggests 8-bits can not describe answer
- //NEXT fill lookuptable
- for lFrameCount := 1 to SOFnf do begin
- lIncY := 0;
- for lSz := 1 to 8 do begin //set the huffman lookup table for keys with lengths <=8
- if DHTliRA[lFrameCount,lSz]> 0 then begin
- for lIncX := 1 to DHTliRA[lFrameCount,lSz] do begin
- inc(lIncY);
- lHufVal := lHufRA[lFrameCount,lIncY].HufVal; //SSSS
- {if (lHufVal < 0) or (lHufVal > 17) then begin
- msg('Unknown SSSS =' +inttostr(lHufVal));
- lHufVal := 16;
- end; }
- lSSSSszRA[lFrameCount,lHufVal] := lSz;
- k := (lHufRA[lFrameCount,lIncY].HufCode shl (8-lSz )) and 255; //K= most sig bits for hufman table
- if lSz < 8 then begin //fill in all possible bits that exceed the huffman table
- lInc := lBitMask[8-lSz];
- for lCurrentBitPos := 0 to lInc do begin
- lLookUpRA[lFrameCount,k+lCurrentBitPos] := lHufVal;
- end;
- end else
- lLookUpRA[lFrameCount,k] := lHufVal; //SSSS
-
- {msg('Frame ' + inttostr(lFrameCount) + ' SSSS= '+inttostr(lHufRA[lFrameCount,lIncY].HufVal)+
- ' Size= '+inttostr(lHufRA[1,lIncY].HufSz)+
- ' Code= '+inttostr(lHufRA[1,lIncY].HufCode)+
- ' SHL Code= '+inttostr(k)+
- ' EmptyBits= '+inttostr(lInc)); }
- end; //Set SSSS
- end; //Length of size lInc > 0
- end; //for lInc := 1 to 8
- end; //For each frame, e.g. once each for Red/Green/Blue
- //Next: uncompress data: different loops for different predictors
- SOFxdim:= SOFnf*SOFxdim;
- lItems := SOFxdim*SOFydim;
- //if lVerbose then msg('precision'+inttostr(SOFprecision));
- //for timing, multiple decoding loops lRawAbba := lRawPos;for lLoopsAbba := 1 to 100 do begin lRawPos := lRawAbba;
- //if (lRestartSegmentSz > 0) and ((SOFPrecision<> 8) or (SOSss = 7)) then //add restart support if we ever find any samples to test
- // msg('This image uses restart markers. Please contact the author. Predictor:Precision '+inttostr(SOSss)+':'+inttostr(SOFPrecision));
- inc(lRawPos);//abbax
- lCurrentBitPos := 0; //read in a new byte
- //lCurrentBitPos := 1; //read in a new byte
- lItems := SOFxdim*SOFydim;
- lPredicted := 1 shl (SOFPrecision-1-SOSpttrans);
- lInc := 0;
- if (SOFPrecision<> 8) then begin //start - 16 bit data
- lImgRA := @lOutSmallRA[0];{set to 1 for MRIcro, else 0}
- FillChar(lImgRA^,lItems*sizeof(word), 0); //zero array
- lPredB:= 0;
- lPredC := 0;
- case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
- 2: lPredA:= SOFxDim-1; //Rb directly above
- 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
- 4,5: begin
- lPredA := 0;
- lPredB := SOFxDim-1; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- 6: begin
- lPredB := 0;
- lPredA := SOFxDim-1; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- else lPredA := 0; //Ra: directly to left
- end; //case SOSss: predictor offset
- for lIncX := 1 to SOFxdim do begin
- inc(lInc); //writenext voxel
- if lInc > 1 then lPredicted := lImgRA^[lInc-1];
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //first line: use prev voxel prediction;
-
-
- if lRestartSegmentSz = 0 then begin
- for lIncY := 2 to SOFyDim do begin
- inc(lInc); //write next voxel
- lPredicted := lImgRA^[lInc-SOFxdim];
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- if SOSss = 4 then begin
- for lIncX := 2 to SOFxdim do begin
- lPredicted := lImgRA^[lInc-lPredA]+lImgRA^[lInc-lPredB]-lImgRA^[lInc-lPredC];
- inc(lInc); //writenext voxel
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //for lIncX
- end else if (SOSss = 5) or (SOSss = 6) then begin
- for lIncX := 2 to SOFxdim do begin
- lPredicted := lImgRA^[lInc-lPredA]+ ((lImgRA^[lInc-lPredB]-lImgRA^[lInc-lPredC]) shr 1);
- inc(lInc); //writenext voxel
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //for lIncX
- end else if SOSss = 7 then begin
- for lIncX := 2 to SOFxdim do begin
- inc(lInc); //writenext voxel
- lPredicted := (lImgRA^[lInc-1]+lImgRA^[lInc-SOFxdim]) shr 1;
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //for lIncX
- end else begin //SOSss 1,2,3 read single values
- for lIncX := 2 to SOFxdim do begin
- lPredicted := lImgRA^[lInc-lPredA];
- inc(lInc); //writenext voxel
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- end; //for lIncX
- end; //SOSss predictor
-
-
- end; //for lIncY
- end {RestartSegmentSz = 0} else begin {restartsegment}
- if SOSss > 3 then
- msg('Unusual 16-bit lossless JPEG with restart segments. Please contact the author:'+inttostr(SOSss));
- lSegmentEnd := lRestartSegmentSz;
- repeat
- if lSegmentEnd > lItems then lSegmentEnd := lItems;
- lLineStart := (((lInc div SOFxDim)+1)* SOFxDim){-1};
- if lInc > (SOFxDim+1) then
- lPredicted := 1 shl (SOFPrecision-1-SOSpttrans)
- else
- lPredicted := lImgRA^[lInc-SOFxdim];
-
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRA^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRA^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredicted := lImgRA^[lInc-lPredA];
- end;
- if (lSegmentEnd+1) < lItems then begin
- dec(lRawPos);
- repeat
- while (lRawRA^[lRawPos] <> 255) do
- inc(lRawPos);
- inc(lRawPos);
- until (lRawRA^[lRawPos] >= $D0) and (lRawRA^[lRawPos] <= $D7);
- lCurrentBitPos := 0; //read in a new byte
- inc(lRawPos);//abbax
- end;
- lSegmentEnd := lSegmentEnd + lRestartSegmentSz;
- until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
- end; //restartsegments
- end else if SOFnf = 3 then begin //>8bit data; 8 bit follows
- //LOSSLESS JPEG: 7 possible predictors - we will handle all of them
- lPredB:= 0;
- lPredC := 0;
- case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
- 2: lPredA:= SOFxDim-3; //Rb directly above
- 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
- 5: begin
- lPredA := 0;
- lPredB := SOFxDim-3; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- 6: begin
- lPredB := 0;
- lPredA := SOFxDim-3; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- else lPredA := 0; //Ra: directly to left
- end; //case SOSss: predictor offset
- lPredictedG := lPredicted;
- lPredictedB := lPredicted;
- lOffset := 0;
- lInc := lOffset;
- for lIncX := 1 to (SOFxdim div 3) do begin //write first line
- //DecodePixelDifference=RED
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- lPredicted := lImgRAz^[lInc];
- inc(lInc); //writenext voxel
- //DecodePixelDifference=GREEN
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2);
- lPredictedG := lImgRAz^[lInc];
- inc(lInc); //writenext voxel
- //DecodePixelDifference=BLUE
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3);
- lPredictedB := lImgRAz^[lInc];
- inc(lInc); //writenext voxel
- end; //first line: use prev voxel prediction;
- if lRestartSegmentSz = 0 then lSegmentEnd := lItems
- else lSegmentEnd := lRestartSegmentSz;
- repeat
- if lSegmentEnd > lItems then lSegmentEnd := lItems;
- lLineStart := (((lInc div SOFxDim)+1)* SOFxDim)+lOffset{-1};
- if lInc > (SOFxDim+1) then begin
- lPredicted := 1 shl (SOFPrecision-1-SOSpttrans);
- lPredictedG := lPredicted;
- lPredictedB := lPredicted;
- end else begin
- lPredicted := lImgRAz^[lInc-SOFxdim+lOffset];
- lPredictedG := lImgRAz^[1+lInc-SOFxdim+lOffset];
- lPredictedB := lImgRAz^[2+lInc-SOFxdim+lOffset];
- end;
- if SOSss = 4 then begin //predictor = 4
- //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
- while lInc < (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1); //RED
- inc(lInc);
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
- inc(lInc);
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
- inc(lInc);
- if lInc = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc-SOFxdim];
- lPredictedG := lImgRAz^[lInc-SOFxdim+1];
- lPredictedB := lImgRAz^[lInc-SOFxdim+2];
- lLineStart := lLineStart + (SOFxDim);
- end else begin
- lPredicted := lImgRAz^[lInc-3]+lImgRAz^[lInc-3-(SOFxDim-3)]-lImgRAz^[lInc-3-SOFxDim];
- lPredictedG := lImgRAz^[lInc-2]+lImgRAz^[lInc-2-(SOFxDim-3)]-lImgRAz^[lInc-2-SOFxDim];
- lPredictedB := lImgRAz^[lInc-1]+lImgRAz^[lInc-1-(SOFxDim-3)]-lImgRAz^[lInc-1-SOFxDim];
- end;
- end;
- //xxx
- end else if (SOSss = 5) or (SOSss = 6) then begin //predictor = 5 or 6
- //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
- while lInc < (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1); //RED
- inc(lInc);
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
- inc(lInc);
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
- inc(lInc);
- if lInc = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc-SOFxdim];
- lPredictedG := lImgRAz^[lInc-SOFxdim+1];
- lPredictedB := lImgRAz^[lInc-SOFxdim+2];
- lLineStart := lLineStart + (SOFxDim);
- end else begin
- lPredicted := lImgRAz^[lInc-3-lPredA]+((lImgRAz^[lInc-3-lPredB]-lImgRAz^[lInc-3-lPredC])shr 1);
- lPredictedG := lImgRAz^[lInc-2-lPredA]+((lImgRAz^[lInc-2-lPredB]-lImgRAz^[lInc-2-lPredC])shr 1);
- lPredictedB := lImgRAz^[lInc-1-lPredA]+((lImgRAz^[lInc-1-lPredB]-lImgRAz^[lInc-1-lPredC])shr 1);
- end;
- end;
- end else if SOSss = 7 then begin //predictor = 7
- while lInc < (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1); //RED
- inc(lInc);
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
- inc(lInc);
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
- inc(lInc);
- if lInc = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc-SOFxdim];
- lPredictedG := lImgRAz^[lInc-SOFxdim+1];
- lPredictedB := lImgRAz^[lInc-SOFxdim+2];
- lLineStart := lLineStart + (SOFxDim);
- end else begin
- lPredicted := (lImgRAz^[lInc-3]+lImgRAz^[lInc-3-(SOFxDim-3)])shr 1;
- lPredictedG := (lImgRAz^[lInc-2]+lImgRAz^[lInc-2-(SOFxDim-3)]) shr 1;
- lPredictedB := (lImgRAz^[lInc-1]+lImgRAz^[lInc-1-(SOFxDim-3)]) shr 1;
- end;
- end;
-
- end else begin //predictor in range 1,2,3
- //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
- while lInc < (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1); //RED
- inc(lInc);
- lImgRAz^[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
- inc(lInc);
- lImgRAz^[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
- inc(lInc);
- if lInc = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc-SOFxdim];
- lPredictedG := lImgRAz^[lInc-SOFxdim+1];
- lPredictedB := lImgRAz^[lInc-SOFxdim+2];
- lLineStart := lLineStart + (SOFxDim);
- end else begin
- lPredicted := lImgRAz^[lInc-3-lPredA];
- lPredictedG := lImgRAz^[lInc-2-lPredA];
- lPredictedB := lImgRAz^[lInc-1-lPredA];
- end;
- end;
- end; //predictor <> 7
- until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
- // end; //8<>15data type
- end else begin //previously 12/16/24bit data, 8 bit follows
- lInc := 0;
- //LOSSLESS JPEG: 7 possible predictors - we will handle all of them
- lPredB:= 0;
- lPredC := 0;
- case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
- 2: lPredA:= SOFxDim-1; //Rb directly above
- 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
- 5: begin
- lPredA := 0;
- lPredB := SOFxDim-1; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- 6: begin
- lPredB := 0;
- lPredA := SOFxDim-1; //Rb directly above
- lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
- end;
- else lPredA := 0; //Ra: directly to left
- end; //case SOSss: predictor offset
- //lOffset := -1;
- for lIncX := 1 to SOFxdim do begin //write first line
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- inc(lInc); //writenext voxel
- lPredicted := lImgRAz^[lInc-1];
- end; //first line: use prev voxel prediction;
- if lRestartSegmentSz = 0 then lSegmentEnd := lItems
- else lSegmentEnd := lRestartSegmentSz;
- repeat
- if lSegmentEnd > lItems then lSegmentEnd := lItems;
- lLineStart := (((lInc div SOFxDim)+1)* SOFxDim){-1};
- if lInc > (SOFxDim+1) then
- lPredicted := 1 shl (SOFPrecision-1-SOSpttrans)
- else
- lPredicted := lImgRAz^[lInc-SOFxdim];
- if SOSss = 4 then begin //predictor 4 : ABOVE+LEFT-(UPPERLEFT)
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredicted := lImgRAz^[lInc]+lImgRAz^[lInc-(SOFxDim-1)] -lImgRAz^[lInc-SOFxDim] ;
- end;
-
- end else if (SOSss = 5) or (SOSss=6) then begin //predictor 5,6 : comparisons
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredicted := lImgRAz^[lInc-lPredA]+((lImgRAz^[lInc-lPredB]-lImgRAz^[lInc-lPredC]) shr 1) ;
- end;
- end else if SOSss = 7 then begin //predictor 7: average above and left
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredA := lImgRAz^[lInc];
- lPredB:= lImgRAz^[lInc-SOFxDim+1];//correct
- lPredicted := (lPredA+lPredB) shr 1;
- end;
- end else begin //predictor <> 7 : assume SOSss=1: previous
- for lInc := lInc to (lSegmentEnd-1) do begin
- lImgRAz^[lInc] := lPredicted+DecodePixelDifference(1);
- if lInc+1 = lLineStart then begin//newline
- lPredicted := lImgRAz^[lInc+1-SOFxdim];
- lLineStart := lLineStart + SOFxDim;
- end else
- lPredicted := lImgRAz^[lInc-lPredA];
- end;
- end; //predictor <> 7
- if (lSegmentEnd+1) < lItems then begin
- dec(lRawPos);
- {msg('x'+inttostr(lRawPos)+' '+inttostr(lRawRA^[lRawPos])+':'+
- inttostr(lRawRA^[lRawPos+1])+':'+inttostr(lRawRA^[lRawPos+2])+':'+
- inttostr(lRawRA^[lRawPos+3])+':');}
- repeat
- while (lRawRA^[lRawPos] <> 255) do
- inc(lRawPos);
- inc(lRawPos);
- //msg(inttostr(lRawRA^[lRawPos]));
- until (lRawRA^[lRawPos] >= $D0) and (lRawRA^[lRawPos] <= $D7);
- //lCurrentByteVal := 0; //not FF
- lCurrentBitPos := 0; //read in a new byte
- //msg('x');
- inc(lRawPos);//abbax
- //lCurrentBitPos := 9; //read in a new byte
- end;
- lSegmentEnd := lSegmentEnd + lRestartSegmentSz;
- until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
- end; //8<>15data type
-end;
-
-end.
-
+unit lsjpeg;
+{*$DEFINE Stream}
+//rev13: changes by CR and JGS
+//rev19: uses Lookup table for decoding Huffman table: this doubles the speed
+//rev26: fixed memory leak: FreeMem(lRawRA)
+interface
+{$IFDEF FPC} {$mode delphi}{$H+} {$ENDIF}
+
+uses
+dialogsx,
+ sysutils,define_types,classes;
+type
+ HufRA = record
+ HufSz,HufCode,HufVal: Integer;
+ end;
+{$IFDEF Stream}
+ procedure DecodeJPEG(var lStream: TMemoryStream; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
+{$ELSE}
+ procedure DecodeJPEG(var infp: file; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
+{$ENDIF}
+implementation
+
+{$IFDEF Stream}
+ procedure DecodeJPEG(var lStream: TMemoryStream; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
+{$ELSE}
+procedure DecodeJPEG(var infp: file; var lOutSmallRA: SmallIntP0; var lImgRAz: ByteP0;lOutputSz,lCptPosition,lCptSize: integer; lVerbose: boolean);
+{$ENDIF}
+const
+ kmaxFrames = 4;
+label
+ 666 {EOF}, 123 {Freemem};
+ var
+ lRawRA: bytep;
+ lImgRA: WordP;
+ lHufVal,lAbba,lOffset,lLineStart,lPredicted,lPredictedG,lPredictedB,lRestartSegmentSz,
+ lSz,k,Code,Si,lIncX,lIncY,lInc,lPredA,lPredB,lPredC,lCurrentBitPos,btS1,btS2, btMarkerType,
+ DHTnLi,DHTtcth,SOFprecision,SOSpttrans, SOFnf,SOFarrayPos,SOSns,SOSarrayPos,SOSss,SOSse,SOSahal:integer;//byte;
+ lHufTable,lnHufTables,{lDecode,}lImgStart,lRawSz,lRawPos,lItems,SOFydim, SOFxdim: integer;
+ lMaxHufSi,lMaxHufVal: array [1..kmaxFrames] of integer;
+ DHTLiRA,DHTstartRA: array [1..kmaxFrames,0..31] of integer;//byte;
+ lBitMask: array [1..17] of integer;
+ lSSSSszRA: array [1..kMaxFrames,0..17] of byte;
+ lLookUpRA: array [1..kMaxFrames,0..255] of byte; //lists all possible SSSS with <= 8bits
+ lHufRA: array [1..kMaxFrames,0..31] of HufRA;
+ lFrameCount,lSegmentLength,lSegmentEnd,lI: integer;
+ lImgTypeC3,lHdrOK: boolean;
+function ReadBit: integer; //Read the next single bit
+begin
+ result := (lRawRA[lRawPos] shr (7-lCurrentBitPos)) and 1;
+ lCurrentBitPos := lCurrentBitPos + 1;
+ if (lCurrentBitPos = 8) then begin
+ lRawPos := 1+lRawPos;
+ lCurrentBitPos := 0;
+ end;
+end; //nested proc ReadBit
+
+(*
+START Disabled Procedures
+// These functions are not used: these routines have been inlined (following VTune profiling)
+// but they are useful utilities if you want to explore Huffman Tables
+function ReadBits2_9 ( lNum: integer): integer; //lNum: bits to read, not to exceed 9
+//wo Advance: does not increment the Byte/Bit position. Use AdvanceBitPos to do this
+begin
+ result := lRawRA[lRawPos];
+ result := result shl 8 + lRawRA[lRawPos+1];
+ //result := result shl 8 + lRawRA[lRawPos+2];
+ result := (result shr (16-lCurrentBitPos-lNum)) and lBitMask[lNum]; //lCurrentBitPos is incremented from 1, so -1
+ lCurrentBitPos := lCurrentBitPos + lNum;
+ if (lCurrentBitPos > 7) then begin
+ lRawPos := lRawPos+(lCurrentBitPos shr 3{div 8});
+ lCurrentBitPos := (lCurrentBitPos and 7{mod 8});
+ end;
+end;
+procedure RetractBitPos(lNum: integer);
+begin
+ lCurrentBitPos := lCurrentBitPos - lNum;
+ while (lCurrentBitPos < 0) do begin
+ lRawPos := lRawPos - 1;
+ lCurrentBitPos := lCurrentBitPos + 8;
+ end;
+end;
+procedure AdvanceBitPos(lNum: integer);
+//Advances Bit/Byte counters
+begin
+ lCurrentBitPos := lCurrentBitPos + lNum;
+ if (lCurrentBitPos > 7) then begin
+ lRawPos := lRawPos+(lCurrentBitPos shr 3{div 8});
+ lCurrentBitPos := (lCurrentBitPos and 7{mod 8});
+ end;
+end;
+END Disabled Procedures*)
+
+function ReadBits ( lNum: integer): integer; //lNum: bits to read, not to exceed 16
+begin
+ result := lRawRA[lRawPos];
+ result := result shl 8 + lRawRA[lRawPos+1];
+ result := result shl 8 + lRawRA[lRawPos+2];
+ result := (result shr (24-lCurrentBitPos-lNum)) and lBitMask[lNum]; //lCurrentBitPos is incremented from 1, so -1
+ lCurrentBitPos := lCurrentBitPos + lNum;
+ if (lCurrentBitPos > 7) then begin
+ lRawPos := lRawPos+(lCurrentBitPos shr 3{div 8});
+ lCurrentBitPos := (lCurrentBitPos and 7{mod 8});
+ end;
+end; //nested proc ReadBits
+
+function DecodePixelDifference( lFrame: integer): integer;//Red/Green/Blue each a separate 'Frame': can have unique huffman tables
+var
+ lByte,lHufValSSSS,lInput,lInputbits,lDiff,lI: integer;
+begin
+ // read one byte from the stream, without modifying the pointer
+ lByte := (lRawRA[lRawPos] shl lCurrentBitPos) + (lRawRA[lRawPos+1] shr (8-lCurrentBitPos));
+ lByte := lByte and 255;
+ lHufValSSSS := lLookUpRA[lFrame,lByte];
+ //lLookUpRA: array [1..kMaxFrames,0..255] of byte; //lists all possible SSSS with <= 8bits
+ if lHufValSSSS < 255 then begin
+ lCurrentBitPos := lSSSSszRA[lFrame,lHufValSSSS] + lCurrentBitPos;
+ lRawPos := lRawPos + (lCurrentBitpos shr 3);
+ lCurrentBitpos := lCurrentBitpos and 7;
+ //AdvanceBitPos(lSSSSszRA[lFrame,lSSSS]), but inlined;
+ end else begin //full SSSS is not in the first 8-bits
+ //if (lByte < 0) or (lByte > 255) then showmessage('yikes: this is impossible');
+ lInput := lByte;
+ lInputBits := 8;
+ inc(lRawPos); // forward 8 bits = precisely 1 byte
+ repeat
+ Inc(lInputBits);
+ lInput := lInput shl 1 + ReadBit;
+ if DHTLiRA[lFrame,lInputBits] <> 0 then begin //if any entires with this length
+ for lI := DHTstartRA[lFrame,lInputBits] to (DHTstartRA[lFrame,lInputBits]+DHTLiRA[lFrame,lInputBits]-1) do begin
+ if (lInput = lHufRA[lFrame,lI].HufCode) then
+ lHufValSSSS := lHufRA[lFrame,lI].HufVal;
+ end; //check each code
+ end; //if any entires with this length
+ if (lInputBits >= lMaxHufSi[lFrame]) and (lHufValSSSS > 254) then begin//exhausted options CR: added rev13
+ lHufValSSSS := lMaxHufVal[lFrame];
+ end;
+ until (lHufValSSSS < 255){found};
+ end; //answer in first 8 bits
+ //The HufVal is referred to as the SSSS in the Codec, so it is called 'lHufValSSSS'
+ case lHufValSSSS of
+ 0: result:= 0;
+ 1: if ReadBit = 0 then result := -1 else result := 1;
+ (*BELOW only a tiny bit faster to separate 2..15 into 2..9 and 10..15, requires extra procedure and more
+ 2..9: begin //see 10..15 for explanation
+ lDiff := ReadBits2_9(lHufValSSSS);
+ if (lDiff > (lBitMask[lHufValSSSS-1])) then //add
+ result := lDiff
+ else //negation
+ result := lDiff - lBitMask[lHufValSSSS];
+ end; //2..9 *)
+ 2..15: begin
+ //Osiris includes extra bits after SSSS=16...a violation of the standard See "TABLE H.2 - Difference categories for lossless Huffman coding" of the codec ITU-T81
+ //According to the Codec H.1.2.2 "No extra bits are appended after SSSS = 16 is encoded."
+ //To patch for Osiris Change case from 2..15 to 2..16
+ // This will work for Osiris images, but will break non-Osiris images
+ lDiff := ReadBits(lHufValSSSS);
+ if (lDiff > (lBitMask[lHufValSSSS-1])) then //add
+ result := lDiff
+ // this is slightly unintuitive: the positive bit is identical to the offset shown in TABLE H.2, a slower but more intuitive way to do this is:
+ //result := (lDiff and lBitMask[lHufVal-1]) + (1 shl (lHufval-1));
+ //where you clip off the sign bit and then SHL appropriately
+ else //negation
+ result := lDiff - lBitMask[lHufValSSSS];
+ //NEXT to lines are a bit more intuitive:
+ {lDiff := lBitMask[lHufVal-1]- lDiff;
+ result := -(lDiff + (1 shl (lHufval-1)));}//negation
+ end; //10..15
+ else {16, not osiris}
+ result := 32768;
+ end; //case HuffVal
+end; //nested proc DecodePixelDifference
+
+procedure ReadByte(var lByte: integer);
+begin
+ inc(lRawPos);
+ lByte := lRawRA[lRawPos];
+end; //nested proc ReadByte
+
+function ReadWord: word;
+var
+ lbtL1, lbtL2: byte;
+begin
+ inc(lRawPos);
+ lbtL1 := lRawRA[lRawPos];
+ inc(lRawPos);
+ lbtL2 := lRawRA[lRawPos];
+ result := (256 * lbtL1 + lbtL2)
+end; //nested proc ReadWord
+//NEXT: main procedure
+ begin
+ lAbba := 4;
+ lnHufTables := 0;
+ lRawSz := lCptSize;
+ lRawPos := 0;
+ lRestartSegmentSz := 0;
+ lImgTypeC3 := false;
+ SOFxdim:= 1;
+ if lRawSz < 32 then goto 666;
+ for lFrameCount := 1 to kMaxFrames do
+ for lInc := 1 to 16 do
+ DHTstartRA[lFrameCount,lInc] := 0;
+ SOFydim := 1;
+ SOSpttrans := 0;
+ lHdrOK := false;
+ SOFnf := 0;
+ SOSns := 0;
+ GetMem( lRawRA, lRawSz);
+{$IFDEF Stream}
+ lStream.Seek(lCptPosition, soFromBeginning);
+ lStream.readBuffer(lRawRA^, lRawSz);
+{$ELSE}
+ Seek(infp,lCptPosition);
+ BlockRead(infp, lRawRA^, lRawSz);
+{$ENDIF}
+ ReadByte(btS1);
+ ReadByte(btS1);
+ repeat
+ repeat
+ if lRawPos <= lRawSz then ReadByte(btS1);
+ if btS1 <> $FF then begin
+ goto 666;
+ end;
+ if lRawPos <= lRawSz then ReadByte( btMarkerType);
+ case btMarkerType of //only process segments with length fields
+ $0,$1,$D0..$D7,$FF: btMarkerType := 0; //0&FF = fillers, $1=TEM,$D0..D7=resync
+ end;
+ until (lRawPos >= lRawSz) or (btMarkerType <> 0);
+ lSegmentLength := ReadWord;
+ lSegmentEnd := lRawPos+(lSegmentLength - 2);
+ if lSegmentEnd > lRawSz then goto 666;
+ if (btMarkerType = $C3) then
+ lImgTypeC3 := true;
+ if lverbose then msg( {result+}inttohex(btMarkerType,2){':'+inttostr( lSegmentLength )+'@'+inttostr(positon)+' '});
+ case btMarkerType of
+ $0: ; //filler - ignore
+ $C0..$C3,$C5..$CB,$CD..$CF: begin //read SOF FrameHeader
+ ReadByte(SOFprecision);
+ SOFydim := ReadWord;
+ SOFxdim:= ReadWord;
+ ReadByte(SOFnf);
+ if lverbose then msg('[precision:'+inttostr(SOFprecision)+' X*Y:'+inttostr(SOFxdim)+'*'+inttostr(SOFydim)+'nFrames:'+inttostr(SOFnf)+'] ');
+ if (not lImgTypeC3) or ((SOFnf <> 1) and (SOFnf <> 3)) then begin
+ msg('Unable to extract this file format.');
+ end;
+ SOFarrayPos := lRawPos;
+ lRawPos := (lSegmentEnd);
+ end; //SOF FrameHeader
+ $C4: begin //DHT Huffman
+ if lverbose then msg( 'HuffmanLength'+inttostr(lSegmentLength)+':');
+ //if SOFnf <1 then SOFnf := 1; //we may not know SOFnf yet!
+ lFrameCount := 1;
+ repeat
+ ReadByte( DHTtcth);
+ //showmessage(inttostr(lFrameCount)+'@'+inttostr(DHTtcth and 15)+'x'+inttostr(DHTtcth ));
+ DHTnLi := 0;
+ for lInc := 1 to 16 do begin
+ ReadByte(DHTliRA[lFrameCount,lInc]);
+ DHTnLi := DHTnLi + DHTliRA[lFrameCount,lInc];
+ if DHTliRA[lFrameCount,lInc] <> 0 then lMaxHufSi[lFrameCount] := lInc;
+ //showmessage(inttostr(DHTliRA[lFrameCount,lInc])+'@'+inttostr(lMaxHufSi));
+ end;
+ if DHTnLi > 17 then begin
+ msg('Huffman table corrupted.');
+ goto 666;
+ end;
+ lIncY := 0; //frequency
+
+ for lInc := 0 to 31 do begin
+ lHufRA[lFrameCount, lInc].HufVal := -1;
+ lHufRA[lFrameCount, lInc].HufSz := -1;
+ lHufRA[lFrameCount, lInc].HufCode := -1;
+ end;
+
+ for lInc := 1 to 16 do begin //set the huffman size values
+ if DHTliRA[lFrameCount,lInc]> 0 then begin
+ DHTstartRA[lFrameCount,lInc] := lIncY+1;
+ for lIncX := 1 to DHTliRA[lFrameCount,lInc] do begin
+ inc(lIncY);
+ ReadByte(btS1);
+ lHufRA[lFrameCount,lIncY].HufVal := btS1;
+ lMaxHufVal[lFrameCount] := btS1;
+ if (btS1 >= 0) and (btS1 <= 16) then
+ lHufRA[lFrameCount,lIncY].HufSz := lInc
+ else begin
+ msg('Huffman size array corrupted.');
+ goto 666;
+ end; {}
+ end;
+ end; //Length of size lInc > 0
+ end;
+ //showmessage('Max bits:'+inttostr(lMaxHufSi)+' SSSS:'+inttostr(lMaxHufVal));
+ K := 1;
+ Code := 0;
+ Si := lHufRA[lFrameCount,K].HufSz;//HuffSizeRA[1];
+ repeat
+ while (Si = lHufRA[lFrameCount,K].HufSz) do begin
+ lHufRA[lFrameCount,K].HufCode := Code;
+ //showmessage('bits: '+inttostr(Si)+' NthEntry:'+inttostr(K)+' Code:'+inttostr(Code));
+ Code := Code + 1;
+ Inc(K);
+ end;
+ if K <= DHTnLi then begin
+ while lHufRA[lFrameCount,K].HufSz > Si do begin
+ Code := Code Shl 1;
+ Si := Si + 1;
+ end; //while Si
+ end; //K <= 17
+ until K > DHTnLi;// JGS added rev13
+ inc(lFrameCount);
+ until (lSegmentEnd-lRawPos) < 18;
+ lnHufTables := lFrameCount - 1;
+ //showmessage(inttostr(lnHufTables));
+ lRawPos := (lSegmentEnd);
+ end; //$C4: DHT Huffman
+ $DD: begin //Define Restart
+ lRestartSegmentSz := Readword;
+ lRawPos := (lSegmentEnd);
+ end;
+ $DA: begin //read SOS Scan Header
+ if SOSns > 0 then goto 666; //multiple SOS!
+ ReadByte(SOSns);
+ //if Ns = 1 then NOT interleaved, else interleaved: see B.2.3
+ SOSarrayPos := lRawPos;
+ if SOSns > 0 then begin
+ for lInc := 1 to SOSns do begin
+ ReadByte( btS1); //component identifier 1=Y,2=Cb,3=Cr,4=I,5=Q
+ ReadByte(btS2); //horizontal and vertical sampling factors
+ end;
+ end;
+ ReadByte(SOSss); //predictor selection B.3
+ ReadByte( SOSse);
+ ReadByte( SOSahal); //lower 4bits= pointtransform
+ SOSpttrans := SOSahal and 16;
+ if lverbose then
+ msg('[Predictor: '+inttostr(SOSss)+' PointTransform:'+inttostr(SOSahal)+'] ');
+ lRawPos := (lSegmentEnd);
+ end; //$DA SOS - Scan Header
+ else begin //skip marker segment;
+ lRawPos := (lSegmentEnd);
+ end;
+ end; //case markertype
+ until (lRawPos >= lRawSz) or (btMarkerType = $DA); {hexDA=Start of scan}
+ lHdrOK := true; //errors goto label 666, so are NOT OK
+ lImgStart := lRawPos;
+666:
+ if not lHdrOK then begin
+ msg('Unable to read this file - is this really a JPEG image?');
+ goto 123;
+ end;
+ if (not lImgTypeC3) then
+ goto 123; //lossless compressed huffman tables
+ //NEXT: unpad data - delete byte that follows $FF
+ lINc := lRawPos;
+ lIncX := lRawPos;
+ repeat
+ lRawRA[lIncX] := lRawRA[lInc];
+ if lRawRA[lInc] = 255 then begin
+ if (lRawRA[lInc+1] = $00) then
+ lInc := lInc+1
+ else begin
+ //showmessage(inttostr(lRawRA[lInc+1]));
+ if (lRawRA[lInc+1] = $D9) then //end of image
+ lIncX := -666; //end of padding
+ end;
+ end;
+ inc(lInc);
+ inc(lIncX);
+ until lIncX < 0;
+ //End: Data unpadding
+ //NEXT: Create Huffman LookupTable.
+ //We will compute all possible outcomes for an 8-bit value, while less intuitive than
+ //reading Huffman 1 bit at a time, it doubles the decompression speed
+ lBitMask[1]:= 1;
+ lBitMask[2]:= 3;
+ lBitMask[3]:= 7;
+ lBitMask[4]:= 15;
+ lBitMask[5]:= 31;
+ lBitMask[6]:= 63;
+ lBitMask[7]:= 127;
+ lBitMask[8]:= 255;
+ lBitMask[9]:= 511;
+ lBitMask[10]:= 1023;
+ lBitMask[11]:= 2047;
+ lBitMask[12]:= 4095;
+ lBitMask[13]:= 8191;
+ lBitMask[14]:= 16383;
+ lBitMask[15]:= 32767;
+ lBitMask[16]:= 65535;
+ lBitMask[17]:= 131071; //ONLY required for Osiris corrupted images, see DecodePixelDifference for details
+ //NEXT: some RGB images use only a single Huffman table for all 3 colour planes. In this case, replicate the correct values
+ if (lnHufTables < SOFnf) then begin //use single Hufman table for each frame
+ //showmessage('generating tables'+inttostr(SOFnf));
+ if lnHufTables < 1 then begin
+ msg('Lossless JPEG decoding error: no Huffman tables.');
+ goto 123;
+ end;
+ for lFrameCount := 2 to SOFnf do begin
+ for lInc := 1 to 16 do
+ DHTstartRA[lFrameCount,lInc] := DHTstartRA[1,lInc];
+ for lInc := 0 to 31 do begin
+ lHufRA[lFrameCount,lInc].HufCode := lHufRA[1,lInc].HufCode;
+ lHufRA[lFrameCount,lInc].HufVal := lHufRA[1,lInc].HufVal;
+ lHufRA[lFrameCount,lInc].HufSz := lHufRA[1,lInc].HufSz;
+ DHTliRA[lFrameCount,lInc] := DHTliRA[1,lInc];
+ end; //for each table entry
+ end; //for each frame xx
+ end;// if lnHufTables < SOFnf
+ for lFrameCount := 1 to kMaxFrames do
+ for lInc := 0 to 17 do
+ lSSSSszRA[lFrameCount,lInc] := 123; //Impossible value for SSSS, suggests 8-bits can not describe answer
+ for lFrameCount := 1 to kMaxFrames do
+ for lInc := 0 to 255 do
+ lLookUpRA[lFrameCount,lInc] := 255; //Impossible value for SSSS, suggests 8-bits can not describe answer
+ //NEXT fill lookuptable
+ for lFrameCount := 1 to SOFnf do begin
+ lIncY := 0;
+ for lSz := 1 to 8 do begin //set the huffman lookup table for keys with lengths <=8
+ if DHTliRA[lFrameCount,lSz]> 0 then begin
+ for lIncX := 1 to DHTliRA[lFrameCount,lSz] do begin
+ inc(lIncY);
+ lHufVal := lHufRA[lFrameCount,lIncY].HufVal; //SSSS
+ {if (lHufVal < 0) or (lHufVal > 17) then begin
+ showmessage('Unknown SSSS =' +inttostr(lHufVal));
+ lHufVal := 16;
+ end; }
+ lSSSSszRA[lFrameCount,lHufVal] := lSz;
+ k := (lHufRA[lFrameCount,lIncY].HufCode shl (8-lSz )) and 255; //K= most sig bits for hufman table
+ if lSz < 8 then begin //fill in all possible bits that exceed the huffman table
+ lInc := lBitMask[8-lSz];
+ for lCurrentBitPos := 0 to lInc do begin
+ lLookUpRA[lFrameCount,k+lCurrentBitPos] := lHufVal;
+ end;
+ end else
+ lLookUpRA[lFrameCount,k] := lHufVal; //SSSS
+
+ {Showmessage('Frame ' + inttostr(lFrameCount) + ' SSSS= '+inttostr(lHufRA[lFrameCount,lIncY].HufVal)+
+ ' Size= '+inttostr(lHufRA[1,lIncY].HufSz)+
+ ' Code= '+inttostr(lHufRA[1,lIncY].HufCode)+
+ ' SHL Code= '+inttostr(k)+
+ ' EmptyBits= '+inttostr(lInc)); {}
+ end; //Set SSSS
+ end; //Length of size lInc > 0
+ end; //for lInc := 1 to 8
+ end; //For each frame, e.g. once each for Red/Green/Blue
+ //Next: uncompress data: different loops for different predictors
+ SOFxdim:= SOFnf*SOFxdim;
+ lItems := SOFxdim*SOFydim;
+ //if lVerbose then showmessage('precision'+inttostr(SOFprecision));
+ //for timing, multiple decoding loops lRawAbba := lRawPos;for lLoopsAbba := 1 to 100 do begin lRawPos := lRawAbba;
+ //if (lRestartSegmentSz > 0) and ((SOFPrecision<> 8) or (SOSss = 7)) then //add restart support if we ever find any samples to test
+ // showmessage('This image uses restart markers. Please contact the author. Predictor:Precision '+inttostr(SOSss)+':'+inttostr(SOFPrecision));
+ inc(lRawPos);//abbax
+ lCurrentBitPos := 0; //read in a new byte
+ //lCurrentBitPos := 1; //read in a new byte
+ lItems := SOFxdim*SOFydim;
+ lPredicted := 1 shl (SOFPrecision-1-SOSpttrans);
+ lInc := 0;
+ if (SOFPrecision<> 8) then begin //start - 16 bit data
+ lImgRA := @lOutSmallRA[0];{set to 1 for MRIcro, else 0}
+ FillChar(lImgRA^,lItems*sizeof(word), 0); //zero array
+ lPredB:= 0;
+ lPredC := 0;
+ case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
+ 2: lPredA:= SOFxDim-1; //Rb directly above
+ 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
+ 4,5: begin
+ lPredA := 0;
+ lPredB := SOFxDim-1; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ 6: begin
+ lPredB := 0;
+ lPredA := SOFxDim-1; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ else lPredA := 0; //Ra: directly to left
+ end; //case SOSss: predictor offset
+ for lIncX := 1 to SOFxdim do begin
+ inc(lInc); //writenext voxel
+ if lInc > 1 then lPredicted := lImgRA[lInc-1];
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //first line: use prev voxel prediction;
+ if lRestartSegmentSz = 0 then begin
+ for lIncY := 2 to SOFyDim do begin
+ inc(lInc); //write next voxel
+ lPredicted := lImgRA[lInc-SOFxdim];
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ if SOSss = 4 then begin
+ for lIncX := 2 to SOFxdim do begin
+ lPredicted := lImgRA[lInc-lPredA]+lImgRA[lInc-lPredB]-lImgRA[lInc-lPredC];
+ inc(lInc); //writenext voxel
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //for lIncX
+ end else if (SOSss = 5) or (SOSss = 6) then begin
+ for lIncX := 2 to SOFxdim do begin
+ lPredicted := lImgRA[lInc-lPredA]+ ((lImgRA[lInc-lPredB]-lImgRA[lInc-lPredC]) shr 1);
+ inc(lInc); //writenext voxel
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //for lIncX
+ end else if SOSss = 7 then begin
+ for lIncX := 2 to SOFxdim do begin
+ inc(lInc); //writenext voxel
+ lPredicted := (lImgRA[lInc-1]+lImgRA[lInc-SOFxdim]) shr 1;
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //for lIncX
+ end else begin //SOSss 1,2,3 read single values
+ for lIncX := 2 to SOFxdim do begin
+ lPredicted := lImgRA[lInc-lPredA];
+ inc(lInc); //writenext voxel
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ end; //for lIncX
+ end; //SOSss predictor
+
+
+ end; //for lIncY
+ end {RestartSegmentSz = 0} else begin {restartsegment}
+ if SOSss > 3 then
+ msg('Unusual 16-bit lossless JPEG with restart segments. Please contact the author:'+inttostr(SOSss));
+ lSegmentEnd := lRestartSegmentSz;
+ repeat
+ if lSegmentEnd > lItems then lSegmentEnd := lItems;
+ lLineStart := (((lInc div SOFxDim)+1)* SOFxDim){-1};
+ if lInc > (SOFxDim+1) then
+ lPredicted := 1 shl (SOFPrecision-1-SOSpttrans)
+ else
+ lPredicted := lImgRA[lInc-SOFxdim];
+
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRA[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRA[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredicted := lImgRA[lInc-lPredA];
+ end;
+ if (lSegmentEnd+1) < lItems then begin
+ dec(lRawPos);
+ repeat
+ while (lRawRA[lRawPos] <> 255) do
+ inc(lRawPos);
+ inc(lRawPos);
+ until (lRawRA[lRawPos] >= $D0) and (lRawRA[lRawPos] <= $D7);
+ lCurrentBitPos := 0; //read in a new byte
+ inc(lRawPos);//abbax
+ end;
+ lSegmentEnd := lSegmentEnd + lRestartSegmentSz;
+ until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
+ end; //restartsegments
+ end else if SOFnf = 3 then begin //>8bit data; 8 bit follows
+ //LOSSLESS JPEG: 7 possible predictors - we will handle all of them
+ lPredB:= 0;
+ lPredC := 0;
+ case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
+ 2: lPredA:= SOFxDim-3; //Rb directly above
+ 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
+ 5: begin
+ lPredA := 0;
+ lPredB := SOFxDim-3; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ 6: begin
+ lPredB := 0;
+ lPredA := SOFxDim-3; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ else lPredA := 0; //Ra: directly to left
+ end; //case SOSss: predictor offset
+ lPredictedG := lPredicted;
+ lPredictedB := lPredicted;
+ lOffset := 0;
+ lInc := lOffset;
+ for lIncX := 1 to (SOFxdim div 3) do begin //write first line
+ //DecodePixelDifference=RED
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ lPredicted := lImgRAz[lInc];
+ inc(lInc); //writenext voxel
+ //DecodePixelDifference=GREEN
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2);
+ lPredictedG := lImgRAz[lInc];
+ inc(lInc); //writenext voxel
+ //DecodePixelDifference=BLUE
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3);
+ lPredictedB := lImgRAz[lInc];
+ inc(lInc); //writenext voxel
+ end; //first line: use prev voxel prediction;
+ if lRestartSegmentSz = 0 then lSegmentEnd := lItems
+ else lSegmentEnd := lRestartSegmentSz;
+ repeat
+ if lSegmentEnd > lItems then lSegmentEnd := lItems;
+ lLineStart := (((lInc div SOFxDim)+1)* SOFxDim)+lOffset{-1};
+ if lInc > (SOFxDim+1) then begin
+ lPredicted := 1 shl (SOFPrecision-1-SOSpttrans);
+ lPredictedG := lPredicted;
+ lPredictedB := lPredicted;
+ end else begin
+ lPredicted := lImgRAz[lInc-SOFxdim+lOffset];
+ lPredictedG := lImgRAz[1+lInc-SOFxdim+lOffset];
+ lPredictedB := lImgRAz[2+lInc-SOFxdim+lOffset];
+ end;
+ if SOSss = 4 then begin //predictor = 4
+ //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
+ while lInc < (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1); //RED
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
+ inc(lInc);
+ if lInc = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ lPredictedG := lImgRAz[lInc-SOFxdim+1];
+ lPredictedB := lImgRAz[lInc-SOFxdim+2];
+ lLineStart := lLineStart + (SOFxDim);
+ end else begin
+ lPredicted := lImgRAz[lInc-3]+lImgRAz[lInc-3-(SOFxDim-3)]-lImgRAz[lInc-3-SOFxDim];
+ lPredictedG := lImgRAz[lInc-2]+lImgRAz[lInc-2-(SOFxDim-3)]-lImgRAz[lInc-2-SOFxDim];
+ lPredictedB := lImgRAz[lInc-1]+lImgRAz[lInc-1-(SOFxDim-3)]-lImgRAz[lInc-1-SOFxDim];
+ end;
+ end;
+ //xxx
+ end else if (SOSss = 5) or (SOSss = 6) then begin //predictor = 5 or 6
+ //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
+ while lInc < (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1); //RED
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
+ inc(lInc);
+ if lInc = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ lPredictedG := lImgRAz[lInc-SOFxdim+1];
+ lPredictedB := lImgRAz[lInc-SOFxdim+2];
+ lLineStart := lLineStart + (SOFxDim);
+ end else begin
+ lPredicted := lImgRAz[lInc-3-lPredA]+((lImgRAz[lInc-3-lPredB]-lImgRAz[lInc-3-lPredC])shr 1);
+ lPredictedG := lImgRAz[lInc-2-lPredA]+((lImgRAz[lInc-2-lPredB]-lImgRAz[lInc-2-lPredC])shr 1);
+ lPredictedB := lImgRAz[lInc-1-lPredA]+((lImgRAz[lInc-1-lPredB]-lImgRAz[lInc-1-lPredC])shr 1);
+ end;
+ end;
+ end else if SOSss = 7 then begin //predictor = 7
+ while lInc < (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1); //RED
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
+ inc(lInc);
+ if lInc = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ lPredictedG := lImgRAz[lInc-SOFxdim+1];
+ lPredictedB := lImgRAz[lInc-SOFxdim+2];
+ lLineStart := lLineStart + (SOFxDim);
+ end else begin
+ lPredicted := (lImgRAz[lInc-3]+lImgRAz[lInc-3-(SOFxDim-3)])shr 1;
+ lPredictedG := (lImgRAz[lInc-2]+lImgRAz[lInc-2-(SOFxDim-3)]) shr 1;
+ lPredictedB := (lImgRAz[lInc-1]+lImgRAz[lInc-1-(SOFxDim-3)]) shr 1;
+ end;
+ end;
+
+ end else begin //predictor in range 1,2,3
+ //this is a 24-bit image, so for 512-pixel wid image, SOFxdim will be (3*512=) 1536
+ while lInc < (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1); //RED
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedG+DecodePixelDifference(2); //GREEN
+ inc(lInc);
+ lImgRAz[lInc] := lPredictedB+DecodePixelDifference(3); //BLUE
+ inc(lInc);
+ if lInc = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ lPredictedG := lImgRAz[lInc-SOFxdim+1];
+ lPredictedB := lImgRAz[lInc-SOFxdim+2];
+ lLineStart := lLineStart + (SOFxDim);
+ end else begin
+ lPredicted := lImgRAz[lInc-3-lPredA];
+ lPredictedG := lImgRAz[lInc-2-lPredA];
+ lPredictedB := lImgRAz[lInc-1-lPredA];
+ end;
+ end;
+ end; //predictor <> 7
+ until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
+ // end; //8<>15data type
+ end else begin //previously 12/16/24bit data, 8 bit follows
+ lInc := 0;
+ //LOSSLESS JPEG: 7 possible predictors - we will handle all of them
+ lPredB:= 0;
+ lPredC := 0;
+ case SOSss of //predictors 1,2,3 examine single previous pixel, here we set the relative location
+ 2: lPredA:= SOFxDim-1; //Rb directly above
+ 3: lPredA:= SOFxDim; //Rc UpperLeft:above and to the left
+ 5: begin
+ lPredA := 0;
+ lPredB := SOFxDim-1; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ 6: begin
+ lPredB := 0;
+ lPredA := SOFxDim-1; //Rb directly above
+ lPredC:= SOFxDim; //Rc UpperLeft:above and to the left
+ end;
+ else lPredA := 0; //Ra: directly to left
+ end; //case SOSss: predictor offset
+ //lOffset := -1;
+ for lIncX := 1 to SOFxdim do begin //write first line
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ inc(lInc); //writenext voxel
+ lPredicted := lImgRAz[lInc-1];
+ end; //first line: use prev voxel prediction;
+ if lRestartSegmentSz = 0 then lSegmentEnd := lItems
+ else lSegmentEnd := lRestartSegmentSz;
+ repeat
+ if lSegmentEnd > lItems then lSegmentEnd := lItems;
+ lLineStart := (((lInc div SOFxDim)+1)* SOFxDim){-1};
+ if lInc > (SOFxDim+1) then
+ lPredicted := 1 shl (SOFPrecision-1-SOSpttrans)
+ else
+ lPredicted := lImgRAz[lInc-SOFxdim];
+ if SOSss = 4 then begin //predictor 4 : ABOVE+LEFT-(UPPERLEFT)
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredicted := lImgRAz[lInc]+lImgRAz[lInc-(SOFxDim-1)] -lImgRAz[lInc-SOFxDim] ;
+ end;
+
+ end else if (SOSss = 5) or (SOSss=6) then begin //predictor 5,6 : comparisons
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredicted := lImgRAz[lInc-lPredA]+((lImgRAz[lInc-lPredB]-lImgRAz[lInc-lPredC]) shr 1) ;
+ end;
+ end else if SOSss = 7 then begin //predictor 7: average above and left
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredA := lImgRAz[lInc];
+ lPredB:= lImgRAz[lInc-SOFxDim+1];//correct
+ lPredicted := (lPredA+lPredB) shr 1;
+ end;
+ end else begin //predictor <> 7 : assume SOSss=1: previous
+ for lInc := lInc to (lSegmentEnd-1) do begin
+ lImgRAz[lInc] := lPredicted+DecodePixelDifference(1);
+ if lInc+1 = lLineStart then begin//newline
+ lPredicted := lImgRAz[lInc+1-SOFxdim];
+ lLineStart := lLineStart + SOFxDim;
+ end else
+ lPredicted := lImgRAz[lInc-lPredA];
+ end;
+ end; //predictor <> 7
+ if (lSegmentEnd+1) < lItems then begin
+ dec(lRawPos);
+ repeat
+ while (lRawRA[lRawPos] <> 255) do
+ inc(lRawPos);
+ inc(lRawPos);
+ until (lRawRA[lRawPos] >= $D0) and (lRawRA[lRawPos] <= $D7);
+ lCurrentBitPos := 0; //read in a new byte
+ inc(lRawPos);
+ //lCurrentBitPos := 9; //read in a new byte
+ end;
+ lSegmentEnd := lSegmentEnd + lRestartSegmentSz;
+ until (lRestartSegmentSz < 1) or ((lSegmentEnd-2) > lItems);
+ end; //8<>15data type
+123:
+ FreeMem( lRawRA); //release memory buffer
+end;
+
+end.
diff --git a/dcm2nii/manifest.or b/dcm2nii_prePARRECDTI/manifest.or
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/manifest.or
copy to dcm2nii_prePARRECDTI/manifest.or
diff --git a/dcm2nii/nifti_form.dfm b/dcm2nii_prePARRECDTI/nifti_form.dfm
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/nifti_form.dfm
copy to dcm2nii_prePARRECDTI/nifti_form.dfm
diff --git a/dcm2nii/nifti_form.lfm b/dcm2nii_prePARRECDTI/nifti_form.lfm
old mode 100644
new mode 100755
similarity index 79%
copy from dcm2nii/nifti_form.lfm
copy to dcm2nii_prePARRECDTI/nifti_form.lfm
index a56f450..b6de3d9
--- a/dcm2nii/nifti_form.lfm
+++ b/dcm2nii_prePARRECDTI/nifti_form.lfm
@@ -1,7 +1,7 @@
object NIfTIForm: TNIfTIForm
- Left = 250
+ Left = 797
Height = 266
- Top = 98
+ Top = 32
Width = 338
ActiveControl = OKBtn
BorderIcons = [biSystemMenu]
@@ -14,21 +14,21 @@ object NIfTIForm: TNIfTIForm
Constraints.MinHeight = 266
Constraints.MinWidth = 338
OnCreate = FormCreate
- LCLVersion = '0.9.29'
+ LCLVersion = '0.9.30.2'
object Label1: TLabel
Left = 8
- Height = 14
+ Height = 17
Top = 168
- Width = 79
+ Width = 102
Alignment = taCenter
Caption = 'Output Format: '
ParentColor = False
end
object Label4: TLabel
Left = 8
- Height = 14
+ Height = 17
Top = 16
- Width = 27
+ Width = 35
Alignment = taCenter
Caption = 'Task:'
ParentColor = False
@@ -56,10 +56,10 @@ object NIfTIForm: TNIfTIForm
end
object TypeCombo: TComboBox
Left = 118
- Height = 21
+ Height = 20
Top = 163
Width = 209
- ItemHeight = 13
+ ItemHeight = 0
Items.Strings = (
'SPM2 (3D Anlyze hdr/img)'
'SPM5 (3D NIfTI hdr/img)'
@@ -73,51 +73,53 @@ object NIfTIForm: TNIfTIForm
TabOrder = 2
end
object Panel1: TPanel
- Left = 40
+ Left = 8
Height = 103
- Top = 48
- Width = 275
+ Top = 59
+ Width = 312
BevelOuter = bvNone
ClientHeight = 103
- ClientWidth = 275
+ ClientWidth = 312
TabOrder = 3
object Label2: TLabel
Left = 8
- Height = 14
+ Height = 17
Top = 15
- Width = 143
+ Width = 190
Caption = 'Volumes to remove from start'
ParentColor = False
end
object Label3: TLabel
Left = 7
- Height = 14
+ Height = 17
Top = 55
- Width = 143
- Caption = 'Volumes to remove from start'
+ Width = 185
+ Caption = 'Volumes to remove from end'
ParentColor = False
end
object StartEdit: TSpinEdit
- Left = 196
- Height = 21
- Top = 6
+ Left = 224
+ Height = 16
+ Top = 13
Width = 74
+ MaxValue = 9999999
TabOrder = 0
end
object EndEdit: TSpinEdit
- Left = 196
- Height = 21
- Top = 46
+ Left = 224
+ Height = 16
+ Top = 53
Width = 74
+ MaxValue = 9999999
TabOrder = 1
end
end
object Combo4D: TComboBox
Left = 47
- Height = 21
+ Height = 20
Top = 11
- Width = 188
- ItemHeight = 13
+ Width = 280
+ ItemHeight = 0
Items.Strings = (
'Change format'
'Flip dimensions 3 and 4'
@@ -131,11 +133,11 @@ object NIfTIForm: TNIfTIForm
TabOrder = 4
end
object Combo3D: TComboBox
- Left = 74
- Height = 21
+ Left = 48
+ Height = 20
Top = 11
- Width = 188
- ItemHeight = 13
+ Width = 279
+ ItemHeight = 0
Items.Strings = (
'Change format'
'Reorient to orthogonal'
@@ -147,7 +149,7 @@ object NIfTIForm: TNIfTIForm
object ASLPanel: TPanel
Left = 40
Height = 50
- Top = 40
+ Top = 24
Width = 275
BevelOuter = bvNone
ClientHeight = 50
@@ -155,10 +157,10 @@ object NIfTIForm: TNIfTIForm
TabOrder = 6
object ASLCombo: TComboBox
Left = 16
- Height = 21
+ Height = 20
Top = 11
Width = 246
- ItemHeight = 13
+ ItemHeight = 0
Items.Strings = (
'Subtract pairs - first image tagged'
'Subtract pairs - first image control'
@@ -172,7 +174,7 @@ object NIfTIForm: TNIfTIForm
object FormulaPanel: TPanel
Left = 47
Height = 114
- Top = 37
+ Top = 56
Width = 273
BevelOuter = bvNone
ClientHeight = 114
@@ -180,25 +182,25 @@ object NIfTIForm: TNIfTIForm
TabOrder = 7
object Label5: TLabel
Left = 31
- Height = 14
+ Height = 17
Top = 17
- Width = 26
+ Width = 33
Alignment = taCenter
Caption = 'Scale'
ParentColor = False
end
object Label6: TLabel
Left = 31
- Height = 14
+ Height = 17
Top = 59
- Width = 31
+ Width = 39
Alignment = taCenter
Caption = 'Power'
ParentColor = False
end
object ScaleEdit: TFloatSpinEdit
Left = 127
- Height = 21
+ Height = 16
Top = 11
Width = 130
DecimalPlaces = 8
@@ -210,7 +212,7 @@ object NIfTIForm: TNIfTIForm
end
object PowerEdit: TFloatSpinEdit
Left = 127
- Height = 21
+ Height = 16
Top = 56
Width = 130
DecimalPlaces = 8
@@ -221,4 +223,4 @@ object NIfTIForm: TNIfTIForm
Value = 1.2E-6
end
end
-end
+end
\ No newline at end of file
diff --git a/dcm2nii_prePARRECDTI/nifti_form.lrs b/dcm2nii_prePARRECDTI/nifti_form.lrs
new file mode 100755
index 0000000..eb9a942
--- /dev/null
+++ b/dcm2nii_prePARRECDTI/nifti_form.lrs
@@ -0,0 +1,62 @@
+{ This is an automatically generated lazarus resource file }
+
+LazarusResources.Add('TNIfTIForm','FORMDATA',[
+ 'TPF0'#10'TNIfTIForm'#9'NIfTIForm'#4'Left'#3#29#3#6'Height'#3#10#1#3'Top'#2' '
+ +#5'Width'#3'R'#1#13'ActiveControl'#7#5'OKBtn'#11'BorderIcons'#11#12'biSystem'
+ +'Menu'#0#11'BorderStyle'#7#8'bsDialog'#7'Caption'#6#18'Convert NIfTI File'#12
+ +'ClientHeight'#3#10#1#11'ClientWidth'#3'R'#1#21'Constraints.MaxHeight'#3#10#1
+ +#20'Constraints.MaxWidth'#3'R'#1#21'Constraints.MinHeight'#3#10#1#20'Constra'
+ +'ints.MinWidth'#3'R'#1#8'OnCreate'#7#10'FormCreate'#10'LCLVersion'#6#8'0.9.3'
+ +'0.2'#0#6'TLabel'#6'Label1'#4'Left'#2#8#6'Height'#2#17#3'Top'#3#168#0#5'Widt'
+ +'h'#2'f'#9'Alignment'#7#8'taCenter'#7'Caption'#6#15'Output Format: '#11'Pare'
+ +'ntColor'#8#0#0#6'TLabel'#6'Label4'#4'Left'#2#8#6'Height'#2#17#3'Top'#2#16#5
+ +'Width'#2'#'#9'Alignment'#7#8'taCenter'#7'Caption'#6#5'Task:'#11'ParentColor'
+ +#8#0#0#7'TButton'#5'OKBtn'#4'Left'#3#200#0#6'Height'#2#25#3'Top'#3#208#0#5'W'
+ +'idth'#2'K'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#2'OK'#11'ModalRes'
+ +'ult'#2#1#7'OnClick'#7#10'OKBtnClick'#8'TabOrder'#2#0#0#0#7'TButton'#9'Cance'
+ +'lBtn'#4'Left'#2'h'#6'Height'#2#25#3'Top'#3#208#0#5'Width'#2'K'#25'BorderSpa'
+ +'cing.InnerBorder'#2#4#7'Caption'#6#6'Cancel'#11'ModalResult'#2#2#8'TabOrder'
+ +#2#1#0#0#9'TComboBox'#9'TypeCombo'#4'Left'#2'v'#6'Height'#2#20#3'Top'#3#163#0
+ +#5'Width'#3#209#0#10'ItemHeight'#2#0#13'Items.Strings'#1#6#24'SPM2 (3D Anlyz'
+ +'e hdr/img)'#6#23'SPM5 (3D NIfTI hdr/img)'#6#19'SPM8 (3D NIfTI nii)'#6#16'4D'
+ +' NIfTI hdr/img'#6#18'FSL (4D NIfTI nii)'#6#29'Compressed FSL (4D NIfTI nii)'
+ +#6#21'MRIcron drawing (voi)'#0#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#2
+ +#0#0#6'TPanel'#6'Panel1'#4'Left'#2#8#6'Height'#2'g'#3'Top'#2';'#5'Width'#3'8'
+ +#1#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'g'#11'ClientWidth'#3'8'#1#8
+ +'TabOrder'#2#3#0#6'TLabel'#6'Label2'#4'Left'#2#8#6'Height'#2#17#3'Top'#2#15#5
+ +'Width'#3#190#0#7'Caption'#6#28'Volumes to remove from start'#11'ParentColor'
+ +#8#0#0#6'TLabel'#6'Label3'#4'Left'#2#7#6'Height'#2#17#3'Top'#2'7'#5'Width'#3
+ +#185#0#7'Caption'#6#26'Volumes to remove from end'#11'ParentColor'#8#0#0#9'T'
+ +'SpinEdit'#9'StartEdit'#4'Left'#3#224#0#6'Height'#2#16#3'Top'#2#13#5'Width'#2
+ +'J'#8'MaxValue'#4#127#150#152#0#8'TabOrder'#2#0#0#0#9'TSpinEdit'#7'EndEdit'#4
+ +'Left'#3#224#0#6'Height'#2#16#3'Top'#2'5'#5'Width'#2'J'#8'MaxValue'#4#127#150
+ +#152#0#8'TabOrder'#2#1#0#0#0#9'TComboBox'#7'Combo4D'#4'Left'#2'/'#6'Height'#2
+ +#20#3'Top'#2#11#5'Width'#3#24#1#10'ItemHeight'#2#0#13'Items.Strings'#1#6#13
+ +'Change format'#6#23'Flip dimensions 3 and 4'#6#21'Clip 1st/Last Volumes'#6
+ +#21'Export as 32-bit real'#6#13'Apply formula'#6#14'ASL conversion'#0#8'OnCh'
+ +'ange'#7#13'Combo4DChange'#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#4#0#0
+ +#9'TComboBox'#7'Combo3D'#4'Left'#2'0'#6'Height'#2#20#3'Top'#2#11#5'Width'#3
+ +#23#1#10'ItemHeight'#2#0#13'Items.Strings'#1#6#13'Change format'#6#22'Reorie'
+ +'nt to orthogonal'#6#17'Reorient and crop'#0#5'Style'#7#14'csDropDownList'#8
+ +'TabOrder'#2#5#0#0#6'TPanel'#8'ASLPanel'#4'Left'#2'('#6'Height'#2'2'#3'Top'#2
+ +#24#5'Width'#3#19#1#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'2'#11'Clie'
+ +'ntWidth'#3#19#1#8'TabOrder'#2#6#0#9'TComboBox'#8'ASLCombo'#4'Left'#2#16#6'H'
+ +'eight'#2#20#3'Top'#2#11#5'Width'#3#246#0#10'ItemHeight'#2#0#13'Items.String'
+ +'s'#1#6'#Subtract pairs - first image tagged'#6'$Subtract pairs - first imag'
+ +'e control'#6#15'Subtract Custom'#6#19'Add (odd+even) BOLD'#0#5'Style'#7#14
+ +'csDropDownList'#8'TabOrder'#2#0#0#0#0#6'TPanel'#12'FormulaPanel'#4'Left'#2
+ +'/'#6'Height'#2'r'#3'Top'#2'8'#5'Width'#3#17#1#10'BevelOuter'#7#6'bvNone'#12
+ +'ClientHeight'#2'r'#11'ClientWidth'#3#17#1#8'TabOrder'#2#7#0#6'TLabel'#6'Lab'
+ +'el5'#4'Left'#2#31#6'Height'#2#17#3'Top'#2#17#5'Width'#2'!'#9'Alignment'#7#8
+ +'taCenter'#7'Caption'#6#5'Scale'#11'ParentColor'#8#0#0#6'TLabel'#6'Label6'#4
+ +'Left'#2#31#6'Height'#2#17#3'Top'#2';'#5'Width'#2''''#9'Alignment'#7#8'taCen'
+ +'ter'#7'Caption'#6#5'Power'#11'ParentColor'#8#0#0#14'TFloatSpinEdit'#9'Scale'
+ +'Edit'#4'Left'#2#127#6'Height'#2#16#3'Top'#2#11#5'Width'#3#130#0#13'DecimalP'
+ +'laces'#2#8#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0
+ +#0#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#0#5'Value'#5#0
+ +#176#27'l'#160#175#15#161#235'?'#0#0#14'TFloatSpinEdit'#9'PowerEdit'#4'Left'
+ +#2#127#6'Height'#2#16#3'Top'#2'8'#5'Width'#3#130#0#13'DecimalPlaces'#2#8#9'I'
+ +'ncrement'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8
+ +'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#1#5'Value'#5#0#176#27'l'#160
+ +#175#15#161#235'?'#0#0#0#0
+]);
\ No newline at end of file
diff --git a/dcm2nii/nifti_form.pas b/dcm2nii_prePARRECDTI/nifti_form.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/nifti_form.pas
copy to dcm2nii_prePARRECDTI/nifti_form.pas
diff --git a/dcm2nii/niftiutil.pas b/dcm2nii_prePARRECDTI/niftiutil.pas
old mode 100644
new mode 100755
similarity index 82%
copy from dcm2nii/niftiutil.pas
copy to dcm2nii_prePARRECDTI/niftiutil.pas
index e469306..c785669
--- a/dcm2nii/niftiutil.pas
+++ b/dcm2nii_prePARRECDTI/niftiutil.pas
@@ -1,13 +1,13 @@
unit niftiutil;
-
+ {$Include ..\common\isgui.inc}
interface
uses
{$IFDEF FPC}
-gzio2,
+ {$IFDEF GUI}FileUtil, {$ENDIF} //FileUtil requires LResources that requires extra environment variables with tools like matlab
+gzio2, process, //FileUtil,
{$ELSE}
-gziod,
+gziod, ShellAPI,Windows,Forms,
{$ENDIF}
-
SysUtils,Classes,define_types,filename,dicomtypes,prefs;
{$H+}
const
@@ -37,6 +37,8 @@ function Merge4DFiles (lLowSliceName,lHighSliceName,lDestName: string; lNumberof
function Insert3Din4D (l3DSliceName,l4DSliceName,lDestName: string; lVol2Copy: integer; lPrefs: TPrefs):string;
function MaskImages(lMaskName: string; lFiles: TStrings; lPrefs: TPrefs; lVol: integer; lSaveThresh: boolean): string;
function NonspatialDimensionsNII (lA: TNIFTIhdr): integer;
+function runPigz(var lImgName : string; processes: integer): boolean;
+function CheckHugeUint16(lFilename: string; UINT16toFLOAT32: boolean): boolean;
implementation
uses dialogsx;
@@ -153,34 +155,109 @@ begin
freemem(l16ui);
end;*)
+
+function CheckHugeUint16(lFilename: string; UINT16toFLOAT32: boolean): boolean;
+var
+ lHdr: TNIFTIHdr;
+ lByteSwap: boolean;
+ lMax,lVol,lVox: integer;
+ lnVol,lnVox: Int64;
+ lImgBuffer: WordP;
+ lExt,lImgName: string;
+ lInF: File;
+begin
+ result := false;
+ if (GzExt(lFilename)) then begin
+ Msg('CheckHugeUint16: Unable to read GZ files ' + lFilename);
+ exit;
+ end;
+ if not NIFTIhdr_LoadHdr (lFilename, lHdr, lByteSwap) then begin
+ Msg('CheckHugeUint16: Unable to read as NifTI/Analyze ' + lFilename);
+ exit;
+ end;//load the header from disk...
+ lnVol := NonspatialDimensionsNII(lHdr);
+ lnVox := lHdr.dim[1]*lHdr.dim[2]*lHdr.dim[3];
+ result := true;
+ if (lHdr.datatype <> kDT_UINT16) or (lnVol < 1) or (lnVox < 1) or (lByteswap) then
+ exit;
+ if lByteswap then begin
+ Msg('CheckHugeUint16: Unable to read byte-swapped data (yet) ' + lFilename);
+ result := false;
+ exit;
+ end;//load the header from disk...
+
+ GetMem(lImgBuffer,lnVox * sizeof(Word));
+ lExt := UpCaseExt(lFilename);
+ if lExt ='.HDR' then
+ lImgName := changefileext(lFilename,'.img')
+ else
+ lImgName := lFilename;
+ AssignFile(lInF, lImgName);
+ Reset(lInF,1);
+ Seek(lInF,round(lHdr.vox_offset));
+ Filemode := 0; //ReadOnly
+ for lVol := 1 to lnVol do begin
+ BlockRead(lInF, lImgBuffer^[1],lnVox * sizeof(Word));
+ if lVol = 1 then begin
+ lMax := lImgBuffer^[1];
+ end;
+ for lVox := 1 to lnVox do
+ if (lImgBuffer^[lVox] > lMax) then
+ lMax := lImgBuffer^[lVox];
+ end;
+ CloseFile(lInF);
+ FreeMem(lImgBuffer);
+ Filemode := 2; //Read-Write
+ if (lMax < 32768) then begin
+ lHdr.datatype := kDT_SIGNED_SHORT;
+ AssignFile(lInF, lFileName); {WIN}
+ Reset(lInF,1) ;
+ BlockWrite(lInF,lHdr,sizeof(TNIFTIhdr) );
+ CloseFile(lInF);
+ Msg(lFilename+' losslessly converted from UINT16->INT16, maximum value is '+inttostr(lMax));
+ result := true;
+ exit;
+ end;
+ Msg('WARNING: This huge image is stored in the unusual UINT16 format. Maximum intensity of '+inttostr(lMax)
+ +'makes it impossible to save the image as the more popular INT16 format. Some tools may not be able to process this image. ' +lFilename);
+
+ result := true;
+end;
+
procedure Uint16 (var lvBuffer: bytep; lVolOffset: integer; var lInHdr: TNIFTIhdr;var lPrefs: TPrefs; var lByteSwap: boolean);
//kDT_UINT16 saves data range 0..65535, but this is an atypical NIfTI format (not included in earlier Analyze format)
// this procedure saves the data as kDT_SIGNED_SHORT 0..36767
// if data range is <32767 then saved unchanged, if range is >32767, saved as 15-bit (Least Significant bit clipped).
var
- i,lmax,lv,lnv: integer;
+ i,lmax,lv,lnv: Int64;
lTempB: ByteP;
l16ui : WordP;
- //l16i: SmallIntP;
l32f: SingleP;
begin
-
lnv := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]*NonspatialDimensionsNII(lInHdr);
if (lInHdr.datatype <> kDT_UINT16) or (lnv < 1) then
exit;
l16ui := WordP(@lvBuffer^[lVolOffset]);
if lByteSwap then begin
lmax := swap(l16ui^[1]);
- for lv := 1 to lnv do
- if swap(l16ui^[lv]) > lmax then
- lmax := swap(l16ui^[lv]);
+ //for lv := 1 to lnv do // fpc can not use int64 in for loop
+ lv := 1;
+ while lv <= lnv do begin
+ if swap(l16ui^[lv]) > lmax then
+ lmax := swap(l16ui^[lv]);
+ inc(lv)
+ end;
end else begin
lmax := l16ui^[1];
- for lv := 1 to lnv do
- if l16ui^[lv] > lmax then
- lmax := l16ui^[lv];
- end;
+ //for lv := 1 to lnv do //fpc can not use int64 in for loop
+ lv := 1;
+ while lv <= lnv do begin
+ if l16ui^[lv] > lmax then
+ lmax := l16ui^[lv];
+ inc(lv)
+ end;
+ end; //if swapped else not swapped
if lmax < 32768 then begin //lossless: unsigned range <32768 (15 bits), so can be stored in signed 16bit
lInHdr.datatype := kDT_SIGNED_SHORT;
(*next lines not required, as range 0..32767 is stored identically for WORDS and SMALLINTS, see TestUINT16
@@ -198,36 +275,211 @@ begin
lmax := lVolOffset+ (lnv*sizeof(Word));
GetMem(lTempB,lmax);
if lByteSwap then begin
+ Msg(' Swapping data to native byte order (Big vs Little Endian)');
+ //for lv := 1 to lnv do //fpc can not use int64 in for loop
+ lv := 1;
+ while lv <= lnv do begin
+ l16ui^[lv] := swap(l16ui^[lv]);
+ inc(lv)
+ end;
+
+ end;
+ //for lv := 1 to lmax do //fpc can not use int64 in for loop
+ lv := 1;
+ while lv <= lmax do begin
+ lTempB^[lv] := lvBuffer^[lv];
+ inc(lv)
+ end;
+
+ (*if lByteSwap then begin
lByteSwap := false;
+ if (lVolOffset > 0) do
+ for lv := 1 to lVolOffset do
+ lTempB^[lv] := swap(lvBuffer^[lv]);
+ xx
for lv := 1 to lmax do
lTempB^[lv] := swap(lvBuffer^[lv]);
- Msg(' Swapping data to native byte order (Big vs Little Endian)');
+ Msg(' Swapping data to native byte order (Big vs Little Endian)');
end else begin
for lv := 1 to lmax do
lTempB^[lv] := lvBuffer^[lv];
- end;
+ end;*)
freemem(lvBuffer);
GetMem(lvBuffer,lVolOffset+ (lnv*sizeof(single)));
- for lv := 1 to lVolOffset do //copy header
- lvBuffer^[lv] := lTempB^[lv];
+ //for lv := 1 to lVolOffset do //fpc can not use int64 in for loop
+ lv := 1;
+ while lv <= lVolOffset do begin
+ lvBuffer^[lv] := lTempB^[lv];
+ inc(lv)
+ end;
+
l16ui := WordP(@lTempB^[lVolOffset]);
l32f := SingleP(@lvBuffer^[lVolOffset]);
- for lv := 1 to lnv do
- l32f^[lv] :=l16ui^[lv];
+ //for lv := 1 to lnv do //fpc can not use int64 in for loop
+ lv := 1;
+ while lv <= lnv do begin
+ l32f^[lv] :=l16ui^[lv];
+ inc(lv)
+ end;
Freemem(lTempB);
end;// if range requires conversion to 32-bit float
end; //Uint16
+
+function getPigzNameWithPath: string;
+//returns path to pigz executable, e.g. '/Users/rorden/downloads/pigz-master/pigz';
+var
+ temp, exename: string;
+begin
+ {$IFDEF ENDIAN_BIG}
+ Msg('pigz not available with PowerPC computers');
+ result := '';
+ exit;
+ {$ENDIF}
+ {$IFDEF UNIX}
+ exename := 'pigz';
+ {$IFDEF GUI}
+ result := FindDefaultExecutablePath(exename); // "which pigz"
+ if length(result) > 0 then
+ exit;
+ {$ENDIF}
+ {$ELSE}
+ exename := 'pigz.exe';
+ {$ENDIF}
+ //result := ExtractFilePath(Application.ExeName)+'pigz';
+ result := ExtractFilePath( paramstr(0))+exename;
+ if fileexists(result) then exit;
+ {$IFDEF DARWIN}
+ temp := result;
+ result := ExtractFilePath(paramstr(0));
+ result := LeftStr(result, Pos((ExtractFileName(paramstr(0))+'.app'), result)-1)+exename;
+ if fileexists(result) then exit;
+ Msg('File compression error: pigz does not exist in you path or '+result+' or '+temp);
+ {$ELSE}
+ Msg('File compression error: pigz does not exist in you path or '+result);
+ {$ENDIF}
+ result := '';
+end;
+
+{$IFDEF FPC} //Freepascal has handy 'Process' for calling console applications
+function runPigz(var lImgName : string; processes: integer): boolean;
+// abs(processes): 1= default (as many as available, 2..n: use this many processors
+// if processes is a NEGATIVE value, application does not wait for Pigz to complete...
+var
+ AProcess: TProcess;
+ Acmd: string;
+ AResponse: TStringList;
+ i: integer;
+begin
+ result := false;
+ Acmd := getPigzNameWithPath; //+' -k' //<- to KEEP original
+ if length(Acmd) < 1 then exit;
+ //Acmd := Acmd +' -v -k';//verbose, keep files
+ if abs(processes) > 1 then
+ Acmd := Acmd + ' -p '+inttostr( abs(processes) );
+ Acmd := Acmd +' "'+lImgName+'"';
+ Msg('External compression: '+Acmd);
+ AProcess := TProcess.Create(nil);
+ //AProcess.Environment.Add('FSLDIR='/usr/local/fsl/); //optional
+ AProcess.CommandLine := Acmd;
+ if (processes > 0) then //wait for pgzip to complete...
+ AProcess.Options := AProcess.Options + [poWaitOnExit, poStderrToOutPut, poUsePipes]
+ else //do not wait for pigz
+ AProcess.Options := AProcess.Options + [poStderrToOutPut, poUsePipes];
+ AProcess.Execute;
+ if (processes > 0) then begin//wait for pgzip to complete...
+ AResponse := TStringList.Create;
+ AResponse.LoadFromStream(AProcess.Output);
+ if AResponse.Count > 0 then
+ for i := 1 to AResponse.Count do
+ Msg(' '+AResponse.Strings[i-1]);
+ AResponse.Free;
+ end;
+ AProcess.Free;
+ result := true;
+end;
+{$ELSE} //Delphi does not have 'Process' for calling console applications
+
+procedure ExecNewProcess(AppName, ACmd : String; WaitUntilDone: boolean);
+var
+ StartInfo : TStartupInfo;
+ ProcInfo : TProcessInformation;
+ CreateOK : Boolean;
+begin
+ { fill with known state }
+ FillChar(StartInfo,SizeOf(TStartupInfo),#0);
+ FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
+ StartInfo.cb := SizeOf(TStartupInfo);
+ CreateOK := CreateProcess(PChar(AppName),Pchar(Acmd), nil, nil,False,
+ CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,
+ nil, nil, StartInfo, ProcInfo);
+ { check to see if successful }
+ if (CreateOK) and (WaitUntilDone) then
+ WaitForSingleObject(ProcInfo.hProcess, INFINITE);
+end;
+
+function runPigz(var lImgName : string; processes: integer): boolean;
+// abs(processes): 1= default (as many as available, 2..n: use this many processors
+// if processes is a NEGATIVE value, application does not wait for Pigz to complete...
+var
+ AppName, Acmd: string;
+begin
+ result := false;
+ AppName := getPigzNameWithPath; //+' -k' //<- to KEEP original
+ if length(AppName) < 1 then exit;
+ Acmd := '';
+ //Acmd := Acmd +' -v -k';//verbose, keep files
+ if abs(processes) > 1 then
+ Acmd := Acmd + ' -p '+inttostr( abs(processes) );
+ Acmd := Acmd +' "'+lImgName+'"';
+ Msg('External compression: '+AppName+' '+Acmd);
+ Acmd := AppName+' '+Acmd;
+ ExecNewProcess(AppName, ACmd, (processes > 0));
+ result := true;
+end;
+{$ENDIF}
+procedure BlockWriteX(var f: file; var lvBuffer: bytep; Count: Int64;var Result: Int64; lStart: Int64);
+var
+ lSaved, lBlockSize, lMaxBlockSize: Int64;
+ lResult: integer;
+begin
+ if (Count <= 2147483647) then begin
+ //BlockWrite(f, lvBuffer^[lStart], Count);
+ BlockWrite(f, lvBuffer^[lStart], Count, lResult);
+ Result := lResult;
+ exit;
+ end;
+ lMaxBlockSize := 1073741824; // 1Gb = 1073741824 bytes
+ lBlockSize := lMaxBlockSize;
+ lSaved := 0;
+ while (lSaved < Count) do begin
+ if (Count-lSaved) < lMaxBlockSize then
+ lBlockSize := Count-lSaved;
+ BlockWrite(f, lvBuffer^[lStart+lSaved], lBlockSize, lResult);
+ lSaved := lSaved + lResult;
+ if (lResult < lBlockSize) then begin
+ msg('BlockWriteX: Serious problem saving huge file - is disk space exhausted?');
+ Result := lSaved;
+ exit;
+ end;
+
+ end;
+ Result := lSaved;
+end;
+
function SaveNIfTICore (var lOutImgName: string; var lvBuffer: bytep; lVolOffset: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs; var lByteSwap: boolean): string;
//image data should start at lVolOffset - this should be AT LEAST kNIIImgOffset (=352) bytes for creating .nii.gz files
//important note - when converting 4D to 3D to .nii format the lvBuffer is changed :: must correct this
var
lPref : TPrefs;
- lVol,lVolStart,lVolBytes: integer;
+ lVol, lusePigz: integer;
+ lGZip: boolean;
+ lVolStart,lVolBytes,lBytesSaved: Int64;
lOutF: File;
lNoGZName,lHdrName,lImgName: string;
l3dHdr,lOutHdr : TNIFTIHdr;
lHdrBupRA: bytep;
+
begin
lNoGZName := (lOutImgName);
StripGZExt(lNoGZName); //we want to convert filename.nii.gz -> filename.hdr not -> filename.nii.hdr
@@ -250,14 +502,16 @@ begin
end; //for each vol
exit;
end; //l4Dto3D
+
Filemode := 2;
lVolBytes := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]*lInHdr.dim[4]*trunc(((lInHdr.bitpix)+7)/8);
+
+
if ((kNIIImgOffset+lVolBytes)> DiskFreeEx(lNoGZName)) then begin
- Msg('There is not enough free space on the destination disk to save the data. '+kCR+
+ Msg('Insufficient disk space '+
lNoGZName+ kCR+' Bytes Required: '+inttostr(lVolBytes) );
exit;
end;
-
if (lPref.SingleNIIFile) then begin
lVolStart := lVolOffset-kNIIImgOffset;
lVolBytes := lVolBytes + kNIIImgOffset;
@@ -278,9 +532,34 @@ begin
lImgName := changefileext(lNoGZName,'.nii');
SaveHdrRAM (lImgName,lInHdr,lOutHdr, lByteSwap,lPrefs.SPM2);
+
Move(lOutHdr,lvBuffer^[lVolStart],sizeof(lOutHdr)); //move 348 byte header in place
+
//finally - write buffer to disk
- if lPrefs.Gzip then begin
+ //Msg(inttostr(lPrefs.usePigz)+' *'+inttostr(length(getPigzNameWithPath))+'*');
+ lusePigz:= lPrefs.usePigz;
+ lGZip := lPrefs.Gzip;
+ if (lVolBytes >1073741824) and (lGZip) then begin // 1Gb = 1073741824 bytes
+ if (length(getPigzNameWithPath) > 0) then begin
+ if (lusePigz = 0) then begin
+ lusePigz := 1;
+ Msg('Using pigz to create GZ: file too large for internal compressor');
+ end;
+ end else begin
+ lGZip := false;
+ Msg('Warning: File not GZipped (too large). Solution: install pigz');
+ end;
+ end;
+
+ if (lGZip) and (lusePigz <> 0) and (length(getPigzNameWithPath) > 0) then begin
+ AssignFile(lOutF, lImgName);
+ Rewrite(lOutF,1);
+ //BlockWrite(lOutF, lvBuffer^[lVolStart], lVolBytes,lBytesSaved);
+ BlockWriteX(lOutF, lvBuffer, lVolBytes,lBytesSaved,lVolStart);
+ CloseFile(lOutF);
+ runPigz(lImgName, lusePigz);
+ //DeleteFile(lImgName);
+ end else if lGZip then begin
if lPrefs.VOI then
lImgName := changefileext(lNoGZName,'.voi')
else
@@ -293,7 +572,8 @@ begin
Msg('Saving '+lImgName);
AssignFile(lOutF, lImgName);
Rewrite(lOutF,1);
- BlockWrite(lOutF, lvBuffer^[lVolStart], lVolBytes);
+ //BlockWrite(lOutF, lvBuffer^[lVolStart], lVolBytes);
+ BlockWriteX(lOutF, lvBuffer, lVolBytes,lBytesSaved,lVolStart);
CloseFile(lOutF);
end; //else no GZip
Move(lHdrBupRA^[1],lvBuffer^[lVolStart],kNIIImgOffset); //replace data overwritten by header - otherwise 4D->3D corrupts lvBuffer
@@ -502,7 +782,10 @@ end;
function NIFTIhdr_LoadHdr (var lFilename: string; var lHdr: TNIFTIHdr; var lByteSwap: boolean): boolean;
var
- lHdrFile: file; {lOri: array [1..3] of single;} lBuff: Bytep; lReportedSz, lSwappedReportedSz,lHdrSz,lFileSz: Longint; lExt: string; //1494
+ lHdrFile: file; {lOri: array [1..3] of single;} lBuff: Bytep;
+ lReportedSz, lSwappedReportedSz,lHdrSz: Longint;
+ lFileSz: Int64;
+ lExt: string; //1494
begin
Result := false; //assume error
if lFilename = '' then exit;
@@ -849,13 +1132,13 @@ end; //Not anonymized
if lDicomData.Allocbits_per_pixel <> 8 then begin
if lDicomData.Allocbits_per_pixel = 32 then begin
lBHdr.bitpix := 32;
- if lDicomData.Float then
+ if lDicomData.FloatData then
lBHdr.datatype := 16
else
lBHdr.datatype := 8;
end else if lDicomData.Allocbits_per_pixel = 64 then begin
lBHdr.bitpix := 64;
- lBHdr.datatype := 64;;
+ lBHdr.datatype := 64;
end else begin //16bits per pixel
lBHdr.bitpix := 16;
lBHdr.datatype := kDT_SIGNED_SHORT;
diff --git a/dcm2nii/nii_3dto4d.pas b/dcm2nii_prePARRECDTI/nii_3dto4d.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/nii_3dto4d.pas
copy to dcm2nii_prePARRECDTI/nii_3dto4d.pas
diff --git a/dcm2nii/nii_4dto3d.pas b/dcm2nii_prePARRECDTI/nii_4dto3d.pas
old mode 100644
new mode 100755
similarity index 91%
copy from dcm2nii/nii_4dto3d.pas
copy to dcm2nii_prePARRECDTI/nii_4dto3d.pas
index 766aebc..f2757f1
--- a/dcm2nii/nii_4dto3d.pas
+++ b/dcm2nii_prePARRECDTI/nii_4dto3d.pas
@@ -25,7 +25,7 @@ function ModifyAnalyze(lFilename: string; lPrefs: TPrefs): boolean;
var
lExt,lOutname: string;
lHdr: TNIFTIhdr;
- lFormat,lStartIn,lEndIn: integer;
+ lFormat,lStartIn,lEndIn, lMinStartIn: integer;
lByteSwap,lReorder: boolean;
lPref: TPrefs;
begin
@@ -39,8 +39,6 @@ begin
Msg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
-
-
if lPrefs.AutoCrop then begin
Msg('Autocrop NIfTI/Analyze image '+lFileName);
lOutname := Reorient(lFilename,lHdr, lPrefs,false,false);
@@ -49,11 +47,22 @@ begin
exit;
end;
Msg('Adjusting NIfTI/Analyze image '+lFileName);
-
+ if (lHdr.dim[4] > 1) then begin //if 4D input
+ if (lPrefs.BeginClip > 0) and (lPrefs.BeginClip < lHdr.dim[4]) then begin
+ lStartIn := lPrefs.BeginClip;
+ Msg('Warning: removing first '+inttostr(lStartIn) + ' volumes (preference: BeginClip)');
+ end;
+ if (lStartIn <> lPrefs.BeginClip) then
+ Msg('Warning preference BeginClip is being ignored (not enough volumes)');
+ if (lPrefs.LastClip > 0) and ( (lPrefs.LastClip+ lPrefs.BeginClip) < lHdr.dim[4]) then begin
+ lEndIn := lPrefs.LastClip;
+ Msg('Warning: removing final '+inttostr(lEndIn) + ' volumes (preference: LastClip)');
+ end;
+ if (lEndIn <> lPrefs.LastClip) then
+ Msg('Warning preference LastClip is being ignored (not enough volumes)');
+ end;//if 4D input
//next - determine output format
if not lPref.ManualNiFtiConv then begin
- lStartIn := 0;
- lEndIn := 0;
lReorder := false;
end else begin //manually specify conversion parameters
lFormat := GetInt('Output: 0=spm2,1=spm5,2=spm8,3=hdr4D,4=fsl,5=fsl.gz ', 0,DefaultOutputFormat (lPrefs),5);
@@ -80,12 +89,12 @@ begin
if lHdr.dim[4] > 1 then begin //4D file
if (lHdr.dim[4] > 1) and (lHdr.dim[3] > 1) then begin
Msg(' Enter a value of -1 to flip 3rd and 4th dimensions.');
- lStartIn := -1;
+ lMinStartIn := -1;
end else
- lStartIn := 0;
- lStartIn := GetInt('Enter volumes to remove from start ', lStartIn,0,lHdr.dim[4]);
+ lMinStartIn := 0;
+ lStartIn := GetInt('Enter volumes to remove from start ', lMinStartIn,lStartIn,lHdr.dim[4]);
if lStartIn >= 0 then
- lEndIn := GetInt('Enter volumes to remove from end ' ,0,0,lHdr.dim[4]);
+ lEndIn := GetInt('Enter volumes to remove from end ' ,0,lEndIn,lHdr.dim[4]);
if ((lStartIn < 0) or (lEndIn < 0)) and (lHdr.dim[4] > 1) and (lHdr.dim[3] > 1) then
lReorder := true
else
diff --git a/dcm2nii/nii_asl.pas b/dcm2nii_prePARRECDTI/nii_asl.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/nii_asl.pas
copy to dcm2nii_prePARRECDTI/nii_asl.pas
diff --git a/dcm2nii/nii_crop.pas b/dcm2nii_prePARRECDTI/nii_crop.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/nii_crop.pas
copy to dcm2nii_prePARRECDTI/nii_crop.pas
diff --git a/dcm2nii/nii_math.pas b/dcm2nii_prePARRECDTI/nii_math.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/nii_math.pas
copy to dcm2nii_prePARRECDTI/nii_math.pas
diff --git a/dcm2nii/nii_orient.pas b/dcm2nii_prePARRECDTI/nii_orient.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/nii_orient.pas
copy to dcm2nii_prePARRECDTI/nii_orient.pas
diff --git a/dcm2nii/nii_reslice.pas b/dcm2nii_prePARRECDTI/nii_reslice.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/nii_reslice.pas
copy to dcm2nii_prePARRECDTI/nii_reslice.pas
diff --git a/dcm2nii/notes.txt b/dcm2nii_prePARRECDTI/notes.txt
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/notes.txt
copy to dcm2nii_prePARRECDTI/notes.txt
diff --git a/dcm2nii/paramstrs.pas b/dcm2nii_prePARRECDTI/paramstrs.pas
old mode 100644
new mode 100755
similarity index 85%
copy from dcm2nii/paramstrs.pas
copy to dcm2nii_prePARRECDTI/paramstrs.pas
index 8fc45f2..ac8b6b4
--- a/dcm2nii/paramstrs.pas
+++ b/dcm2nii_prePARRECDTI/paramstrs.pas
@@ -168,22 +168,23 @@ begin
Msg('Either drag and drop or specify command line options:');
Msg(' '+FilenameWOExt(paramstr(0))+' <options> <sourcenames>');
Msg('OPTIONS:');
- Msg('-a Anonymize [remove identifying information]: Y,N = '+Bool2YN(lPrefs.Anonymize));
- Msg('-b load settings from specified inifile, e.g. ''-b C:\set\t1.ini'' ');
- Msg('-c Collapse input folders: Y,N = '+Bool2YN(lPrefs.CollapseFolders));
- Msg('-d Date in filename [filename.dcm -> 20061230122032.nii]: Y,N = '+Bool2YN(lPrefs.AppendDate));
- Msg('-e events (series/acq) in filename [filename.dcm -> s002a003.nii]: Y,N = '+Bool2YN(lPrefs.AppendAcqSeries));
- Msg('-f Source filename [e.g. filename.par -> filename.nii]: Y,N = '+Bool2YN(lPrefs.AppendFilename));
- Msg('-g gzip output, filename.nii.gz [ignored if ''-n n'']: Y,N = '+Bool2YN(lPrefs.Gzip));
- Msg('-i ID in filename [filename.dcm -> johndoe.nii]: Y,N = '+Bool2YN(lPrefs.AppendPatientName));
- Msg('-m manually prompt user to specify output format [NIfTI input only]: Y,N = '+Bool2YN(lPrefs.ManualNIfTIConv));
- Msg('-n output .nii file [if no, create .hdr/.img pair]: Y,N = '+Bool2YN(lPrefs.SingleNIIFile));
- Msg('-o Output Directory, e.g. ''C:\TEMP'' (if unspecified, source directory is used)');
- Msg('-p Protocol in filename [filename.dcm -> TFE_T1.nii]: Y,N = '+Bool2YN(lPrefs.AppendProtocolName));
- Msg('-r Reorient image to nearest orthogonal: Y,N ');
- Msg('-s SPM2/Analyze not SPM5/NIfTI [ignored if ''-n y'']: Y,N = '+Bool2YN(lPrefs.SPM2));
- Msg('-v Convert every image in the directory: Y,N = '+Bool2YN(lPrefs.EveryFile));
- Msg('-x Reorient and crop 3D NIfTI images: Y,N = '+Bool2YN(lPrefs.Autocrop));
+ Msg(' -4 Create 4D volumes, else DTI/fMRI saved as many 3D volumes: Y,N = '+Bool2YN(lPrefs.FourD));
+ Msg(' -a Anonymize [remove identifying information]: Y,N = '+Bool2YN(lPrefs.Anonymize));
+ Msg(' -b load settings from specified inifile, e.g. ''-b C:\set\t1.ini'' ');
+ Msg(' -c Collapse input folders: Y,N = '+Bool2YN(lPrefs.CollapseFolders));
+ Msg(' -d Date in filename [filename.dcm -> 20061230122032.nii]: Y,N = '+Bool2YN(lPrefs.AppendDate));
+ Msg(' -e events (series/acq) in filename [filename.dcm -> s002a003.nii]: Y,N = '+Bool2YN(lPrefs.AppendAcqSeries));
+ Msg(' -f Source filename [e.g. filename.par -> filename.nii]: Y,N = '+Bool2YN(lPrefs.AppendFilename));
+ Msg(' -g gzip output, filename.nii.gz [ignored if ''-n n'']: Y,N = '+Bool2YN(lPrefs.Gzip));
+ Msg(' -i ID in filename [filename.dcm -> johndoe.nii]: Y,N = '+Bool2YN(lPrefs.AppendPatientName));
+ Msg(' -m manually prompt user to specify output format [NIfTI input only]: Y,N = '+Bool2YN(lPrefs.ManualNIfTIConv));
+ Msg(' -n output .nii file [if no, create .hdr/.img pair]: Y,N = '+Bool2YN(lPrefs.SingleNIIFile));
+ Msg(' -o Output Directory, e.g. ''C:\TEMP'' (if unspecified, source directory is used)');
+ Msg(' -p Protocol in filename [filename.dcm -> TFE_T1.nii]: Y,N = '+Bool2YN(lPrefs.AppendProtocolName));
+ Msg(' -r Reorient image to nearest orthogonal: Y,N ');
+ //Msg(' -s SPM2/Analyze not SPM5/NIfTI [ignored if ''-n y'']: Y,N = '+Bool2YN(lPrefs.SPM2));
+ Msg(' -v Convert every image in the directory: Y,N = '+Bool2YN(lPrefs.EveryFile));
+ Msg(' -x Reorient and crop 3D NIfTI images: Y,N = '+Bool2YN(lPrefs.Autocrop));
Msg(' You can also set defaults by editing '+lIniName);
{$IFDEF UNIX}
Msg('EXAMPLE: '+FilenameWOExt(paramstr(0))+' -a y /Users/Joe/Documents/dcm/IM_0116');
@@ -292,7 +293,7 @@ begin
case lCommandChar of
'4': CharBool(lStr[1],lPrefs.FourD);
'A': CharBool(lStr[1],lPrefs.Anonymize);
- 'C': CharBool(lStr[1],lPrefs.CollapseFolders);
+ 'C': CharBool(lStr[1],lPrefs.CollapseFolders);
'D': CharBool(lStr[1],lPrefs.AppendDate);
'E': CharBool(lStr[1],lPrefs.AppendAcqSeries);
'F': CharBool(lStr[1],lPrefs.AppendFilename);
@@ -356,7 +357,7 @@ begin
exit;
end else begin
{$IFNDEF UNIX}lStartTime := GetTickCount; {$ENDIF}
- if lPrefs.everyfile then
+ if lPrefs.everyfile then
LoadFileList(lStr,lOutDir,lPrefs)
else
LoadParamFileList(lStr,lOutDir,lPrefs,I);
diff --git a/dcm2nii/parconvert.pas b/dcm2nii_prePARRECDTI/parconvert.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/parconvert.pas
copy to dcm2nii_prePARRECDTI/parconvert.pas
diff --git a/dcm2nii/pref_form.dfm b/dcm2nii_prePARRECDTI/pref_form.dfm
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/pref_form.dfm
copy to dcm2nii_prePARRECDTI/pref_form.dfm
diff --git a/dcm2nii/pref_form.lfm b/dcm2nii_prePARRECDTI/pref_form.lfm
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/pref_form.lfm
copy to dcm2nii_prePARRECDTI/pref_form.lfm
diff --git a/dcm2nii/pref_form.lrs b/dcm2nii_prePARRECDTI/pref_form.lrs
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/pref_form.lrs
copy to dcm2nii_prePARRECDTI/pref_form.lrs
diff --git a/dcm2nii/pref_form.pas b/dcm2nii_prePARRECDTI/pref_form.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/pref_form.pas
copy to dcm2nii_prePARRECDTI/pref_form.pas
diff --git a/dcm2nii/prefs.pas b/dcm2nii_prePARRECDTI/prefs.pas
old mode 100644
new mode 100755
similarity index 92%
copy from dcm2nii/prefs.pas
copy to dcm2nii_prePARRECDTI/prefs.pas
index b8ef29d..4693b76
--- a/dcm2nii/prefs.pas
+++ b/dcm2nii_prePARRECDTI/prefs.pas
@@ -20,10 +20,10 @@ type
everyfile,fourD,Swizzle4D,Stack3DImagesWithSameAcqNum,customRename,
CollapseFolders,AutoCrop, UseGE_0021_104F, PhilipsPrecise,Verbose,DebugMode,DebugMode2,UntestedFeatures,UINT16toFLOAT32: boolean;
- SiemensDTIUse0019If00181020atleast,
+ BeginClip, LastClip,SiemensDTIUse0019If00181020atleast,
SiemensDTINoAngulationCorrectionIf00181020atleast,
SiemensDTIStackIf00181020atleast,
- OutDirMode, MinReorientMatrix,MaxReorientMatrix,RecursiveFolderDepth
+ OutDirMode, MinReorientMatrix,MaxReorientMatrix,RecursiveFolderDepth,usePigz,maxGb64bit
: integer;
OutDir, BackupDir,NameAppend: string;
end;
@@ -141,6 +141,15 @@ begin
BackupDir := '';
WritePrefsOnQuit := true;
UINT16toFLOAT32 := true;
+ BeginClip := 0;
+ LastClip := 0;
+ usePigz := 0;
+ {$ifdef CPU64}
+ maxGb64bit := 6;
+ {$ELSE}
+ maxGb64bit := 1;
+ {$ENDIF}
+
end;
end;
@@ -233,10 +242,18 @@ begin
IniBool(lRead,lIniFile,'Stack3DImagesWithSameAcqNum',lPrefs.Stack3DImagesWithSameAcqNum);
IniBool(lRead,lIniFile,'Swizzle4D',lPrefs.Swizzle4D);
IniBool(lRead,lIniFile,'UseGE_0021_104F',lPrefs.UseGE_0021_104F);
+
+ IniInt(lRead,lIniFile,'BeginClip',lPrefs.BeginClip);
+ IniInt(lRead,lIniFile,'LastClip',lPrefs.LastClip);
+ IniInt(lRead,lIniFile,'usePigz',lPrefs.usePigz);
+ {$ifdef CPU64}
+ IniInt(lRead,lIniFile,'maxGb64bit',lPrefs.maxGb64bit);
+ {$ENDIF}
IniInt(lRead,lIniFile,'MaxReorientMatrix',lPrefs.MaxReorientMatrix);
IniInt(lRead,lIniFile,'MinReorientMatrix',lPrefs.MinReorientMatrix);
IniInt(lRead,lIniFile,'RecursiveFolderDepth',lPrefs.RecursiveFolderDepth);
IniInt(lRead,lIniFile,'OutDirMode',lPrefs.OutDirMode);
+
IniInt(lRead,lIniFile,'SiemensDTIUse0019If00181020atleast',lPrefs.SiemensDTIUse0019If00181020atleast);
IniInt(lRead,lIniFile,'SiemensDTINoAngulationCorrectionIf00181020atleast',lPrefs.SiemensDTINoAngulationCorrectionIf00181020atleast);
IniInt(lRead,lIniFile,'SiemensDTIStackIf00181020atleast',lPrefs.SiemensDTIStackIf00181020atleast);
diff --git a/dcm2nii/readint.dfm b/dcm2nii_prePARRECDTI/readint.dfm
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/readint.dfm
copy to dcm2nii_prePARRECDTI/readint.dfm
diff --git a/dcm2nii/readint.lrs b/dcm2nii_prePARRECDTI/readint.lrs
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/readint.lrs
copy to dcm2nii_prePARRECDTI/readint.lrs
diff --git a/dcm2nii/readint.pas b/dcm2nii_prePARRECDTI/readint.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/readint.pas
copy to dcm2nii_prePARRECDTI/readint.pas
diff --git a/dcm2nii/sortdicom.pas b/dcm2nii_prePARRECDTI/sortdicom.pas
old mode 100644
new mode 100755
similarity index 90%
copy from dcm2nii/sortdicom.pas
copy to dcm2nii_prePARRECDTI/sortdicom.pas
index 39fdb7e..61c0b14
--- a/dcm2nii/sortdicom.pas
+++ b/dcm2nii_prePARRECDTI/sortdicom.pas
@@ -203,8 +203,10 @@ begin
if abs (ld1.orient[lI] - ld2.orient[lI]) > kTolerance then
exit;
end;
- if (ld1.IntenScale <> ld2.IntenScale) or (ld1.IntenIntercept <> ld2.IntenIntercept) then //if previous file is a 4D image, we should convert it separately
+ (*if (ld1.IntenScale <> ld2.IntenScale) or (ld1.IntenIntercept <> ld2.IntenIntercept) then begin//if previous file is a 4D image, we should convert it separately
+ msg('Warning: unable to stack images because intensity scaling varies. Names: '+ld1.Filename+' '+ld2.filename+' Slopes: '+floattostr(ld1.IntenScale)+' '+floattostr(ld2.IntenScale)+' Intercepts: '+floattostr(ld1.IntenIntercept)+' '+floattostr(ld2.IntenIntercept));
exit;
+ end; *)
result := true;
end;
@@ -319,7 +321,7 @@ function LoadFileListInner (var lOutDirname: string; var lPrefs: TPrefs; var lSt
var
lPrevDICOM,lDicomData: DicomData;
lDICOMra: TDICOMrap;
- lRepeatLocations,lStartImg,lValidItems, lItems,lInc: integer;
+ lnumEchos,lRepeatLocations,lStartImg,lValidItems, lItems,lInc: integer;
lError,lRepeatedValues,lHdrOK,lImgOK: boolean;
lFilename,lDynStr: string;
begin
@@ -374,28 +376,37 @@ begin
end;
lStartImg := 1;
lRepeatLocations := 0;
+ lnumEchos := 1;
lPrevDICOM := lDICOMra^[1];
for lInc := 1 to lValidItems do begin
//msg(lDICOMra^[lInc].Filename+','+floattostr(lDICOMra^[lInc].PatientPosX)+','+floattostr(lDICOMra^[lInc].PatientPosY)+','+floattostr(lDICOMra^[lInc].PatientPosZ) );
if (lInc > 1) and (not SameIDSeriesAcqXYZ (lPrevDICOM ,lDICOMra^[lInc],lPrefs)) then begin
//SameIDSeriesAcqXYZ2 (lPrevDICOM ,lDICOMra^[lInc]);
- Msg('Converting '+inttostr(lInc-1)+'/'+inttostr(lValidItems)+' '+inttostr(lRepeatLocations));
+ if (lRepeatLocations < 2) and (lnumEchos > 1) then
+ lRepeatLocations := lnumEchos;
+ Msg('Converting '+inttostr(lInc-1)+'/'+inttostr(lValidItems)+' volumes: '+inttostr(lRepeatLocations));
result := Dicom2NII(lDICOMra,lStartImg,lInc-1,lOutDirname,lPrefs,lRepeatLocations);
if not result then
lError := true;
lPrevDICOM := lDICOMra^[lInc];
lStartImg := lInc;
lRepeatLocations := 1;
- //end else if (lDICOMra^[lInc].location = lPrevDICOM.Location) then begin
- end else if (lDICOMra^[lInc].PatientPosX = lPrevDICOM.PatientPosX) and
+ end else if //(lDICOMra^[lInc].location = lPrevDICOM.Location) and
+ (lDICOMra^[lInc].PatientPosX = lPrevDICOM.PatientPosX) and
(lDICOMra^[lInc].PatientPosY = lPrevDICOM.PatientPosY) and
(lDICOMra^[lInc].PatientPosZ = lPrevDICOM.PatientPosZ) then begin
- //fx(lRepeatLocations,lDICOMra^[lInc].location);
+ //fx(lDICOMra^[lInc].PatientPosZ , lPrevDICOM.PatientPosZ );
+ //fx(666,lRepeatLocations,lDICOMra^[lInc].location, lPrevDICOM.Location);
inc(lRepeatLocations);
- end;
+ end else if (lInc > 1) and ( (lDICOMra^[lInc].AcquNum) > (lDICOMra^[lInc-1].AcquNum+999)) then //we increment acquisition number by 1000 to denote new echo
+ inc(lnumEchos);
end; //for each valid
+ if (lRepeatLocations < 2) and (lnumEchos > 1) then
+ lRepeatLocations := lnumEchos;
+ //fx(lPrevDICOM.PatientPosX, lPrevDICOM.PatientPosY, lPrevDICOM.PatientPosZ );
//Msg( inttostr(lValidItems-lStartImg+1)+' '+ inttostr(lRepeatLocations));
+ //fx(lRepeatLocations);
if (((lValidItems-lStartImg+1) mod lRepeatLocations) <> 0) then begin
Msg('*Warning: Number of images in series ('+inttostr(lValidItems-lStartImg+1)+') not divisible by number of volumes ('+inttostr(lRepeatLocations)+')');
Msg('* Perhaps the selected folder only has some of the images');
@@ -407,7 +418,7 @@ begin
Msg(' Perhaps the selected folder only has some of the images');
end;
- Msg('Converting '+inttostr(lValidItems)+'/'+inttostr(lValidItems)+' '+inttostr(lRepeatLocations));
+ Msg('Converting '+inttostr(lValidItems)+'/'+inttostr(lValidItems)+' volumes: '+inttostr(lRepeatLocations));
Dicom2NII(lDICOMra,lStartImg,lValidItems,lOutDirname,lPrefs,lRepeatLocations);
if lError then
result := false //at least one error
@@ -485,4 +496,4 @@ begin
result := LoadFileListInner (lOutDirName, lPrefs,lStringList)
end;
-end.
+end.
\ No newline at end of file
diff --git a/dcm2nii/untar.pas b/dcm2nii_prePARRECDTI/untar.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/untar.pas
copy to dcm2nii_prePARRECDTI/untar.pas
diff --git a/dcm2nii/userdir.pas b/dcm2nii_prePARRECDTI/userdir.pas
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/userdir.pas
copy to dcm2nii_prePARRECDTI/userdir.pas
diff --git a/dcm2nii/windowsxp.res b/dcm2nii_prePARRECDTI/windowsxp.res
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/windowsxp.res
copy to dcm2nii_prePARRECDTI/windowsxp.res
diff --git a/dcm2nii/zconf.inc b/dcm2nii_prePARRECDTI/zconf.inc
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/zconf.inc
copy to dcm2nii_prePARRECDTI/zconf.inc
diff --git a/example/attention.nii.gz b/example/attention.nii.gz
old mode 100644
new mode 100755
diff --git a/example/clipnearr.ini b/example/clipnearr.ini
old mode 100644
new mode 100755
diff --git a/example/cut2.ini b/example/cut2.ini
old mode 100644
new mode 100755
diff --git a/example/cutr.ini b/example/cutr.ini
old mode 100644
new mode 100755
diff --git a/example/dataset/1.voi b/example/dataset/1.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/10.voi b/example/dataset/10.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/11.voi b/example/dataset/11.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/12.voi b/example/dataset/12.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/13.voi b/example/dataset/13.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/14.voi b/example/dataset/14.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/15.voi b/example/dataset/15.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/16.voi b/example/dataset/16.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/17.voi b/example/dataset/17.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/18.voi b/example/dataset/18.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/19.voi b/example/dataset/19.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/2.voi b/example/dataset/2.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/20.voi b/example/dataset/20.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/21.voi b/example/dataset/21.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/22.voi b/example/dataset/22.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/23.voi b/example/dataset/23.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/24.voi b/example/dataset/24.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/3.voi b/example/dataset/3.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/4.voi b/example/dataset/4.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/5.voi b/example/dataset/5.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/6.voi b/example/dataset/6.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/7.voi b/example/dataset/7.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/8.voi b/example/dataset/8.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/9.voi b/example/dataset/9.voi
old mode 100644
new mode 100755
diff --git a/example/dataset/binomial.val b/example/dataset/binomial.val
old mode 100644
new mode 100755
diff --git a/example/dataset/continuous.val b/example/dataset/continuous.val
old mode 100644
new mode 100755
diff --git a/example/fmri2r.ini b/example/fmri2r.ini
old mode 100644
new mode 100755
diff --git a/example/fmri3r.ini b/example/fmri3r.ini
old mode 100644
new mode 100755
diff --git a/example/fmrir.ini b/example/fmrir.ini
old mode 100644
new mode 100755
diff --git a/example/lesionm.ini b/example/lesionm.ini
old mode 100644
new mode 100755
diff --git a/example/saccades.nii.gz b/example/saccades.nii.gz
old mode 100644
new mode 100755
diff --git a/exampleclip.bat b/exampleclip.bat
old mode 100644
new mode 100755
diff --git a/examplecut.bat b/examplecut.bat
old mode 100644
new mode 100755
diff --git a/examplefmri.bat b/examplefmri.bat
old mode 100644
new mode 100755
diff --git a/examplefmri2.bat b/examplefmri2.bat
old mode 100644
new mode 100755
diff --git a/examplefmri3.bat b/examplefmri3.bat
old mode 100644
new mode 100755
diff --git a/extrafpc.cfg b/extrafpc.cfg
old mode 100644
new mode 100755
diff --git a/fastsmooth.pas b/fastsmooth.pas
old mode 100644
new mode 100755
diff --git a/fdr.pas b/fdr.pas
old mode 100644
new mode 100755
diff --git a/fpc-res.or b/fpc-res.or
old mode 100644
new mode 100755
diff --git a/fpc-res.res b/fpc-res.res
old mode 100644
new mode 100755
diff --git a/fpmath/changes.txt b/fpmath/changes.txt
old mode 100644
new mode 100755
diff --git a/fpmath/demo/curfit/mcsim.pas b/fpmath/demo/curfit/mcsim.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/curfit/pcatest.pas b/fpmath/demo/curfit/pcatest.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/curfit/reglin.pas b/fpmath/demo/curfit/reglin.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/curfit/regmult.pas b/fpmath/demo/curfit/regmult.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/curfit/regnlin.pas b/fpmath/demo/curfit/regnlin.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/curfit/regpoly.pas b/fpmath/demo/curfit/regpoly.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/curfit/wreglin.pas b/fpmath/demo/curfit/wreglin.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/equation/numjac.inc b/fpmath/demo/equation/numjac.inc
old mode 100644
new mode 100755
diff --git a/fpmath/demo/equation/testbis.pas b/fpmath/demo/equation/testbis.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/equation/testbrdn.pas b/fpmath/demo/equation/testbrdn.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/equation/testnr.pas b/fpmath/demo/equation/testnr.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/equation/testnr1.pas b/fpmath/demo/equation/testnr1.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/equation/testsec.pas b/fpmath/demo/equation/testsec.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/fmath/contour.pas b/fpmath/demo/fmath/contour.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/fmath/plot.pas b/fpmath/demo/fmath/plot.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/fmath/specfunc.pas b/fpmath/demo/fmath/specfunc.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/fmath/speed.pas b/fpmath/demo/fmath/speed.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/fmath/testfunc.pas b/fpmath/demo/fmath/testfunc.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/fmath/testmach.pas b/fpmath/demo/fmath/testmach.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/fmath/testw.pas b/fpmath/demo/fmath/testw.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/fourier/testfft.pas b/fpmath/demo/fourier/testfft.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/integral/conv.pas b/fpmath/demo/integral/conv.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/integral/gauss.pas b/fpmath/demo/integral/gauss.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/integral/test_rkf.pas b/fpmath/demo/integral/test_rkf.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/integral/trap.pas b/fpmath/demo/integral/trap.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/cholesk.pas b/fpmath/demo/matrices/cholesk.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/detinv.pas b/fpmath/demo/matrices/detinv.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/eigensym.pas b/fpmath/demo/matrices/eigensym.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/eigenval.pas b/fpmath/demo/matrices/eigenval.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/eigenvec.pas b/fpmath/demo/matrices/eigenvec.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/hilbert.pas b/fpmath/demo/matrices/hilbert.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/lineq1.pas b/fpmath/demo/matrices/lineq1.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/lineqm.pas b/fpmath/demo/matrices/lineqm.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/test_lu.pas b/fpmath/demo/matrices/test_lu.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/test_qr.pas b/fpmath/demo/matrices/test_qr.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/matrices/test_svd.pas b/fpmath/demo/matrices/test_svd.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/optim/minline.pas b/fpmath/demo/optim/minline.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/optim/numgrad.inc b/fpmath/demo/optim/numgrad.inc
old mode 100644
new mode 100755
diff --git a/fpmath/demo/optim/numhess.inc b/fpmath/demo/optim/numhess.inc
old mode 100644
new mode 100755
diff --git a/fpmath/demo/optim/testbfgs.pas b/fpmath/demo/optim/testbfgs.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/optim/testmarq.pas b/fpmath/demo/optim/testmarq.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/optim/testnewt.pas b/fpmath/demo/optim/testnewt.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/optim/testsimp.pas b/fpmath/demo/optim/testsimp.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/polynom/evalfrac.pas b/fpmath/demo/polynom/evalfrac.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/polynom/evalpoly.pas b/fpmath/demo/polynom/evalpoly.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/polynom/polyroot.pas b/fpmath/demo/polynom/polyroot.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/proba/binom.pas b/fpmath/demo/proba/binom.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/mt.txt b/fpmath/demo/random/mt.txt
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/randfile.pas b/fpmath/demo/random/randfile.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/ranmul.pas b/fpmath/demo/random/ranmul.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/ranmull.pas b/fpmath/demo/random/ranmull.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/test_ga.pas b/fpmath/demo/random/test_ga.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/test_sa.pas b/fpmath/demo/random/test_sa.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/testmcmc.pas b/fpmath/demo/random/testmcmc.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/testmt.pas b/fpmath/demo/random/testmt.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/testmwc.pas b/fpmath/demo/random/testmwc.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/testnorm.pas b/fpmath/demo/random/testnorm.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/testuvag.pas b/fpmath/demo/random/testuvag.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/random/uvag.txt b/fpmath/demo/random/uvag.txt
old mode 100644
new mode 100755
diff --git a/fpmath/demo/stat/av1.pas b/fpmath/demo/stat/av1.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/stat/av2.pas b/fpmath/demo/stat/av2.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/stat/av2a.pas b/fpmath/demo/stat/av2a.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/stat/histo.pas b/fpmath/demo/stat/histo.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/stat/khi2.pas b/fpmath/demo/stat/khi2.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/stat/stat.pas b/fpmath/demo/stat/stat.pas
old mode 100644
new mode 100755
diff --git a/fpmath/demo/stat/student.pas b/fpmath/demo/stat/student.pas
old mode 100644
new mode 100755
diff --git a/fpmath/dll/dcompil.bat b/fpmath/dll/dcompil.bat
old mode 100644
new mode 100755
diff --git a/fpmath/dll/fpcompil.bat b/fpmath/dll/fpcompil.bat
old mode 100644
new mode 100755
diff --git a/fpmath/dll/fpcompil.sh b/fpmath/dll/fpcompil.sh
old mode 100644
new mode 100755
diff --git a/fpmath/dll/tpgraph.dpr b/fpmath/dll/tpgraph.dpr
old mode 100644
new mode 100755
diff --git a/fpmath/dll/tpgraph.pas b/fpmath/dll/tpgraph.pas
old mode 100644
new mode 100755
diff --git a/fpmath/dll/tpmath.dpr b/fpmath/dll/tpmath.dpr
old mode 100644
new mode 100755
diff --git a/fpmath/dll/tpmath.pas b/fpmath/dll/tpmath.pas
old mode 100644
new mode 100755
diff --git a/fpmath/filelist.txt b/fpmath/filelist.txt
old mode 100644
new mode 100755
diff --git a/fpmath/lgpl.txt b/fpmath/lgpl.txt
old mode 100644
new mode 100755
diff --git a/fpmath/regmult.pas b/fpmath/regmult.pas
old mode 100644
new mode 100755
diff --git a/fpmath/tpmath.pdf b/fpmath/tpmath.pdf
old mode 100644
new mode 100755
diff --git a/fpmath/tpmath.txt b/fpmath/tpmath.txt
old mode 100644
new mode 100755
diff --git a/fpmath/types.inc b/fpmath/types.inc
old mode 100644
new mode 100755
diff --git a/fpmath/uanova1.pas b/fpmath/uanova1.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uanova2.pas b/fpmath/uanova2.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ubalance.pas b/fpmath/ubalance.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ubalbak.pas b/fpmath/ubalbak.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ubartlet.pas b/fpmath/ubartlet.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ubeta.pas b/fpmath/ubeta.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ubfgs.pas b/fpmath/ubfgs.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ubinom.pas b/fpmath/ubinom.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ubisect.pas b/fpmath/ubisect.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ubroyden.pas b/fpmath/ubroyden.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ucholesk.pas b/fpmath/ucholesk.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ucompvec.pas b/fpmath/ucompvec.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ucorrel.pas b/fpmath/ucorrel.pas
old mode 100644
new mode 100755
diff --git a/fpmath/udigamma.pas b/fpmath/udigamma.pas
old mode 100644
new mode 100755
diff --git a/fpmath/udistrib.pas b/fpmath/udistrib.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ueigval.pas b/fpmath/ueigval.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ueigvec.pas b/fpmath/ueigvec.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uelmhes.pas b/fpmath/uelmhes.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ueltran.pas b/fpmath/ueltran.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uexpdist.pas b/fpmath/uexpdist.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ufact.pas b/fpmath/ufact.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ufft.pas b/fpmath/ufft.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ugamdist.pas b/fpmath/ugamdist.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ugamma.pas b/fpmath/ugamma.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ugausjor.pas b/fpmath/ugausjor.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ugausleg.pas b/fpmath/ugausleg.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ugenalg.pas b/fpmath/ugenalg.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ugoldsrc.pas b/fpmath/ugoldsrc.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uhqr.pas b/fpmath/uhqr.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uhqr2.pas b/fpmath/uhqr2.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uhyper.pas b/fpmath/uhyper.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uibeta.pas b/fpmath/uibeta.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uibtdist.pas b/fpmath/uibtdist.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uigamma.pas b/fpmath/uigamma.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uigmdist.pas b/fpmath/uigmdist.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uinterv.pas b/fpmath/uinterv.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uinvbeta.pas b/fpmath/uinvbeta.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uinvgam.pas b/fpmath/uinvgam.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uinvnorm.pas b/fpmath/uinvnorm.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ujacobi.pas b/fpmath/ujacobi.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ukhi2.pas b/fpmath/ukhi2.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ulambert.pas b/fpmath/ulambert.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ulineq.pas b/fpmath/ulineq.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ulinfit.pas b/fpmath/ulinfit.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ulinmin.pas b/fpmath/ulinmin.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ulinminq.pas b/fpmath/ulinminq.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ulu.pas b/fpmath/ulu.pas
old mode 100644
new mode 100755
diff --git a/fpmath/umarq.pas b/fpmath/umarq.pas
old mode 100644
new mode 100755
diff --git a/fpmath/umath.pas b/fpmath/umath.pas
old mode 100644
new mode 100755
diff --git a/fpmath/umcmc.pas b/fpmath/umcmc.pas
old mode 100644
new mode 100755
diff --git a/fpmath/umeansd.pas b/fpmath/umeansd.pas
old mode 100644
new mode 100755
diff --git a/fpmath/umedian.pas b/fpmath/umedian.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uminbrak.pas b/fpmath/uminbrak.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uminmax.pas b/fpmath/uminmax.pas
old mode 100644
new mode 100755
diff --git a/fpmath/umulfit.pas b/fpmath/umulfit.pas
old mode 100644
new mode 100755
diff --git a/fpmath/unewteq.pas b/fpmath/unewteq.pas
old mode 100644
new mode 100755
diff --git a/fpmath/unewteqs.pas b/fpmath/unewteqs.pas
old mode 100644
new mode 100755
diff --git a/fpmath/unewton.pas b/fpmath/unewton.pas
old mode 100644
new mode 100755
diff --git a/fpmath/unlfit.pas b/fpmath/unlfit.pas
old mode 100644
new mode 100755
diff --git a/fpmath/unonpar.pas b/fpmath/unonpar.pas
old mode 100644
new mode 100755
diff --git a/fpmath/unormal.pas b/fpmath/unormal.pas
old mode 100644
new mode 100755
diff --git a/fpmath/upca.pas b/fpmath/upca.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uplot.pas b/fpmath/uplot.pas
old mode 100644
new mode 100755
diff --git a/fpmath/upoidist.pas b/fpmath/upoidist.pas
old mode 100644
new mode 100755
diff --git a/fpmath/upolev.pas b/fpmath/upolev.pas
old mode 100644
new mode 100755
diff --git a/fpmath/upolfit.pas b/fpmath/upolfit.pas
old mode 100644
new mode 100755
diff --git a/fpmath/upolutil.pas b/fpmath/upolutil.pas
old mode 100644
new mode 100755
diff --git a/fpmath/upolynom.pas b/fpmath/upolynom.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uqr.pas b/fpmath/uqr.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uqsort.pas b/fpmath/uqsort.pas
old mode 100644
new mode 100755
diff --git a/fpmath/urandom.pas b/fpmath/urandom.pas
old mode 100644
new mode 100755
diff --git a/fpmath/urangaus.pas b/fpmath/urangaus.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uranmt.pas b/fpmath/uranmt.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uranmult.pas b/fpmath/uranmult.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uranmwc.pas b/fpmath/uranmwc.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uranuvag.pas b/fpmath/uranuvag.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uregtest.pas b/fpmath/uregtest.pas
old mode 100644
new mode 100755
diff --git a/fpmath/urkf.pas b/fpmath/urkf.pas
old mode 100644
new mode 100755
diff --git a/fpmath/urootpol.pas b/fpmath/urootpol.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uround.pas b/fpmath/uround.pas
old mode 100644
new mode 100755
diff --git a/fpmath/urtpol1.pas b/fpmath/urtpol1.pas
old mode 100644
new mode 100755
diff --git a/fpmath/urtpol2.pas b/fpmath/urtpol2.pas
old mode 100644
new mode 100755
diff --git a/fpmath/urtpol3.pas b/fpmath/urtpol3.pas
old mode 100644
new mode 100755
diff --git a/fpmath/urtpol4.pas b/fpmath/urtpol4.pas
old mode 100644
new mode 100755
diff --git a/fpmath/usecant.pas b/fpmath/usecant.pas
old mode 100644
new mode 100755
diff --git a/fpmath/usimann.pas b/fpmath/usimann.pas
old mode 100644
new mode 100755
diff --git a/fpmath/usimplex.pas b/fpmath/usimplex.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uskew.pas b/fpmath/uskew.pas
old mode 100644
new mode 100755
diff --git a/fpmath/usnedeco.pas b/fpmath/usnedeco.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ustdpair.pas b/fpmath/ustdpair.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ustrings.pas b/fpmath/ustrings.pas
old mode 100644
new mode 100755
diff --git a/fpmath/ustudind.pas b/fpmath/ustudind.pas
old mode 100644
new mode 100755
diff --git a/fpmath/usvd.pas b/fpmath/usvd.pas
old mode 100644
new mode 100755
diff --git a/fpmath/usvdfit.pas b/fpmath/usvdfit.pas
old mode 100644
new mode 100755
diff --git a/fpmath/utrapint.pas b/fpmath/utrapint.pas
old mode 100644
new mode 100755
diff --git a/fpmath/utrigo.pas b/fpmath/utrigo.pas
old mode 100644
new mode 100755
diff --git a/fpmath/utypes.pas b/fpmath/utypes.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uwinplot.pas b/fpmath/uwinplot.pas
old mode 100644
new mode 100755
diff --git a/fpmath/uwoolf.pas b/fpmath/uwoolf.pas
old mode 100644
new mode 100755
diff --git a/fx8.pas b/fx8.pas
old mode 100644
new mode 100755
diff --git a/graphx.lfm b/graphx.lfm
old mode 100644
new mode 100755
diff --git a/graphx.lrs b/graphx.lrs
old mode 100644
new mode 100755
diff --git a/graphx.pas b/graphx.pas
old mode 100644
new mode 100755
diff --git a/gzio20.pas b/gzio20.pas
old mode 100644
new mode 100755
diff --git a/histoform.lfm b/histoform.lfm
old mode 100644
new mode 100755
index 5c52f80..f392566
--- a/histoform.lfm
+++ b/histoform.lfm
@@ -4,28 +4,29 @@ object HistogramForm: THistogramForm
Top = 272
Width = 465
Caption = 'Histogram'
- ClientHeight = 317
+ ClientHeight = 336
ClientWidth = 465
Font.Height = -11
Font.Name = 'MS Sans Serif'
Menu = MainMenu1
+ OnCreate = FormCreate
Position = poScreenCenter
- LCLVersion = '0.9.29'
+ LCLVersion = '0.9.30.2'
object HistoPanel: TScrollBox
Left = 0
- Height = 317
+ Height = 336
Top = 0
Width = 465
Align = alClient
- ClientHeight = 313
- ClientWidth = 461
+ ClientHeight = 336
+ ClientWidth = 465
TabOrder = 0
object HistoImage: TImage
Cursor = crCross
Left = 0
- Height = 313
+ Height = 336
Top = 0
- Width = 461
+ Width = 465
Align = alClient
AutoSize = True
Center = True
@@ -56,4 +57,4 @@ object HistogramForm: THistogramForm
end
end
end
-end
+end
\ No newline at end of file
diff --git a/histoform.lrs b/histoform.lrs
old mode 100644
new mode 100755
index 18f9147..ae70736
--- a/histoform.lrs
+++ b/histoform.lrs
@@ -2,19 +2,19 @@
LazarusResources.Add('THistogramForm','FORMDATA',[
'TPF0'#14'THistogramForm'#13'HistogramForm'#4'Left'#3#239#3#6'Height'#3'P'#1#3
- +'Top'#3#16#1#5'Width'#3#209#1#7'Caption'#6#9'Histogram'#12'ClientHeight'#3'='
+ +'Top'#3#16#1#5'Width'#3#209#1#7'Caption'#6#9'Histogram'#12'ClientHeight'#3'P'
+#1#11'ClientWidth'#3#209#1#11'Font.Height'#2#245#9'Font.Name'#6#13'MS Sans S'
- +'erif'#4'Menu'#7#9'MainMenu1'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'
- +#6#6'0.9.29'#0#10'TScrollBox'#10'HistoPanel'#4'Left'#2#0#6'Height'#3'='#1#3
- +'Top'#2#0#5'Width'#3#209#1#5'Align'#7#8'alClient'#12'ClientHeight'#3'9'#1#11
- +'ClientWidth'#3#205#1#8'TabOrder'#2#0#0#6'TImage'#10'HistoImage'#6'Cursor'#7
- +#7'crCross'#4'Left'#2#0#6'Height'#3'9'#1#3'Top'#2#0#5'Width'#3#205#1#5'Align'
- +#7#8'alClient'#8'AutoSize'#9#6'Center'#9#0#0#0#9'TMainMenu'#9'MainMenu1'#4'l'
- +'eft'#2'q'#3'top'#2'3'#0#9'TMenuItem'#5'File1'#7'Caption'#6#4'File'#0#9'TMen'
- +'uItem'#13'Saveasbitmap1'#7'Caption'#6#17'Save as bitmap...'#8'ShortCut'#3'S'
- +'@'#7'OnClick'#7#18'Saveasbitmap1Click'#0#0#9'TMenuItem'#12'Closewindow1'#7
- +'Caption'#6#12'Close window'#8'ShortCut'#3'W@'#7'OnClick'#7#17'Closewindow1C'
- +'lick'#0#0#0#9'TMenuItem'#5'Edit1'#7'Caption'#6#4'Edit'#0#9'TMenuItem'#5'Cop'
- +'y1'#7'Caption'#6#4'Copy'#8'ShortCut'#3'C@'#7'OnClick'#7#10'Copy1Click'#0#0#0
- +#0#0
-]);
+ +'erif'#4'Menu'#7#9'MainMenu1'#8'OnCreate'#7#10'FormCreate'#8'Position'#7#14
+ +'poScreenCenter'#10'LCLVersion'#6#8'0.9.30.2'#0#10'TScrollBox'#10'HistoPanel'
+ +#4'Left'#2#0#6'Height'#3'P'#1#3'Top'#2#0#5'Width'#3#209#1#5'Align'#7#8'alCli'
+ +'ent'#12'ClientHeight'#3'P'#1#11'ClientWidth'#3#209#1#8'TabOrder'#2#0#0#6'TI'
+ +'mage'#10'HistoImage'#6'Cursor'#7#7'crCross'#4'Left'#2#0#6'Height'#3'P'#1#3
+ +'Top'#2#0#5'Width'#3#209#1#5'Align'#7#8'alClient'#8'AutoSize'#9#6'Center'#9#0
+ +#0#0#9'TMainMenu'#9'MainMenu1'#4'left'#2'q'#3'top'#2'3'#0#9'TMenuItem'#5'Fil'
+ +'e1'#7'Caption'#6#4'File'#0#9'TMenuItem'#13'Saveasbitmap1'#7'Caption'#6#17'S'
+ +'ave as bitmap...'#8'ShortCut'#3'S@'#7'OnClick'#7#18'Saveasbitmap1Click'#0#0
+ +#9'TMenuItem'#12'Closewindow1'#7'Caption'#6#12'Close window'#8'ShortCut'#3'W'
+ +'@'#7'OnClick'#7#17'Closewindow1Click'#0#0#0#9'TMenuItem'#5'Edit1'#7'Caption'
+ +#6#4'Edit'#0#9'TMenuItem'#5'Copy1'#7'Caption'#6#4'Copy'#8'ShortCut'#3'C@'#7
+ +'OnClick'#7#10'Copy1Click'#0#0#0#0#0
+]);
\ No newline at end of file
diff --git a/histoform.pas b/histoform.pas
old mode 100644
new mode 100755
index d610cd3..033108b
--- a/histoform.pas
+++ b/histoform.pas
@@ -10,6 +10,9 @@ uses
Menus, ExtCtrls,ClipBrd;
type
+
+ { THistogramForm }
+
THistogramForm = class(TForm)
HistoPanel: TScrollBox;
HistoImage: TImage;
@@ -21,6 +24,7 @@ type
Closewindow1: TMenuItem;
procedure Copy1Click(Sender: TObject);
procedure Closewindow1Click(Sender: TObject);
+ procedure FormCreate(Sender: TObject);
procedure Saveasbitmap1Click(Sender: TObject);
private
{ Private declarations }
@@ -67,6 +71,17 @@ begin
HistogramForm.Close;
end;
+procedure THistogramForm.FormCreate(Sender: TObject);
+begin
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+ Copy1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ Saveasbitmap1.ShortCut := ShortCut(Word('S'), [ssMeta]);
+ Closewindow1.ShortCut := ShortCut(Word('W'), [ssMeta]);
+ {$ENDIF}
+ {$ENDIF}
+end;
+
procedure THistogramForm.Saveasbitmap1Click(Sender: TObject);
begin
{$IFNDEF FPC}
@@ -81,4 +96,4 @@ initialization
{$I histoform.lrs}
{$ENDIF}
-end.
+end.
\ No newline at end of file
diff --git a/hrf.pas b/hrf.pas
old mode 100644
new mode 100755
diff --git a/html/bat.html b/html/bat.html
old mode 100644
new mode 100755
diff --git a/html/dcm2nii.html b/html/dcm2nii.html
old mode 100644
new mode 100755
diff --git a/html/images/48x36.gif b/html/images/48x36.gif
old mode 100644
new mode 100755
diff --git a/html/images/autocrop.jpg b/html/images/autocrop.jpg
old mode 100644
new mode 100755
diff --git a/html/images/dcm2niigui.gif b/html/images/dcm2niigui.gif
old mode 100644
new mode 100755
diff --git a/html/images/design.gif b/html/images/design.gif
old mode 100644
new mode 100755
diff --git a/html/images/draw/3dfill.png b/html/images/draw/3dfill.png
old mode 100644
new mode 100755
diff --git a/html/images/draw/circle.png b/html/images/draw/circle.png
old mode 100644
new mode 100755
diff --git a/html/images/draw/closedpen.png b/html/images/draw/closedpen.png
old mode 100644
new mode 100755
diff --git a/html/images/draw/fill.png b/html/images/draw/fill.png
old mode 100644
new mode 100755
diff --git a/html/images/draw/pen.png b/html/images/draw/pen.png
old mode 100644
new mode 100755
diff --git a/html/images/examplefmri.jpg b/html/images/examplefmri.jpg
old mode 100644
new mode 100755
diff --git a/html/images/examplefmri_multi.jpg b/html/images/examplefmri_multi.jpg
old mode 100644
new mode 100755
diff --git a/html/images/icon.png b/html/images/icon.png
old mode 100644
new mode 100755
diff --git a/html/images/layers.gif b/html/images/layers.gif
old mode 100644
new mode 100755
diff --git a/html/images/lazarus.gif b/html/images/lazarus.gif
old mode 100644
new mode 100755
diff --git a/html/images/lesionsum.jpg b/html/images/lesionsum.jpg
old mode 100644
new mode 100755
diff --git a/html/images/lieber.gif b/html/images/lieber.gif
old mode 100644
new mode 100755
diff --git a/html/images/main.jpg b/html/images/main.jpg
old mode 100644
new mode 100755
diff --git a/html/images/meld.jpg b/html/images/meld.jpg
old mode 100644
new mode 100755
diff --git a/html/images/nifti.jpg b/html/images/nifti.jpg
old mode 100644
new mode 100755
diff --git a/html/images/npm.gif b/html/images/npm.gif
old mode 100644
new mode 100755
diff --git a/html/images/patient9.jpg b/html/images/patient9.jpg
old mode 100644
new mode 100755
diff --git a/html/images/prefs.gif b/html/images/prefs.gif
old mode 100644
new mode 100755
diff --git a/html/images/renderAAL.gif b/html/images/renderAAL.gif
old mode 100644
new mode 100755
diff --git a/html/images/results.jpg b/html/images/results.jpg
old mode 100644
new mode 100755
diff --git a/html/images/space.gif b/html/images/space.gif
old mode 100644
new mode 100755
diff --git a/html/images/splash.jpg b/html/images/splash.jpg
old mode 100644
new mode 100755
diff --git a/html/images/threshold.gif b/html/images/threshold.gif
old mode 100644
new mode 100755
diff --git a/html/images/transparency.gif b/html/images/transparency.gif
old mode 100644
new mode 100755
diff --git a/html/images/val.gif b/html/images/val.gif
old mode 100644
new mode 100755
diff --git a/html/images/zhistogram.gif b/html/images/zhistogram.gif
old mode 100644
new mode 100755
diff --git a/html/index.html b/html/index.html
old mode 100644
new mode 100755
diff --git a/html/install.html b/html/install.html
old mode 100644
new mode 100755
diff --git a/html/main.html b/html/main.html
old mode 100644
new mode 100755
diff --git a/html/peri/images/eventtime.png b/html/peri/images/eventtime.png
old mode 100644
new mode 100755
diff --git a/html/peri/images/icon.png b/html/peri/images/icon.png
old mode 100644
new mode 100755
diff --git a/html/peri/images/meld.jpg b/html/peri/images/meld.jpg
old mode 100644
new mode 100755
diff --git a/html/peri/images/periset.png b/html/peri/images/periset.png
old mode 100644
new mode 100755
diff --git a/html/peri/images/peristimulusplot.png b/html/peri/images/peristimulusplot.png
old mode 100644
new mode 100755
diff --git a/html/peri/images/perivol.png b/html/peri/images/perivol.png
old mode 100644
new mode 100755
diff --git a/html/peri/images/timeline.png b/html/peri/images/timeline.png
old mode 100644
new mode 100755
diff --git a/html/peri/index.html b/html/peri/index.html
old mode 100644
new mode 100755
diff --git a/html/source.html b/html/source.html
old mode 100644
new mode 100755
diff --git a/html/stats.html b/html/stats.html
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/design.gif b/html/tutorial/images/design.gif
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/icon.png b/html/tutorial/images/icon.png
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/lesionsum.jpg b/html/tutorial/images/lesionsum.jpg
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/lieber.gif b/html/tutorial/images/lieber.gif
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/meld.jpg b/html/tutorial/images/meld.jpg
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/npm.gif b/html/tutorial/images/npm.gif
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/patient9.jpg b/html/tutorial/images/patient9.jpg
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/results.jpg b/html/tutorial/images/results.jpg
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/threshold.gif b/html/tutorial/images/threshold.gif
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/val.gif b/html/tutorial/images/val.gif
old mode 100644
new mode 100755
diff --git a/html/tutorial/images/zhistogram.gif b/html/tutorial/images/zhistogram.gif
old mode 100644
new mode 100755
diff --git a/iconfinal.ico b/iconfinal.ico
old mode 100644
new mode 100755
diff --git a/icons/dcm2niigui.png b/icons/dcm2niigui.png
old mode 100644
new mode 100755
diff --git a/icons/mricrogl.png b/icons/mricrogl.png
old mode 100644
new mode 100755
diff --git a/icons/mricron.png b/icons/mricron.png
old mode 100644
new mode 100755
diff --git a/icons/npm.png b/icons/npm.png
old mode 100644
new mode 100755
diff --git a/imgutil.pas b/imgutil.pas
old mode 100644
new mode 100755
diff --git a/isthreaded.inc b/isthreaded.inc
old mode 100644
new mode 100755
diff --git a/landmarks.lfm b/landmarks.lfm
old mode 100644
new mode 100755
diff --git a/landmarks.lrs b/landmarks.lrs
old mode 100644
new mode 100755
diff --git a/landmarks.pas b/landmarks.pas
old mode 100644
new mode 100755
diff --git a/license.txt b/license.txt
old mode 100644
new mode 100755
diff --git a/lut/16.lut b/lut/16.lut
old mode 100644
new mode 100755
diff --git a/lut/1hot.lut b/lut/1hot.lut
old mode 100644
new mode 100755
diff --git a/lut/2winter.lut b/lut/2winter.lut
old mode 100644
new mode 100755
diff --git a/lut/3warm.lut b/lut/3warm.lut
old mode 100644
new mode 100755
diff --git a/lut/4cool.lut b/lut/4cool.lut
old mode 100644
new mode 100755
diff --git a/lut/5redyell.lut b/lut/5redyell.lut
old mode 100644
new mode 100755
diff --git a/lut/6bluegrn.lut b/lut/6bluegrn.lut
old mode 100644
new mode 100755
diff --git a/lut/GE_color.lut b/lut/GE_color.lut
old mode 100644
new mode 100755
diff --git a/lut/HOTIRON.lut b/lut/HOTIRON.lut
old mode 100644
new mode 100755
diff --git a/lut/NIH.lut b/lut/NIH.lut
old mode 100644
new mode 100755
diff --git a/lut/NIH_fire.lut b/lut/NIH_fire.lut
old mode 100644
new mode 100755
diff --git a/lut/NIH_ice.lut b/lut/NIH_ice.lut
old mode 100644
new mode 100755
diff --git a/lut/Rainramp.lut b/lut/Rainramp.lut
old mode 100644
new mode 100755
diff --git a/lut/actc.lut b/lut/actc.lut
old mode 100644
new mode 100755
diff --git a/lut/blackbdy.lut b/lut/blackbdy.lut
old mode 100644
new mode 100755
diff --git a/lut/blue_otto.lut b/lut/blue_otto.lut
old mode 100644
new mode 100755
diff --git a/lut/bluegray.lut b/lut/bluegray.lut
old mode 100644
new mode 100755
diff --git a/lut/bone.lut b/lut/bone.lut
old mode 100644
new mode 100755
diff --git a/lut/cardiac.lut b/lut/cardiac.lut
old mode 100644
new mode 100755
diff --git a/lut/cortex.lut b/lut/cortex.lut
old mode 100644
new mode 100755
diff --git a/lut/flow.lut b/lut/flow.lut
old mode 100644
new mode 100755
diff --git a/lut/french.lut b/lut/french.lut
old mode 100644
new mode 100755
diff --git a/lut/gold.lut b/lut/gold.lut
old mode 100644
new mode 100755
diff --git a/lut/gooch.lut b/lut/gooch.lut
old mode 100644
new mode 100755
diff --git a/lut/greengray.lut b/lut/greengray.lut
old mode 100644
new mode 100755
diff --git a/lut/overlay_classic.lut b/lut/overlay_classic.lut
old mode 100644
new mode 100755
diff --git a/lut/pink.lut b/lut/pink.lut
old mode 100644
new mode 100755
diff --git a/lut/pink_old.lut b/lut/pink_old.lut
old mode 100644
new mode 100755
diff --git a/lut/red_otto.lut b/lut/red_otto.lut
old mode 100644
new mode 100755
diff --git a/lut/spectrum.lut b/lut/spectrum.lut
old mode 100644
new mode 100755
diff --git a/lut/surface.lut b/lut/surface.lut
old mode 100644
new mode 100755
diff --git a/lut/x_hot.lut b/lut/x_hot.lut
old mode 100644
new mode 100755
diff --git a/lut/x_rain.lut b/lut/x_rain.lut
old mode 100644
new mode 100755
diff --git a/manifest.res b/manifest.res
old mode 100644
new mode 100755
diff --git a/metagraph.pas b/metagraph.pas
old mode 100644
new mode 100755
diff --git a/mini.bmp b/mini.bmp
old mode 100644
new mode 100755
diff --git a/mni.lfm b/mni.lfm
old mode 100644
new mode 100755
diff --git a/mni.lrs b/mni.lrs
old mode 100644
new mode 100755
diff --git a/mni.pas b/mni.pas
old mode 100644
new mode 100755
diff --git a/dcm2nii/dcm2niigui.app/Contents/Info.plist b/mricron.app/Contents/Info.plist
similarity index 89%
rename from dcm2nii/dcm2niigui.app/Contents/Info.plist
rename to mricron.app/Contents/Info.plist
index 60af24a..de29ee6 100644
--- a/dcm2nii/dcm2niigui.app/Contents/Info.plist
+++ b/mricron.app/Contents/Info.plist
@@ -5,17 +5,17 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
- <string>dcm2niigui</string>
+ <string>mricron</string>
<key>CFBundleName</key>
- <string>dcm2niigui</string>
+ <string>MRIcron</string>
<key>CFBundleIdentifier</key>
- <string>com.company.dcm2niigui</string>
+ <string>com.company.mricron</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
- <string>dcm2</string>
+ <string>mric</string>
<key>CFBundleShortVersionString</key>
<string>0.1</string>
<key>CFBundleVersion</key>
diff --git a/mricron.app/Contents/MacOS/mricron b/mricron.app/Contents/MacOS/mricron
new file mode 120000
index 0000000..36c5b68
--- /dev/null
+++ b/mricron.app/Contents/MacOS/mricron
@@ -0,0 +1 @@
+../../../mricron
\ No newline at end of file
diff --git a/dcm2nii/dcm2nii.app/Contents/PkgInfo b/mricron.app/Contents/PkgInfo
similarity index 100%
copy from dcm2nii/dcm2nii.app/Contents/PkgInfo
copy to mricron.app/Contents/PkgInfo
diff --git a/mricron.ico b/mricron.ico
old mode 100644
new mode 100755
diff --git a/mricron.ini b/mricron.ini
old mode 100644
new mode 100755
index 1aa9b68..04413e0
--- a/mricron.ini
+++ b/mricron.ini
@@ -1,8 +1,8 @@
[MRU]
-file1=C:\pas\mricron\templates\ch2bet.nii.gz
+file1=C:\Users\neuropsych\Desktop\dev\crap.nii
file0=C:\pas\mricron\templates\ch2bet.nii.gz
-file2=
-file3=
+file2=C:\Users\neuropsych\Desktop\cT1.nii.gz
+file3=C:\pas\mricron\templates\ch2bet.nii.gz
file4=
file5=
@@ -34,7 +34,7 @@ XBarGap=7
XBarThick=3
XBarClr=16711680
VOIClr=255
-BGTransPct=0
+BGTransPct=20
OverlayTransPct=20
MaxThreads=2
LesionSmooth=3
diff --git a/mricron.lpi b/mricron.lpi
old mode 100644
new mode 100755
index 00a9ff4..94f2cb2
--- a/mricron.lpi
+++ b/mricron.lpi
@@ -41,7 +41,7 @@
<Filename Value="mricron.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="mricron"/>
- <EditorIndex Value="7"/>
+ <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="16" Y="13"/>
@@ -65,10 +65,10 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="nifti_hdr_view"/>
- <EditorIndex Value="8"/>
+ <EditorIndex Value="3"/>
<WindowIndex Value="0"/>
- <TopLine Value="486"/>
- <CursorPos X="64" Y="486"/>
+ <TopLine Value="688"/>
+ <CursorPos X="1" Y="702"/>
<UsageCount Value="200"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
@@ -97,13 +97,10 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="about"/>
- <EditorIndex Value="5"/>
<WindowIndex Value="0"/>
<TopLine Value="4"/>
<CursorPos X="65" Y="40"/>
<UsageCount Value="200"/>
- <Loaded Value="True"/>
- <LoadedDesigner Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
@@ -122,9 +119,13 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="text"/>
- <TopLine Value="52"/>
- <CursorPos X="51" Y="63"/>
+ <EditorIndex Value="4"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="38"/>
+ <CursorPos X="1" Y="61"/>
<UsageCount Value="200"/>
+ <Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit7>
<Unit8>
@@ -176,11 +177,10 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="nifti_img_view"/>
- <IsVisibleTab Value="True"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="81" Y="5"/>
+ <TopLine Value="1372"/>
+ <CursorPos X="7" Y="1411"/>
<UsageCount Value="200"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
@@ -189,10 +189,10 @@
<Unit13>
<Filename Value="nifti_img.pas"/>
<UnitName Value="nifti_img"/>
- <EditorIndex Value="12"/>
+ <EditorIndex Value="7"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="128" Y="1"/>
+ <TopLine Value="1011"/>
+ <CursorPos X="3" Y="1019"/>
<UsageCount Value="100"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
@@ -225,8 +225,8 @@
<ResourceBaseClass Value="Form"/>
<UnitName Value="MultiSlice"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="30" Y="3"/>
+ <TopLine Value="847"/>
+ <CursorPos X="46" Y="851"/>
<UsageCount Value="200"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit16>
@@ -277,8 +277,9 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="histoform"/>
- <TopLine Value="1"/>
- <CursorPos X="9" Y="4"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="40"/>
+ <CursorPos X="1" Y="76"/>
<UsageCount Value="200"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit21>
@@ -390,10 +391,12 @@
<Filename Value="cropedges.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="CropEdgeForm"/>
+ <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="CropEdges"/>
- <TopLine Value="61"/>
- <CursorPos X="23" Y="76"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="81"/>
+ <CursorPos X="3" Y="83"/>
<UsageCount Value="200"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit35>
@@ -508,7 +511,7 @@
<WindowIndex Value="0"/>
<TopLine Value="385"/>
<CursorPos X="36" Y="391"/>
- <UsageCount Value="185"/>
+ <UsageCount Value="186"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit48>
<Unit49>
@@ -531,12 +534,13 @@
<Filename Value="prefs.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="PrefForm"/>
+ <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="prefs"/>
<WindowIndex Value="0"/>
- <TopLine Value="57"/>
- <CursorPos X="3" Y="59"/>
- <UsageCount Value="177"/>
+ <TopLine Value="10"/>
+ <CursorPos X="8" Y="81"/>
+ <UsageCount Value="178"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit51>
<Unit52>
@@ -610,7 +614,7 @@
<UnitName Value="perisettings"/>
<TopLine Value="81"/>
<CursorPos X="38" Y="96"/>
- <UsageCount Value="156"/>
+ <UsageCount Value="157"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit60>
<Unit61>
@@ -621,7 +625,7 @@
<UnitName Value="graphx"/>
<TopLine Value="1043"/>
<CursorPos X="29" Y="1055"/>
- <UsageCount Value="156"/>
+ <UsageCount Value="157"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit61>
<Unit62>
@@ -856,12 +860,10 @@
<Unit91>
<Filename Value="clustering.pas"/>
<UnitName Value="clustering"/>
- <EditorIndex Value="10"/>
<WindowIndex Value="0"/>
<TopLine Value="161"/>
<CursorPos X="6" Y="183"/>
<UsageCount Value="16"/>
- <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit91>
<Unit92>
@@ -872,7 +874,7 @@
<UnitName Value="ReadFloat"/>
<TopLine Value="38"/>
<CursorPos X="38" Y="53"/>
- <UsageCount Value="117"/>
+ <UsageCount Value="118"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit92>
<Unit93>
@@ -886,18 +888,21 @@
<Unit94>
<Filename Value="common\nifti_hdr.pas"/>
<UnitName Value="nifti_hdr"/>
- <TopLine Value="847"/>
- <CursorPos X="24" Y="850"/>
+ <EditorIndex Value="6"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="978"/>
+ <CursorPos X="53" Y="1001"/>
<UsageCount Value="18"/>
+ <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit94>
<Unit95>
<Filename Value="common\define_types.pas"/>
<UnitName Value="define_types"/>
- <EditorIndex Value="6"/>
+ <EditorIndex Value="1"/>
<WindowIndex Value="0"/>
- <TopLine Value="28"/>
- <CursorPos X="26" Y="58"/>
+ <TopLine Value="10"/>
+ <CursorPos X="27" Y="21"/>
<UsageCount Value="36"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
@@ -960,18 +965,22 @@
<Unit103>
<Filename Value="reslice_img.pas"/>
<UnitName Value="reslice_img"/>
- <TopLine Value="264"/>
- <CursorPos X="1" Y="279"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="450"/>
+ <CursorPos X="114" Y="462"/>
<UsageCount Value="17"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit103>
<Unit104>
<Filename Value="ortho_reorient.pas"/>
<UnitName Value="ortho_reorient"/>
+ <IsVisibleTab Value="True"/>
+ <EditorIndex Value="8"/>
<WindowIndex Value="0"/>
- <TopLine Value="376"/>
- <CursorPos X="24" Y="393"/>
+ <TopLine Value="253"/>
+ <CursorPos X="12" Y="257"/>
<UsageCount Value="11"/>
+ <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit104>
<Unit105>
@@ -1093,7 +1102,7 @@
<UnitName Value="landmarks"/>
<TopLine Value="166"/>
<CursorPos X="50" Y="175"/>
- <UsageCount Value="63"/>
+ <UsageCount Value="64"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit119>
<Unit120>
@@ -1113,7 +1122,7 @@
</Unit121>
<Unit122>
<Filename Value="common\isgui.inc"/>
- <EditorIndex Value="11"/>
+ <EditorIndex Value="5"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="57" Y="1"/>
@@ -1127,7 +1136,7 @@
<UnitName Value="batchstatselect"/>
<TopLine Value="58"/>
<CursorPos X="64" Y="69"/>
- <UsageCount Value="52"/>
+ <UsageCount Value="53"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit123>
<Unit124>
@@ -1141,12 +1150,10 @@
<Unit125>
<Filename Value="yokesharemem.pas"/>
<UnitName Value="yokesharemem"/>
- <EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="53"/>
<CursorPos X="14" Y="58"/>
<UsageCount Value="14"/>
- <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit125>
<Unit126>
@@ -1175,10 +1182,12 @@
<Unit129>
<Filename Value="common\dialogsx.pas"/>
<UnitName Value="dialogsx"/>
+ <EditorIndex Value="10"/>
<WindowIndex Value="0"/>
- <TopLine Value="6"/>
- <CursorPos X="18" Y="15"/>
+ <TopLine Value="118"/>
+ <CursorPos X="38" Y="119"/>
<UsageCount Value="14"/>
+ <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit129>
<Unit130>
@@ -1212,6 +1221,7 @@
<TopLine Value="206"/>
<CursorPos X="1" Y="228"/>
<UsageCount Value="11"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit133>
<Unit134>
<Filename Value="otsu2.pas"/>
@@ -1220,30 +1230,26 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="13" Y="98"/>
- <UsageCount Value="29"/>
+ <UsageCount Value="30"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit134>
<Unit135>
<Filename Value="CarbonOpenDoc.pas"/>
<UnitName Value="CarbonOpenDoc"/>
- <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="39" Y="6"/>
<UsageCount Value="12"/>
- <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit135>
<Unit136>
<Filename Value="fastsmooth.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="fastsmooth"/>
- <EditorIndex Value="3"/>
<WindowIndex Value="0"/>
<TopLine Value="16"/>
<CursorPos X="17" Y="28"/>
- <UsageCount Value="29"/>
- <Loaded Value="True"/>
+ <UsageCount Value="30"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit136>
<Unit137>
@@ -1251,8 +1257,8 @@
<UnitName Value="gzio2"/>
<EditorIndex Value="9"/>
<WindowIndex Value="0"/>
- <TopLine Value="761"/>
- <CursorPos X="15" Y="791"/>
+ <TopLine Value="75"/>
+ <CursorPos X="5" Y="82"/>
<UsageCount Value="12"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
@@ -1260,140 +1266,138 @@
<Unit138>
<Filename Value="otsuml.pas"/>
<UnitName Value="otsuml"/>
- <EditorIndex Value="4"/>
<WindowIndex Value="0"/>
<TopLine Value="275"/>
<CursorPos X="11" Y="15"/>
<UsageCount Value="11"/>
- <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit138>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="4859" Column="61" TopLine="1"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="5290" Column="16" TopLine="5263"/>
</Position1>
<Position2>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1" Column="105" TopLine="1"/>
+ <Filename Value="common\gzio2.pas"/>
+ <Caret Line="34" Column="79" TopLine="13"/>
</Position2>
<Position3>
<Filename Value="common\gzio2.pas"/>
- <Caret Line="699" Column="13" TopLine="668"/>
+ <Caret Line="35" Column="17" TopLine="13"/>
</Position3>
<Position4>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="3192" Column="2" TopLine="3183"/>
+ <Filename Value="common\gzio2.pas"/>
+ <Caret Line="36" Column="17" TopLine="13"/>
</Position4>
<Position5>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="23" Column="52" TopLine="4"/>
+ <Filename Value="common\gzio2.pas"/>
+ <Caret Line="125" Column="39" TopLine="119"/>
</Position5>
<Position6>
- <Filename Value="fastsmooth.pas"/>
- <Caret Line="8" Column="57" TopLine="2"/>
+ <Filename Value="common\gzio2.pas"/>
+ <Caret Line="126" Column="23" TopLine="118"/>
</Position6>
<Position7>
- <Filename Value="fastsmooth.pas"/>
- <Caret Line="9" Column="40" TopLine="2"/>
+ <Filename Value="common\gzio2.pas"/>
+ <Caret Line="125" Column="10" TopLine="116"/>
</Position7>
<Position8>
- <Filename Value="fastsmooth.pas"/>
- <Caret Line="14" Column="67" TopLine="2"/>
+ <Filename Value="common\gzio2.pas"/>
+ <Caret Line="97" Column="29" TopLine="95"/>
</Position8>
<Position9>
- <Filename Value="fastsmooth.pas"/>
- <Caret Line="28" Column="17" TopLine="16"/>
+ <Filename Value="common\gzio2.pas"/>
+ <Caret Line="33" Column="87" TopLine="26"/>
</Position9>
<Position10>
- <Filename Value="CarbonOpenDoc.pas"/>
- <Caret Line="3" Column="1" TopLine="1"/>
+ <Filename Value="common\gzio2.pas"/>
+ <Caret Line="1786" Column="3" TopLine="1779"/>
</Position10>
<Position11>
- <Filename Value="CarbonOpenDoc.pas"/>
- <Caret Line="10" Column="64" TopLine="1"/>
+ <Filename Value="common\dialogsx.pas"/>
+ <Caret Line="15" Column="18" TopLine="6"/>
</Position11>
<Position12>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="3" Column="28" TopLine="1"/>
+ <Filename Value="common\dialogsx.pas"/>
+ <Caret Line="6" Column="20" TopLine="1"/>
</Position12>
<Position13>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="27" Column="55" TopLine="1"/>
+ <Filename Value="common\dialogsx.pas"/>
+ <Caret Line="18" Column="31" TopLine="11"/>
</Position13>
<Position14>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1570" Column="50" TopLine="1511"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="5158" Column="4" TopLine="4881"/>
</Position14>
<Position15>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="4" Column="82" TopLine="1"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="14" Column="18" TopLine="7"/>
</Position15>
<Position16>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="5" Column="84" TopLine="1"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="5158" Column="67" TopLine="5152"/>
</Position16>
<Position17>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="225" Column="21" TopLine="171"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="5456" Column="29" TopLine="5450"/>
</Position17>
<Position18>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1223" Column="20" TopLine="1169"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="4261" Column="67" TopLine="4253"/>
</Position18>
<Position19>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1227" Column="29" TopLine="1173"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="4259" Column="24" TopLine="4252"/>
</Position19>
<Position20>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1245" Column="7" TopLine="1195"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="4258" Column="53" TopLine="4251"/>
</Position20>
<Position21>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1232" Column="17" TopLine="1195"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="3877" Column="24" TopLine="3870"/>
</Position21>
<Position22>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1244" Column="23" TopLine="1195"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="3876" Column="24" TopLine="3870"/>
</Position22>
<Position23>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1246" Column="54" TopLine="1224"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="62" Column="73" TopLine="55"/>
</Position23>
<Position24>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1241" Column="81" TopLine="1213"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="2248" Column="3" TopLine="2241"/>
</Position24>
<Position25>
- <Filename Value="about.pas"/>
- <Caret Line="40" Column="65" TopLine="4"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="2087" Column="28" TopLine="2079"/>
</Position25>
<Position26>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1170" Column="40" TopLine="1167"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="2000" Column="5" TopLine="2000"/>
</Position26>
<Position27>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1467" Column="41" TopLine="1462"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="2022" Column="30" TopLine="2017"/>
</Position27>
<Position28>
- <Filename Value="nifti_img_view.pas"/>
- <Caret Line="1461" Column="13" TopLine="1456"/>
+ <Filename Value="nifti_img.pas"/>
+ <Caret Line="1926" Column="22" TopLine="1919"/>
</Position28>
<Position29>
- <Filename Value="yokesharemem.pas"/>
- <Caret Line="36" Column="36" TopLine="1"/>
+ <Filename Value="ortho_reorient.pas"/>
+ <Caret Line="393" Column="24" TopLine="376"/>
</Position29>
<Position30>
- <Filename Value="common\define_types.pas"/>
- <Caret Line="2" Column="101" TopLine="1"/>
+ <Filename Value="ortho_reorient.pas"/>
+ <Caret Line="256" Column="6" TopLine="247"/>
</Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
- <Version Value="9"/>
+ <Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="mricron"/>
@@ -1416,6 +1420,8 @@
</CodeGeneration>
<Linking>
<Debugging>
+ <GenerateDebugInfo Value="False"/>
+ <UseLineInfoUnit Value="False"/>
<StripSymbols Value="True"/>
</Debugging>
<LinkSmart Value="True"/>
@@ -1443,4 +1449,4 @@
</Item2>
</Exceptions>
</Debugging>
-</CONFIG>
+</CONFIG>
\ No newline at end of file
diff --git a/mricron.lpr b/mricron.lpr
old mode 100644
new mode 100755
diff --git a/mricron.or b/mricron.or
old mode 100644
new mode 100755
index e4e0f9e..4a3628d
Binary files a/mricron.or and b/mricron.or differ
diff --git a/mricron.res b/mricron.res
old mode 100644
new mode 100755
index 7f1426e..d9c8b12
Binary files a/mricron.res and b/mricron.res differ
diff --git a/multislice/default.ini b/multislice/default.ini
old mode 100644
new mode 100755
diff --git a/neurodebian.txt b/neurodebian.txt
old mode 100644
new mode 100755
diff --git a/nifti_hdr_view.lfm b/nifti_hdr_view.lfm
old mode 100644
new mode 100755
index 64dca23..fcd42c7
--- a/nifti_hdr_view.lfm
+++ b/nifti_hdr_view.lfm
@@ -5,9 +5,9 @@ object HdrForm: THdrForm
Width = 542
ActiveControl = PageControl1
BorderIcons = [biSystemMenu]
- BorderStyle = bsDialog
+ BorderStyle = bsSingle
Caption = 'NIfTI Header Information'
- ClientHeight = 399
+ ClientHeight = 418
ClientWidth = 542
Constraints.MaxHeight = 418
Constraints.MaxWidth = 542
@@ -18,10 +18,10 @@ object HdrForm: THdrForm
OnCreate = FormCreate
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '0.9.30'
+ LCLVersion = '0.9.30.2'
object PageControl1: TPageControl
Left = 4
- Height = 371
+ Height = 395
Top = 4
Width = 534
ActivePage = TabRequired
@@ -35,21 +35,21 @@ object HdrForm: THdrForm
TabOrder = 0
object TabRequired: TTabSheet
Caption = 'Dimensions'
- ClientHeight = 342
- ClientWidth = 526
+ ClientHeight = 356
+ ClientWidth = 528
object Label21: TLabel
Left = 6
- Height = 17
+ Height = 18
Top = 6
- Width = 82
+ Width = 80
Caption = 'Header Type'
ParentColor = False
end
object Label1: TLabel
Left = 14
- Height = 17
+ Height = 18
Top = 35
- Width = 238
+ Width = 269
Caption = 'Dimension Length Spacing Unit'
Font.Name = 'MS Sans Serif'
ParentColor = False
@@ -57,31 +57,31 @@ object HdrForm: THdrForm
end
object Label2: TLabel
Left = 16
- Height = 17
+ Height = 18
Top = 67
- Width = 47
+ Width = 46
Caption = 'I Space'
ParentColor = False
end
object Label3: TLabel
Left = 16
- Height = 17
+ Height = 18
Top = 97
- Width = 51
+ Width = 49
Caption = 'J Space'
ParentColor = False
end
object Label4: TLabel
Left = 16
- Height = 17
+ Height = 18
Top = 131
- Width = 52
+ Width = 51
Caption = 'K Space'
ParentColor = False
end
object Label8: TLabel
Left = 6
- Height = 17
+ Height = 18
Top = 297
Width = 30
Caption = 'Data'
@@ -89,50 +89,50 @@ object HdrForm: THdrForm
end
object Label7: TLabel
Left = 294
- Height = 17
+ Height = 18
Top = 235
- Width = 35
+ Width = 41
Caption = 'Offset'
ParentColor = False
end
object Label44: TLabel
Left = 16
- Height = 17
+ Height = 18
Top = 166
- Width = 32
+ Width = 31
Caption = 'Time'
ParentColor = False
end
object Label29: TLabel
Left = 16
- Height = 17
+ Height = 18
Top = 198
- Width = 45
+ Width = 51
Caption = '5th Dim'
ParentColor = False
end
object Label41: TLabel
Left = 16
- Height = 17
+ Height = 18
Top = 230
- Width = 45
+ Width = 51
Caption = '6th Dim'
ParentColor = False
end
object Label42: TLabel
Left = 16
- Height = 17
+ Height = 18
Top = 265
- Width = 45
+ Width = 51
Caption = '7th Dim'
ParentColor = False
end
object HeaderMagicDrop: TComboBox
Left = 108
- Height = 24
+ Height = 20
Top = 2
Width = 239
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'Unknown'
'ni1: NIfTI separate file (hdr+.img)'
@@ -146,10 +146,10 @@ object HdrForm: THdrForm
end
object Endian: TComboBox
Left = 231
- Height = 24
+ Height = 20
Top = 291
Width = 210
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'Native Endian'
'Swapped Endian'
@@ -159,11 +159,11 @@ object HdrForm: THdrForm
end
object fTypeDrop: TComboBox
Left = 56
- Height = 24
+ Height = 20
Top = 291
Width = 152
DropDownCount = 20
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'binary'
'8-bit S'
@@ -188,10 +188,10 @@ object HdrForm: THdrForm
end
object xyzt_sizeDrop: TComboBox
Left = 262
- Height = 24
+ Height = 20
Top = 87
Width = 128
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'Unknown'
'Meter'
@@ -204,10 +204,10 @@ object HdrForm: THdrForm
end
object xyzt_timeDrop: TComboBox
Left = 262
- Height = 24
+ Height = 20
Top = 157
Width = 128
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'Unknown'
'Second'
@@ -222,7 +222,7 @@ object HdrForm: THdrForm
end
object Xdim: TSpinEdit
Left = 80
- Height = 24
+ Height = 16
Top = 59
Width = 74
MaxValue = 9999
@@ -233,7 +233,7 @@ object HdrForm: THdrForm
end
object Ydim: TSpinEdit
Left = 80
- Height = 24
+ Height = 16
Top = 89
Width = 74
MaxValue = 9999
@@ -245,7 +245,7 @@ object HdrForm: THdrForm
end
object Zdim: TSpinEdit
Left = 80
- Height = 24
+ Height = 16
Top = 123
Width = 74
MaxValue = 9999
@@ -257,7 +257,7 @@ object HdrForm: THdrForm
end
object Xmm: TFloatSpinEdit
Left = 164
- Height = 24
+ Height = 16
Top = 59
Width = 74
Increment = 1
@@ -268,7 +268,7 @@ object HdrForm: THdrForm
end
object Ymm: TFloatSpinEdit
Left = 164
- Height = 24
+ Height = 16
Top = 89
Width = 74
Increment = 1
@@ -279,7 +279,7 @@ object HdrForm: THdrForm
end
object Zmm: TFloatSpinEdit
Left = 164
- Height = 24
+ Height = 16
Top = 123
Width = 74
Increment = 1
@@ -290,7 +290,7 @@ object HdrForm: THdrForm
end
object OffsetEdit: TSpinEdit
Left = 342
- Height = 24
+ Height = 16
Top = 230
Width = 94
MaxValue = 999999
@@ -300,7 +300,7 @@ object HdrForm: THdrForm
end
object TDim: TSpinEdit
Left = 80
- Height = 24
+ Height = 16
Top = 157
Width = 74
MaxValue = 9999
@@ -312,7 +312,7 @@ object HdrForm: THdrForm
end
object TSec: TFloatSpinEdit
Left = 164
- Height = 24
+ Height = 16
Top = 157
Width = 74
DecimalPlaces = 4
@@ -324,7 +324,7 @@ object HdrForm: THdrForm
end
object Dim5Edit: TSpinEdit
Left = 80
- Height = 24
+ Height = 16
Top = 191
Width = 74
MaxValue = 35000
@@ -336,7 +336,7 @@ object HdrForm: THdrForm
end
object Dim6Edit: TSpinEdit
Left = 80
- Height = 24
+ Height = 16
Top = 223
Width = 74
MaxValue = 35000
@@ -348,7 +348,7 @@ object HdrForm: THdrForm
end
object Dim7Edit: TSpinEdit
Left = 80
- Height = 24
+ Height = 16
Top = 258
Width = 74
MaxValue = 35000
@@ -360,7 +360,7 @@ object HdrForm: THdrForm
end
object PixDim5: TFloatSpinEdit
Left = 164
- Height = 24
+ Height = 16
Top = 191
Width = 74
DecimalPlaces = 4
@@ -372,7 +372,7 @@ object HdrForm: THdrForm
end
object PixDim6: TFloatSpinEdit
Left = 164
- Height = 24
+ Height = 16
Top = 223
Width = 74
DecimalPlaces = 4
@@ -384,7 +384,7 @@ object HdrForm: THdrForm
end
object PixDim7: TFloatSpinEdit
Left = 164
- Height = 24
+ Height = 16
Top = 258
Width = 74
DecimalPlaces = 4
@@ -465,10 +465,10 @@ object HdrForm: THdrForm
end
object QFormDrop: TComboBox
Left = 150
- Height = 24
+ Height = 20
Top = 5
Width = 260
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'None'
'Scanner Position'
@@ -483,10 +483,10 @@ object HdrForm: THdrForm
end
object SFormDrop: TComboBox
Left = 145
- Height = 24
+ Height = 20
Top = 150
Width = 204
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'None'
'Scanner Position'
@@ -501,8 +501,8 @@ object HdrForm: THdrForm
end
object srow_x0Edit: TFloatSpinEdit
Left = 34
- Height = 24
- Top = 184
+ Height = 16
+ Top = 188
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -513,8 +513,8 @@ object HdrForm: THdrForm
end
object srow_x1Edit: TFloatSpinEdit
Left = 142
- Height = 24
- Top = 184
+ Height = 16
+ Top = 188
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -525,8 +525,8 @@ object HdrForm: THdrForm
end
object srow_x2Edit: TFloatSpinEdit
Left = 254
- Height = 24
- Top = 184
+ Height = 16
+ Top = 188
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -537,8 +537,8 @@ object HdrForm: THdrForm
end
object srow_y0Edit: TFloatSpinEdit
Left = 34
- Height = 24
- Top = 218
+ Height = 16
+ Top = 222
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -549,8 +549,8 @@ object HdrForm: THdrForm
end
object srow_y1Edit: TFloatSpinEdit
Left = 142
- Height = 24
- Top = 218
+ Height = 16
+ Top = 222
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -561,8 +561,8 @@ object HdrForm: THdrForm
end
object srow_y2Edit: TFloatSpinEdit
Left = 254
- Height = 24
- Top = 218
+ Height = 16
+ Top = 222
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -573,8 +573,8 @@ object HdrForm: THdrForm
end
object srow_z0Edit: TFloatSpinEdit
Left = 34
- Height = 24
- Top = 251
+ Height = 16
+ Top = 255
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -585,8 +585,8 @@ object HdrForm: THdrForm
end
object srow_z1Edit: TFloatSpinEdit
Left = 142
- Height = 24
- Top = 251
+ Height = 16
+ Top = 255
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -597,8 +597,8 @@ object HdrForm: THdrForm
end
object srow_z2Edit: TFloatSpinEdit
Left = 254
- Height = 24
- Top = 251
+ Height = 16
+ Top = 255
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -609,8 +609,8 @@ object HdrForm: THdrForm
end
object srow_x3Edit: TFloatSpinEdit
Left = 366
- Height = 24
- Top = 184
+ Height = 16
+ Top = 188
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -621,8 +621,8 @@ object HdrForm: THdrForm
end
object srow_y3Edit: TFloatSpinEdit
Left = 366
- Height = 24
- Top = 218
+ Height = 16
+ Top = 222
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -633,8 +633,8 @@ object HdrForm: THdrForm
end
object srow_z3Edit: TFloatSpinEdit
Left = 366
- Height = 24
- Top = 251
+ Height = 16
+ Top = 255
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -645,8 +645,8 @@ object HdrForm: THdrForm
end
object quatern_bEdit: TFloatSpinEdit
Left = 94
- Height = 24
- Top = 80
+ Height = 16
+ Top = 84
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -657,8 +657,8 @@ object HdrForm: THdrForm
end
object quatern_cEdit: TFloatSpinEdit
Left = 212
- Height = 24
- Top = 80
+ Height = 16
+ Top = 84
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -669,8 +669,8 @@ object HdrForm: THdrForm
end
object quatern_dEdit: TFloatSpinEdit
Left = 332
- Height = 24
- Top = 80
+ Height = 16
+ Top = 84
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -681,8 +681,8 @@ object HdrForm: THdrForm
end
object qoffset_xEdit: TFloatSpinEdit
Left = 94
- Height = 24
- Top = 113
+ Height = 16
+ Top = 117
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -693,8 +693,8 @@ object HdrForm: THdrForm
end
object qoffset_yEdit: TFloatSpinEdit
Left = 212
- Height = 24
- Top = 113
+ Height = 16
+ Top = 117
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -705,8 +705,8 @@ object HdrForm: THdrForm
end
object qoffset_zEdit: TFloatSpinEdit
Left = 332
- Height = 24
- Top = 113
+ Height = 16
+ Top = 117
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -717,8 +717,8 @@ object HdrForm: THdrForm
end
object QFacEdit: TFloatSpinEdit
Left = 140
- Height = 24
- Top = 42
+ Height = 16
+ Top = 46
Width = 100
DecimalPlaces = 5
Increment = 1
@@ -782,8 +782,8 @@ object HdrForm: THdrForm
end
object cmax: TFloatSpinEdit
Left = 94
- Height = 24
- Top = 161
+ Height = 16
+ Top = 165
Width = 110
DecimalPlaces = 5
Increment = 1
@@ -794,8 +794,8 @@ object HdrForm: THdrForm
end
object cmin: TFloatSpinEdit
Left = 94
- Height = 24
- Top = 125
+ Height = 16
+ Top = 129
Width = 110
DecimalPlaces = 5
Increment = 1
@@ -806,8 +806,8 @@ object HdrForm: THdrForm
end
object Scale: TFloatSpinEdit
Left = 94
- Height = 24
- Top = 24
+ Height = 16
+ Top = 28
Width = 110
DecimalPlaces = 5
Increment = 1
@@ -818,8 +818,8 @@ object HdrForm: THdrForm
end
object Intercept: TFloatSpinEdit
Left = 94
- Height = 24
- Top = 60
+ Height = 16
+ Top = 64
Width = 110
DecimalPlaces = 5
Increment = 1
@@ -867,11 +867,11 @@ object HdrForm: THdrForm
end
object IntentCodeDrop: TComboBox
Left = 76
- Height = 24
+ Height = 20
Top = 8
Width = 218
DropDownCount = 44
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'Not statistics'
'Correlation coefficient '
@@ -913,8 +913,8 @@ object HdrForm: THdrForm
end
object intent_p1Edit: TFloatSpinEdit
Left = 110
- Height = 24
- Top = 42
+ Height = 16
+ Top = 46
Width = 138
DecimalPlaces = 5
Increment = 1
@@ -925,8 +925,8 @@ object HdrForm: THdrForm
end
object intent_p2Edit: TFloatSpinEdit
Left = 110
- Height = 24
- Top = 79
+ Height = 16
+ Top = 83
Width = 138
DecimalPlaces = 5
Increment = 1
@@ -937,8 +937,8 @@ object HdrForm: THdrForm
end
object intent_p3Edit: TFloatSpinEdit
Left = 110
- Height = 24
- Top = 115
+ Height = 16
+ Top = 119
Width = 138
DecimalPlaces = 5
Increment = 1
@@ -1018,10 +1018,10 @@ object HdrForm: THdrForm
end
object SliceCodeDrop: TComboBox
Left = 87
- Height = 24
+ Height = 20
Top = 137
Width = 159
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'Unknown'
'Sequential Increasing'
@@ -1035,10 +1035,10 @@ object HdrForm: THdrForm
end
object FreqDimDrop: TComboBox
Left = 146
- Height = 24
+ Height = 20
Top = 174
Width = 100
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'Unknown'
'I'
@@ -1051,10 +1051,10 @@ object HdrForm: THdrForm
end
object PhaseDimDrop: TComboBox
Left = 146
- Height = 24
+ Height = 20
Top = 210
Width = 100
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'Unknown'
'I'
@@ -1067,10 +1067,10 @@ object HdrForm: THdrForm
end
object SliceDimDrop: TComboBox
Left = 146
- Height = 24
+ Height = 20
Top = 246
Width = 100
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'Unknown'
'I'
@@ -1083,16 +1083,16 @@ object HdrForm: THdrForm
end
object slice_startEdit: TSpinEdit
Left = 120
- Height = 22
- Top = 70
+ Height = 16
+ Top = 73
Width = 112
TabOrder = 2
Value = 1
end
object Slice_durationEdit: TFloatSpinEdit
Left = 120
- Height = 22
- Top = 35
+ Height = 16
+ Top = 38
Width = 112
DecimalPlaces = 5
Increment = 1
@@ -1103,8 +1103,8 @@ object HdrForm: THdrForm
end
object toffsetEdit: TFloatSpinEdit
Left = 120
- Height = 22
- Top = 4
+ Height = 16
+ Top = 7
Width = 112
DecimalPlaces = 5
Increment = 1
@@ -1115,8 +1115,8 @@ object HdrForm: THdrForm
end
object slice_endEdit: TSpinEdit
Left = 120
- Height = 22
- Top = 101
+ Height = 16
+ Top = 104
Width = 112
TabOrder = 3
Value = 1
@@ -1253,40 +1253,40 @@ object HdrForm: THdrForm
end
object gmax: TSpinEdit
Left = 366
- Height = 22
- Top = 41
+ Height = 16
+ Top = 44
Width = 66
TabOrder = 6
Value = 1
end
object gmin: TSpinEdit
Left = 366
- Height = 22
- Top = 6
+ Height = 16
+ Top = 9
Width = 66
TabOrder = 5
Value = 1
end
object ses: TSpinEdit
Left = 366
- Height = 22
- Top = 74
+ Height = 16
+ Top = 77
Width = 66
TabOrder = 7
Value = 1
end
object ext: TSpinEdit
Left = 366
- Height = 22
- Top = 114
+ Height = 16
+ Top = 117
Width = 66
TabOrder = 8
Value = 1
end
object reg: TSpinEdit
Left = 366
- Height = 22
- Top = 148
+ Height = 16
+ Top = 151
Width = 66
MaxValue = 255
TabOrder = 9
@@ -1296,8 +1296,8 @@ object HdrForm: THdrForm
end
object StatusBar1: TStatusBar
Left = 0
- Height = 20
- Top = 379
+ Height = 15
+ Top = 403
Width = 542
Panels = <
item
diff --git a/nifti_hdr_view.lrs b/nifti_hdr_view.lrs
old mode 100644
new mode 100755
index 9286a99..b8d0ae3
--- a/nifti_hdr_view.lrs
+++ b/nifti_hdr_view.lrs
@@ -3,358 +3,358 @@
LazarusResources.Add('THdrForm','FORMDATA',[
'TPF0'#8'THdrForm'#7'HdrForm'#4'Left'#3#220#1#6'Height'#3#162#1#3'Top'#3'|'#1
+#5'Width'#3#30#2#13'ActiveControl'#7#12'PageControl1'#11'BorderIcons'#11#12
- +'biSystemMenu'#0#11'BorderStyle'#7#8'bsDialog'#7'Caption'#6#24'NIfTI Header '
- +'Information'#12'ClientHeight'#3#143#1#11'ClientWidth'#3#30#2#21'Constraints'
+ +'biSystemMenu'#0#11'BorderStyle'#7#8'bsSingle'#7'Caption'#6#24'NIfTI Header '
+ +'Information'#12'ClientHeight'#3#162#1#11'ClientWidth'#3#30#2#21'Constraints'
+'.MaxHeight'#3#162#1#20'Constraints.MaxWidth'#3#30#2#21'Constraints.MinHeigh'
+'t'#3#162#1#20'Constraints.MinWidth'#3#30#2#9'Font.Name'#6#13'MS Sans Serif'
+#4'Menu'#7#9'MainMenu1'#8'OnCreate'#7#10'FormCreate'#6'OnShow'#7#8'FormShow'
- +#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#6'0.9.30'#0#12'TPageContr'
- +'ol'#12'PageControl1'#4'Left'#2#4#6'Height'#3's'#1#3'Top'#2#4#5'Width'#3#22#2
- +#10'ActivePage'#7#11'TabRequired'#5'Align'#7#8'alClient'#18'BorderSpacing.Le'
- +'ft'#2#2#17'BorderSpacing.Top'#2#2#19'BorderSpacing.Right'#2#2#20'BorderSpac'
- +'ing.Bottom'#2#2#20'BorderSpacing.Around'#2#2#8'TabIndex'#2#0#8'TabOrder'#2#0
- +#0#9'TTabSheet'#11'TabRequired'#7'Caption'#6#10'Dimensions'#12'ClientHeight'
- +#3'V'#1#11'ClientWidth'#3#14#2#0#6'TLabel'#7'Label21'#4'Left'#2#6#6'Height'#2
- +#17#3'Top'#2#6#5'Width'#2'R'#7'Caption'#6#11'Header Type'#11'ParentColor'#8#0
- +#0#6'TLabel'#6'Label1'#4'Left'#2#14#6'Height'#2#17#3'Top'#2'#'#5'Width'#3#238
- +#0#7'Caption'#6'.Dimension Length Spacing Unit'#9'Font.Name'
- +#6#13'MS Sans Serif'#11'ParentColor'#8#10'ParentFont'#8#0#0#6'TLabel'#6'Labe'
- +'l2'#4'Left'#2#16#6'Height'#2#17#3'Top'#2'C'#5'Width'#2'/'#7'Caption'#6#7'I '
- +'Space'#11'ParentColor'#8#0#0#6'TLabel'#6'Label3'#4'Left'#2#16#6'Height'#2#17
- +#3'Top'#2'a'#5'Width'#2'3'#7'Caption'#6#7'J Space'#11'ParentColor'#8#0#0#6'T'
- +'Label'#6'Label4'#4'Left'#2#16#6'Height'#2#17#3'Top'#3#131#0#5'Width'#2'4'#7
- +'Caption'#6#7'K Space'#11'ParentColor'#8#0#0#6'TLabel'#6'Label8'#4'Left'#2#6
- +#6'Height'#2#17#3'Top'#3')'#1#5'Width'#2#30#7'Caption'#6#4'Data'#11'ParentCo'
- +'lor'#8#0#0#6'TLabel'#6'Label7'#4'Left'#3'&'#1#6'Height'#2#17#3'Top'#3#235#0
- +#5'Width'#2'#'#7'Caption'#6#6'Offset'#11'ParentColor'#8#0#0#6'TLabel'#7'Labe'
- +'l44'#4'Left'#2#16#6'Height'#2#17#3'Top'#3#166#0#5'Width'#2' '#7'Caption'#6#4
- +'Time'#11'ParentColor'#8#0#0#6'TLabel'#7'Label29'#4'Left'#2#16#6'Height'#2#17
- +#3'Top'#3#198#0#5'Width'#2'-'#7'Caption'#6#7'5th Dim'#11'ParentColor'#8#0#0#6
- +'TLabel'#7'Label41'#4'Left'#2#16#6'Height'#2#17#3'Top'#3#230#0#5'Width'#2'-'
- +#7'Caption'#6#7'6th Dim'#11'ParentColor'#8#0#0#6'TLabel'#7'Label42'#4'Left'#2
- +#16#6'Height'#2#17#3'Top'#3#9#1#5'Width'#2'-'#7'Caption'#6#7'7th Dim'#11'Par'
- +'entColor'#8#0#0#9'TComboBox'#15'HeaderMagicDrop'#4'Left'#2'l'#6'Height'#2#24
- +#3'Top'#2#2#5'Width'#3#239#0#10'ItemHeight'#2#16#13'Items.Strings'#1#6#7'Unk'
- +'nown'#6'#ni1: NIfTI separate file (hdr+.img)'#6#28'n+1: NIfTI embedded (.'
- +'nii)'#6'$ni2: NIfTI2 separate file (hdr+.img)'#6#29'n+2: NIfTI2 embedded '
- +'(.nii)'#0#8'OnSelect'#7#21'HeaderMagicDropSelect'#5'Style'#7#14'csDropDownL'
- +'ist'#8'TabOrder'#2#15#0#0#9'TComboBox'#6'Endian'#4'Left'#3#231#0#6'Height'#2
- +#24#3'Top'#3'#'#1#5'Width'#3#210#0#10'ItemHeight'#2#16#13'Items.Strings'#1#6
- +#13'Native Endian'#6#14'Swapped Endian'#0#5'Style'#7#14'csDropDownList'#8'Ta'
- +'bOrder'#2#16#0#0#9'TComboBox'#9'fTypeDrop'#4'Left'#2'8'#6'Height'#2#24#3'To'
- +'p'#3'#'#1#5'Width'#3#152#0#13'DropDownCount'#2#20#10'ItemHeight'#2#16#13'It'
- +'ems.Strings'#1#6#6'binary'#6#7'8-bit S'#6#12'8-bit int U*'#6#13'16-bit int '
- +'S*'#6#12'16-bit int U'#6#13'32-bit int S*'#6#12'32-bit int U'#6#12'64-bit i'
- +'nt S'#6#12'64-bit int U'#6#12'32-bit real*'#6#12'64-bit real*'#6#12'128-bit'
- +' real'#6#10'24-bit rgb'#6#10'64-bit com'#6#15'128-bit complex'#6#15'256-bit'
- +' complex'#0#8'OnSelect'#7#13'ImageSzChange'#5'Style'#7#14'csDropDownList'#8
- +'TabOrder'#2#17#0#0#9'TComboBox'#13'xyzt_sizeDrop'#4'Left'#3#6#1#6'Height'#2
- +#24#3'Top'#2'W'#5'Width'#3#128#0#10'ItemHeight'#2#16#13'Items.Strings'#1#6#7
- +'Unknown'#6#5'Meter'#6#10'Millimeter'#6#10'Micrometer'#6#6'Micron'#0#5'Style'
- +#7#14'csDropDownList'#8'TabOrder'#2#18#0#0#9'TComboBox'#13'xyzt_timeDrop'#4
- +'Left'#3#6#1#6'Height'#2#24#3'Top'#3#157#0#5'Width'#3#128#0#10'ItemHeight'#2
- +#16#13'Items.Strings'#1#6#7'Unknown'#6#6'Second'#6#11'Millisecond'#6#11'Micr'
- +'osecond'#6#11'Hertzsecond'#6#5'Part '#6#16'Part per million'#0#5'Style'#7#14
- +'csDropDownList'#8'TabOrder'#2#19#0#0#9'TSpinEdit'#4'Xdim'#4'Left'#2'P'#6'He'
- +'ight'#2#24#3'Top'#2';'#5'Width'#2'J'#8'MaxValue'#3#15''''#8'MinValue'#2#1#6
- +'OnExit'#7#13'ImageSzChange'#8'TabOrder'#2#0#5'Value'#2#2#0#0#9'TSpinEdit'#4
- +'Ydim'#4'Left'#2'P'#6'Height'#2#24#3'Top'#2'Y'#5'Width'#2'J'#8'MaxValue'#3#15
- +''''#8'MinValue'#2#1#8'OnChange'#7#13'ImageSzChange'#6'OnExit'#7#13'ImageSzC'
- +'hange'#8'TabOrder'#2#1#5'Value'#2#2#0#0#9'TSpinEdit'#4'Zdim'#4'Left'#2'P'#6
- +'Height'#2#24#3'Top'#2'{'#5'Width'#2'J'#8'MaxValue'#3#15''''#8'MinValue'#2#1
- +#8'OnChange'#7#13'ImageSzChange'#6'OnExit'#7#13'ImageSzChange'#8'TabOrder'#2
- +#2#5'Value'#2#1#0#0#14'TFloatSpinEdit'#3'Xmm'#4'Left'#3#164#0#6'Height'#2#24
- +#3'Top'#2';'#5'Width'#2'J'#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValu'
- ,'e'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25
- +#192#8'TabOrder'#2#10#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#14'TFloatSpinEdit'#3
- +'Ymm'#4'Left'#3#164#0#6'Height'#2#24#3'Top'#2'Y'#5'Width'#2'J'#9'Increment'#5
- +#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinVa'
- +'lue'#5#0#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#11#5'Value'#5#0#0#0#0#0#0
- +#0#0#0#0#0#0#14'TFloatSpinEdit'#3'Zmm'#4'Left'#3#164#0#6'Height'#2#24#3'Top'
- +#2'{'#5'Width'#2'J'#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0
- +#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25#192#8'TabO'
- +'rder'#2#12#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#9'TSpinEdit'#10'OffsetEdit'#4
- +'Left'#3'V'#1#6'Height'#2#24#3'Top'#3#230#0#5'Width'#2'^'#8'MaxValue'#4'?B'
- +#15#0#6'OnExit'#7#13'ImageSzChange'#8'TabOrder'#2#14#5'Value'#2#1#0#0#9'TSpi'
- +'nEdit'#4'TDim'#4'Left'#2'P'#6'Height'#2#24#3'Top'#3#157#0#5'Width'#2'J'#8'M'
- +'axValue'#3#15''''#8'MinValue'#2#1#8'OnChange'#7#13'ImageSzChange'#6'OnExit'
- +#7#13'ImageSzChange'#8'TabOrder'#2#3#5'Value'#2#1#0#0#14'TFloatSpinEdit'#4'T'
- +'Sec'#4'Left'#3#164#0#6'Height'#2#24#3'Top'#3#157#0#5'Width'#2'J'#13'Decimal'
- +'Places'#2#4#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0
- +#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25#192#8'TabOrder'
- +#2#13#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#9'TSpinEdit'#8'Dim5Edit'#4'Left'#2
- +'P'#6'Height'#2#24#3'Top'#3#191#0#5'Width'#2'J'#8'MaxValue'#4#184#136#0#0#8
+ +#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#8'0.9.30.2'#0#12'TPageCon'
+ +'trol'#12'PageControl1'#4'Left'#2#4#6'Height'#3#139#1#3'Top'#2#4#5'Width'#3
+ +#22#2#10'ActivePage'#7#11'TabRequired'#5'Align'#7#8'alClient'#18'BorderSpaci'
+ +'ng.Left'#2#2#17'BorderSpacing.Top'#2#2#19'BorderSpacing.Right'#2#2#20'Borde'
+ +'rSpacing.Bottom'#2#2#20'BorderSpacing.Around'#2#2#8'TabIndex'#2#0#8'TabOrde'
+ +'r'#2#0#0#9'TTabSheet'#11'TabRequired'#7'Caption'#6#10'Dimensions'#12'Client'
+ +'Height'#3'd'#1#11'ClientWidth'#3#16#2#0#6'TLabel'#7'Label21'#4'Left'#2#6#6
+ +'Height'#2#18#3'Top'#2#6#5'Width'#2'P'#7'Caption'#6#11'Header Type'#11'Paren'
+ +'tColor'#8#0#0#6'TLabel'#6'Label1'#4'Left'#2#14#6'Height'#2#18#3'Top'#2'#'#5
+ +'Width'#3#13#1#7'Caption'#6'.Dimension Length Spacing Unit'
+ +#9'Font.Name'#6#13'MS Sans Serif'#11'ParentColor'#8#10'ParentFont'#8#0#0#6'T'
+ +'Label'#6'Label2'#4'Left'#2#16#6'Height'#2#18#3'Top'#2'C'#5'Width'#2'.'#7'Ca'
+ +'ption'#6#7'I Space'#11'ParentColor'#8#0#0#6'TLabel'#6'Label3'#4'Left'#2#16#6
+ +'Height'#2#18#3'Top'#2'a'#5'Width'#2'1'#7'Caption'#6#7'J Space'#11'ParentCol'
+ +'or'#8#0#0#6'TLabel'#6'Label4'#4'Left'#2#16#6'Height'#2#18#3'Top'#3#131#0#5
+ +'Width'#2'3'#7'Caption'#6#7'K Space'#11'ParentColor'#8#0#0#6'TLabel'#6'Label'
+ +'8'#4'Left'#2#6#6'Height'#2#18#3'Top'#3')'#1#5'Width'#2#30#7'Caption'#6#4'Da'
+ +'ta'#11'ParentColor'#8#0#0#6'TLabel'#6'Label7'#4'Left'#3'&'#1#6'Height'#2#18
+ +#3'Top'#3#235#0#5'Width'#2')'#7'Caption'#6#6'Offset'#11'ParentColor'#8#0#0#6
+ +'TLabel'#7'Label44'#4'Left'#2#16#6'Height'#2#18#3'Top'#3#166#0#5'Width'#2#31
+ +#7'Caption'#6#4'Time'#11'ParentColor'#8#0#0#6'TLabel'#7'Label29'#4'Left'#2#16
+ +#6'Height'#2#18#3'Top'#3#198#0#5'Width'#2'3'#7'Caption'#6#7'5th Dim'#11'Pare'
+ +'ntColor'#8#0#0#6'TLabel'#7'Label41'#4'Left'#2#16#6'Height'#2#18#3'Top'#3#230
+ +#0#5'Width'#2'3'#7'Caption'#6#7'6th Dim'#11'ParentColor'#8#0#0#6'TLabel'#7'L'
+ +'abel42'#4'Left'#2#16#6'Height'#2#18#3'Top'#3#9#1#5'Width'#2'3'#7'Caption'#6
+ +#7'7th Dim'#11'ParentColor'#8#0#0#9'TComboBox'#15'HeaderMagicDrop'#4'Left'#2
+ +'l'#6'Height'#2#20#3'Top'#2#2#5'Width'#3#239#0#10'ItemHeight'#2#0#13'Items.S'
+ +'trings'#1#6#7'Unknown'#6'#ni1: NIfTI separate file (hdr+.img)'#6#28'n+1: NI'
+ +'fTI embedded (.nii)'#6'$ni2: NIfTI2 separate file (hdr+.img)'#6#29'n+2: N'
+ +'IfTI2 embedded (.nii)'#0#8'OnSelect'#7#21'HeaderMagicDropSelect'#5'Style'
+ +#7#14'csDropDownList'#8'TabOrder'#2#15#0#0#9'TComboBox'#6'Endian'#4'Left'#3
+ +#231#0#6'Height'#2#20#3'Top'#3'#'#1#5'Width'#3#210#0#10'ItemHeight'#2#0#13'I'
+ +'tems.Strings'#1#6#13'Native Endian'#6#14'Swapped Endian'#0#5'Style'#7#14'cs'
+ +'DropDownList'#8'TabOrder'#2#16#0#0#9'TComboBox'#9'fTypeDrop'#4'Left'#2'8'#6
+ +'Height'#2#20#3'Top'#3'#'#1#5'Width'#3#152#0#13'DropDownCount'#2#20#10'ItemH'
+ +'eight'#2#0#13'Items.Strings'#1#6#6'binary'#6#7'8-bit S'#6#12'8-bit int U*'#6
+ +#13'16-bit int S*'#6#12'16-bit int U'#6#13'32-bit int S*'#6#12'32-bit int U'
+ +#6#12'64-bit int S'#6#12'64-bit int U'#6#12'32-bit real*'#6#12'64-bit real*'
+ +#6#12'128-bit real'#6#10'24-bit rgb'#6#10'64-bit com'#6#15'128-bit complex'#6
+ +#15'256-bit complex'#0#8'OnSelect'#7#13'ImageSzChange'#5'Style'#7#14'csDropD'
+ +'ownList'#8'TabOrder'#2#17#0#0#9'TComboBox'#13'xyzt_sizeDrop'#4'Left'#3#6#1#6
+ +'Height'#2#20#3'Top'#2'W'#5'Width'#3#128#0#10'ItemHeight'#2#0#13'Items.Strin'
+ +'gs'#1#6#7'Unknown'#6#5'Meter'#6#10'Millimeter'#6#10'Micrometer'#6#6'Micron'
+ +#0#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#18#0#0#9'TComboBox'#13'xyzt_t'
+ +'imeDrop'#4'Left'#3#6#1#6'Height'#2#20#3'Top'#3#157#0#5'Width'#3#128#0#10'It'
+ +'emHeight'#2#0#13'Items.Strings'#1#6#7'Unknown'#6#6'Second'#6#11'Millisecond'
+ +#6#11'Microsecond'#6#11'Hertzsecond'#6#5'Part '#6#16'Part per million'#0#5'S'
+ +'tyle'#7#14'csDropDownList'#8'TabOrder'#2#19#0#0#9'TSpinEdit'#4'Xdim'#4'Left'
+ +#2'P'#6'Height'#2#16#3'Top'#2';'#5'Width'#2'J'#8'MaxValue'#3#15''''#8'MinVal'
+ +'ue'#2#1#6'OnExit'#7#13'ImageSzChange'#8'TabOrder'#2#0#5'Value'#2#2#0#0#9'TS'
+ +'pinEdit'#4'Ydim'#4'Left'#2'P'#6'Height'#2#16#3'Top'#2'Y'#5'Width'#2'J'#8'Ma'
+ +'xValue'#3#15''''#8'MinValue'#2#1#8'OnChange'#7#13'ImageSzChange'#6'OnExit'#7
+ +#13'ImageSzChange'#8'TabOrder'#2#1#5'Value'#2#2#0#0#9'TSpinEdit'#4'Zdim'#4'L'
+ +'eft'#2'P'#6'Height'#2#16#3'Top'#2'{'#5'Width'#2'J'#8'MaxValue'#3#15''''#8'M'
+ +'inValue'#2#1#8'OnChange'#7#13'ImageSzChange'#6'OnExit'#7#13'ImageSzChange'#8
+ +'TabOrder'#2#2#5'Value'#2#1#0#0#14'TFloatSpinEdit'#3'Xmm'#4'Left'#3#164#0#6
+ +'Height'#2#16#3'Top'#2';'#5'Width'#2'J'#9'Increment'#5#0#0#0#0#0#0#0#128#255
+ ,'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31
+ +#188#190#25#192#8'TabOrder'#2#10#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#14'TFloa'
+ +'tSpinEdit'#3'Ymm'#4'Left'#3#164#0#6'Height'#2#16#3'Top'#2'Y'#5'Width'#2'J'#9
+ +'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190
+ +#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#11#5'Value'
+ +#5#0#0#0#0#0#0#0#0#0#0#0#0#14'TFloatSpinEdit'#3'Zmm'#4'Left'#3#164#0#6'Heigh'
+ +'t'#2#16#3'Top'#2'{'#5'Width'#2'J'#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8
+ +'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188
+ +#190#25#192#8'TabOrder'#2#12#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#9'TSpinEdit'
+ +#10'OffsetEdit'#4'Left'#3'V'#1#6'Height'#2#16#3'Top'#3#230#0#5'Width'#2'^'#8
+ +'MaxValue'#4'?B'#15#0#6'OnExit'#7#13'ImageSzChange'#8'TabOrder'#2#14#5'Value'
+ +#2#1#0#0#9'TSpinEdit'#4'TDim'#4'Left'#2'P'#6'Height'#2#16#3'Top'#3#157#0#5'W'
+ +'idth'#2'J'#8'MaxValue'#3#15''''#8'MinValue'#2#1#8'OnChange'#7#13'ImageSzCha'
+ +'nge'#6'OnExit'#7#13'ImageSzChange'#8'TabOrder'#2#3#5'Value'#2#1#0#0#14'TFlo'
+ +'atSpinEdit'#4'TSec'#4'Left'#3#164#0#6'Height'#2#16#3'Top'#3#157#0#5'Width'#2
+ +'J'#13'DecimalPlaces'#2#4#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'
+ +#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25#192#8
+ +'TabOrder'#2#13#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#9'TSpinEdit'#8'Dim5Edit'#4
+ +'Left'#2'P'#6'Height'#2#16#3'Top'#3#191#0#5'Width'#2'J'#8'MaxValue'#4#184#136
+ +#0#0#8'MinValue'#2#1#8'OnChange'#7#13'ImageSzChange'#6'OnExit'#7#13'ImageSzC'
+ +'hange'#8'TabOrder'#2#4#5'Value'#2#1#0#0#9'TSpinEdit'#8'Dim6Edit'#4'Left'#2
+ +'P'#6'Height'#2#16#3'Top'#3#223#0#5'Width'#2'J'#8'MaxValue'#4#184#136#0#0#8
+'MinValue'#2#1#8'OnChange'#7#13'ImageSzChange'#6'OnExit'#7#13'ImageSzChange'
- +#8'TabOrder'#2#4#5'Value'#2#1#0#0#9'TSpinEdit'#8'Dim6Edit'#4'Left'#2'P'#6'He'
- +'ight'#2#24#3'Top'#3#223#0#5'Width'#2'J'#8'MaxValue'#4#184#136#0#0#8'MinValu'
- +'e'#2#1#8'OnChange'#7#13'ImageSzChange'#6'OnExit'#7#13'ImageSzChange'#8'TabO'
- +'rder'#2#5#5'Value'#2#1#0#0#9'TSpinEdit'#8'Dim7Edit'#4'Left'#2'P'#6'Height'#2
- +#24#3'Top'#3#2#1#5'Width'#2'J'#8'MaxValue'#4#184#136#0#0#8'MinValue'#2#1#8'O'
- +'nChange'#7#13'ImageSzChange'#6'OnExit'#7#13'ImageSzChange'#8'TabOrder'#2#9#5
- +'Value'#2#1#0#0#14'TFloatSpinEdit'#7'PixDim5'#4'Left'#3#164#0#6'Height'#2#24
- +#3'Top'#3#191#0#5'Width'#2'J'#13'DecimalPlaces'#2#4#9'Increment'#5#0#0#0#0#0
- +#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0
- +#0#0#224#31#188#190#25#192#8'TabOrder'#2#6#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0
- +#14'TFloatSpinEdit'#7'PixDim6'#4'Left'#3#164#0#6'Height'#2#24#3'Top'#3#223#0
- +#5'Width'#2'J'#13'DecimalPlaces'#2#4#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'
- +#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188
- +#190#25#192#8'TabOrder'#2#7#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#14'TFloatSpin'
- +'Edit'#7'PixDim7'#4'Left'#3#164#0#6'Height'#2#24#3'Top'#3#2#1#5'Width'#2'J'
- +#13'DecimalPlaces'#2#4#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5
- +#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25#192#8
- +'TabOrder'#2#8#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#0#9'TTabSheet'#9'TabSheet4'
- +#7'Caption'#6#8'Reorient'#12'ClientHeight'#3'R'#1#11'ClientWidth'#3#14#2#0#6
- +'TLabel'#7'Label24'#4'Left'#2#10#6'Height'#2#17#3'Top'#3#184#0#5'Width'#2#9#7
- +'Caption'#6#1'X'#11'ParentColor'#8#0#0#6'TLabel'#7'Label36'#4'Left'#2#10#6'H'
- +'eight'#2#17#3'Top'#3#218#0#5'Width'#2#10#7'Caption'#6#1'Y'#11'ParentColor'#8
- +#0#0#6'TLabel'#7'Label37'#4'Left'#2#10#6'Height'#2#17#3'Top'#3#251#0#5'Width'
- +#2#9#7'Caption'#6#1'Z'#11'ParentColor'#8#0#0#6'TLabel'#7'Label39'#4'Left'#2
- +#10#6'Height'#2#17#3'Top'#2'{'#5'Width'#2'7'#7'Caption'#6#9'Q Offsets'#11'Pa'
- +'rentColor'#8#0#0#6'TLabel'#7'Label40'#4'Left'#2#10#6'Height'#2#17#3'Top'#2
- +'V'#5'Width'#2'I'#7'Caption'#6#11'Quaternions'#11'ParentColor'#8#0#0#6'TLabe'
- +'l'#7'Label46'#4'Left'#2#10#6'Height'#2#17#3'Top'#2'.'#5'Width'#2'^'#7'Capti'
- +'on'#6#17'qFactor [1 or -1]'#11'ParentColor'#8#0#0#6'TLabel'#7'Label38'#4'Le'
- +'ft'#2#4#6'Height'#2#17#3'Top'#2#9#5'Width'#3#141#0#7'Caption'#6#22'Quaterni'
- +'on parameters '#11'ParentColor'#8#0#0#6'TLabel'#7'Label47'#4'Left'#2#4#6'He'
- +'ight'#2#17#3'Top'#3#157#0#5'Width'#2'm'#7'Caption'#6#18'Affine parameters '
- +#11'ParentColor'#8#0#0#9'TComboBox'#9'QFormDrop'#4'Left'#3#150#0#6'Height'#2
- +#24#3'Top'#2#5#5'Width'#3#4#1#10'ItemHeight'#2#16#13'Items.Strings'#1#6#4'No'
- +'ne'#6#16'Scanner Position'#6#16'Coregistrationon'#6#14'Normalized Tal'#6#20
- +'Normalzied mni152ach'#6#17'Normalzied mni152'#0#8'OnSelect'#7#21'HeaderMagi'
- +'cDropSelect'#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#19#0#0#9'TComboBox'
- +#9'SFormDrop'#4'Left'#3#145#0#6'Height'#2#24#3'Top'#3#150#0#5'Width'#3#204#0
- +#10'ItemHeight'#2#16#13'Items.Strings'#1#6#4'None'#6#16'Scanner Position'#6
- +#16'Coregistrationon'#6#14'Normalized Tal'#6#20'Normalzied mni152ach'#6#17'N'
- +'ormalzied mni152'#0#8'OnSelect'#7#21'HeaderMagicDropSelect'#5'Style'#7#14'c'
- +'sDropDownList'#8'TabOrder'#2#20#0#0#14'TFloatSpinEdit'#11'srow_x0Edit'#4'Le'
- +'ft'#2'"'#6'Height'#2#24#3'Top'#3#184#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9
+ +#8'TabOrder'#2#5#5'Value'#2#1#0#0#9'TSpinEdit'#8'Dim7Edit'#4'Left'#2'P'#6'He'
+ +'ight'#2#16#3'Top'#3#2#1#5'Width'#2'J'#8'MaxValue'#4#184#136#0#0#8'MinValue'
+ +#2#1#8'OnChange'#7#13'ImageSzChange'#6'OnExit'#7#13'ImageSzChange'#8'TabOrde'
+ +'r'#2#9#5'Value'#2#1#0#0#14'TFloatSpinEdit'#7'PixDim5'#4'Left'#3#164#0#6'Hei'
+ +'ght'#2#16#3'Top'#3#191#0#5'Width'#2'J'#13'DecimalPlaces'#2#4#9'Increment'#5
+ +#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinVa'
+ +'lue'#5#0#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#6#5'Value'#5#0#0#0#0#0#0
+ +#0#0#0#0#0#0#14'TFloatSpinEdit'#7'PixDim6'#4'Left'#3#164#0#6'Height'#2#16#3
+ +'Top'#3#223#0#5'Width'#2'J'#13'DecimalPlaces'#2#4#9'Increment'#5#0#0#0#0#0#0
+ +#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0
+ +#0#224#31#188#190#25#192#8'TabOrder'#2#7#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0
+ +#14'TFloatSpinEdit'#7'PixDim7'#4'Left'#3#164#0#6'Height'#2#16#3'Top'#3#2#1#5
+ +'Width'#2'J'#13'DecimalPlaces'#2#4#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8
+ +'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188
+ +#190#25#192#8'TabOrder'#2#8#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#0#9'TTabSheet'
+ +#9'TabSheet4'#7'Caption'#6#8'Reorient'#12'ClientHeight'#3'R'#1#11'ClientWidt'
+ +'h'#3#14#2#0#6'TLabel'#7'Label24'#4'Left'#2#10#6'Height'#2#17#3'Top'#3#184#0
+ +#5'Width'#2#9#7'Caption'#6#1'X'#11'ParentColor'#8#0#0#6'TLabel'#7'Label36'#4
+ +'Left'#2#10#6'Height'#2#17#3'Top'#3#218#0#5'Width'#2#10#7'Caption'#6#1'Y'#11
+ +'ParentColor'#8#0#0#6'TLabel'#7'Label37'#4'Left'#2#10#6'Height'#2#17#3'Top'#3
+ +#251#0#5'Width'#2#9#7'Caption'#6#1'Z'#11'ParentColor'#8#0#0#6'TLabel'#7'Labe'
+ +'l39'#4'Left'#2#10#6'Height'#2#17#3'Top'#2'{'#5'Width'#2'7'#7'Caption'#6#9'Q'
+ +' Offsets'#11'ParentColor'#8#0#0#6'TLabel'#7'Label40'#4'Left'#2#10#6'Height'
+ +#2#17#3'Top'#2'V'#5'Width'#2'I'#7'Caption'#6#11'Quaternions'#11'ParentColor'
+ +#8#0#0#6'TLabel'#7'Label46'#4'Left'#2#10#6'Height'#2#17#3'Top'#2'.'#5'Width'
+ +#2'^'#7'Caption'#6#17'qFactor [1 or -1]'#11'ParentColor'#8#0#0#6'TLabel'#7'L'
+ +'abel38'#4'Left'#2#4#6'Height'#2#17#3'Top'#2#9#5'Width'#3#141#0#7'Caption'#6
+ +#22'Quaternion parameters '#11'ParentColor'#8#0#0#6'TLabel'#7'Label47'#4'Lef'
+ +'t'#2#4#6'Height'#2#17#3'Top'#3#157#0#5'Width'#2'm'#7'Caption'#6#18'Affine p'
+ +'arameters '#11'ParentColor'#8#0#0#9'TComboBox'#9'QFormDrop'#4'Left'#3#150#0
+ +#6'Height'#2#20#3'Top'#2#5#5'Width'#3#4#1#10'ItemHeight'#2#0#13'Items.String'
+ +'s'#1#6#4'None'#6#16'Scanner Position'#6#16'Coregistrationon'#6#14'Normalize'
+ +'d Tal'#6#20'Normalzied mni152ach'#6#17'Normalzied mni152'#0#8'OnSelect'#7#21
+ +'HeaderMagicDropSelect'#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#19#0#0#9
+ +'TComboBox'#9'SFormDrop'#4'Left'#3#145#0#6'Height'#2#20#3'Top'#3#150#0#5'Wid'
+ +'th'#3#204#0#10'ItemHeight'#2#0#13'Items.Strings'#1#6#4'None'#6#16'Scanner P'
+ +'osition'#6#16'Coregistrationon'#6#14'Normalized Tal'#6#20'Normalzied mni152'
+ +'ach'#6#17'Normalzied mni152'#0#8'OnSelect'#7#21'HeaderMagicDropSelect'#5'St'
+ +'yle'#7#14'csDropDownList'#8'TabOrder'#2#20#0#0#14'TFloatSpinEdit'#11'srow_x'
+ +'0Edit'#4'Left'#2'"'#6'Height'#2#16#3'Top'#3#188#0#5'Width'#2'd'#13'DecimalP'
+ +'laces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0
+ ,'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#7#5'Valu'
+ +'e'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'srow_x1Edit'#4'Left'
+ +#3#142#0#6'Height'#2#16#3'Top'#3#188#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9
+'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0'<'#156#12'@'
- ,#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#7#5'Value'#5#0#0#0#0#0
- +#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'srow_x1Edit'#4'Left'#3#142#0#6'Hei'
- +'ght'#2#24#3'Top'#3#184#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5
+ +#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#8#5'Value'#5#0#0#0#0#0
+ +#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'srow_x2Edit'#4'Left'#3#254#0#6'Hei'
+ +'ght'#2#16#3'Top'#3#188#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5
+#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0'<'#156#12'@'#8'MinValue'
- +#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#8#5'Value'#5#0#0#0#0#0#0#0#128#255
- +'?'#0#0#14'TFloatSpinEdit'#11'srow_x2Edit'#4'Left'#3#254#0#6'Height'#2#24#3
- +'Top'#3#184#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0
- +#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0
- +#0'<'#156#12#192#8'TabOrder'#2#9#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14
- +'TFloatSpinEdit'#11'srow_y0Edit'#4'Left'#2'"'#6'Height'#2#24#3'Top'#3#218#0#5
+ +#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#9#5'Value'#5#0#0#0#0#0#0#0#128#255
+ +'?'#0#0#14'TFloatSpinEdit'#11'srow_y0Edit'#4'Left'#2'"'#6'Height'#2#16#3'Top'
+ +#3#222#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128
+ +#255'?'#8'MaxValue'#5#0#0#0#0#0#0'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0#0'<'
+ +#156#12#192#8'TabOrder'#2#11#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFlo'
+ +'atSpinEdit'#11'srow_y1Edit'#4'Left'#3#142#0#6'Height'#2#16#3'Top'#3#222#0#5
+'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8
+'MaxValue'#5#0#0#0#0#0#0'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192
- +#8'TabOrder'#2#11#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'
- +#11'srow_y1Edit'#4'Left'#3#142#0#6'Height'#2#24#3'Top'#3#218#0#5'Width'#2'd'
+ +#8'TabOrder'#2#12#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'
+ +#11'srow_y2Edit'#4'Left'#3#254#0#6'Height'#2#16#3'Top'#3#222#0#5'Width'#2'd'
+#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5
+#0#0#0#0#0#0'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'
- +#2#12#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'srow_y2E'
- +'dit'#4'Left'#3#254#0#6'Height'#2#24#3'Top'#3#218#0#5'Width'#2'd'#13'Decimal'
- +'Places'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0
- +#0'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#13#5'V'
- +'alue'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'srow_z0Edit'#4'L'
- +'eft'#2'"'#6'Height'#2#24#3'Top'#3#251#0#5'Width'#2'd'#13'DecimalPlaces'#2#5
+ +#2#13#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'srow_z0E'
+ +'dit'#4'Left'#2'"'#6'Height'#2#16#3'Top'#3#255#0#5'Width'#2'd'#13'DecimalPla'
+ +'ces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0
+ +'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#15#5'Val'
+ +'ue'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'srow_z1Edit'#4'Lef'
+ +'t'#3#142#0#6'Height'#2#16#3'Top'#3#255#0#5'Width'#2'd'#13'DecimalPlaces'#2#5
+#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0'<'#156#12
- +'@'#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#15#5'Value'#5#0#0#0
- +#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'srow_z1Edit'#4'Left'#3#142#0#6
- +'Height'#2#24#3'Top'#3#251#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'
+ +'@'#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#16#5'Value'#5#0#0#0
+ +#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'srow_z2Edit'#4'Left'#3#254#0#6
+ +'Height'#2#16#3'Top'#3#255#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'
+#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0'<'#156#12'@'#8'MinValu'
- +'e'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#16#5'Value'#5#0#0#0#0#0#0#0#128
- +#255'?'#0#0#14'TFloatSpinEdit'#11'srow_z2Edit'#4'Left'#3#254#0#6'Height'#2#24
- +#3'Top'#3#251#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0
+ +'e'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'#2#17#5'Value'#5#0#0#0#0#0#0#0#128
+ +#255'?'#0#0#14'TFloatSpinEdit'#11'srow_x3Edit'#4'Left'#3'n'#1#6'Height'#2#16
+ +#3'Top'#3#188#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0
+#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0'<'#156#12'@'#8'MinValue'#5#0#0#0#0
- +#0#0'<'#156#12#192#8'TabOrder'#2#17#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0
- +#14'TFloatSpinEdit'#11'srow_x3Edit'#4'Left'#3'n'#1#6'Height'#2#24#3'Top'#3
- +#184#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128
+ +#0#0'<'#156#12#192#8'TabOrder'#2#10#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0
+ +#14'TFloatSpinEdit'#11'srow_y3Edit'#4'Left'#3'n'#1#6'Height'#2#16#3'Top'#3
+ +#222#0#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128
+#255'?'#8'MaxValue'#5#0#0#0#0#0#0'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0#0'<'
- +#156#12#192#8'TabOrder'#2#10#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFlo'
- +'atSpinEdit'#11'srow_y3Edit'#4'Left'#3'n'#1#6'Height'#2#24#3'Top'#3#218#0#5
+ +#156#12#192#8'TabOrder'#2#14#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFlo'
+ +'atSpinEdit'#11'srow_z3Edit'#4'Left'#3'n'#1#6'Height'#2#16#3'Top'#3#255#0#5
+'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8
+'MaxValue'#5#0#0#0#0#0#0'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192
- +#8'TabOrder'#2#14#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'
- +#11'srow_z3Edit'#4'Left'#3'n'#1#6'Height'#2#24#3'Top'#3#251#0#5'Width'#2'd'
- +#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5
- +#0#0#0#0#0#0'<'#156#12'@'#8'MinValue'#5#0#0#0#0#0#0'<'#156#12#192#8'TabOrder'
- +#2#18#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#13'quatern_'
- +'bEdit'#4'Left'#2'^'#6'Height'#2#24#3'Top'#2'P'#5'Width'#2'd'#13'DecimalPlac'
- +'es'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0
- +#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#1#5'Value'#5#0#0#0
- +#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#13'quatern_cEdit'#4'Left'#3#212#0
- +#6'Height'#2#24#3'Top'#2'P'#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'
- +#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'
- +#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#2#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0
- +#0#14'TFloatSpinEdit'#13'quatern_dEdit'#4'Left'#3'L'#1#6'Height'#2#24#3'Top'
- +#2'P'#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128
- +#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0
- +#0#8'TabOrder'#2#3#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'
- +#13'qoffset_xEdit'#4'Left'#2'^'#6'Height'#2#24#3'Top'#2'q'#5'Width'#2'd'#13
+ +#8'TabOrder'#2#18#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'
+ +#13'quatern_bEdit'#4'Left'#2'^'#6'Height'#2#16#3'Top'#2'T'#5'Width'#2'd'#13
+'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0
- +#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#4#5'Valu'
- +'e'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#13'qoffset_yEdit'#4'Le'
- +'ft'#3#212#0#6'Height'#2#24#3'Top'#2'q'#5'Width'#2'd'#13'DecimalPlaces'#2#5#9
+ +#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#1#5'Valu'
+ +'e'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#13'quatern_cEdit'#4'Le'
+ +'ft'#3#212#0#6'Height'#2#16#3'Top'#2'T'#5'Width'#2'd'#13'DecimalPlaces'#2#5#9
+'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8
- +'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#5#5'Value'#5#0#0#0#0#0#0#0#128
- +#255'?'#0#0#14'TFloatSpinEdit'#13'qoffset_zEdit'#4'Left'#3'L'#1#6'Height'#2
- +#24#3'Top'#2'q'#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0
- ,#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0
- +#0#0#0#0#0#8'TabOrder'#2#6#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloat'
- +'SpinEdit'#8'QFacEdit'#4'Left'#3#140#0#6'Height'#2#24#3'Top'#2'*'#5'Width'#2
- +'d'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'
- +#5#0#0#0#0#0#0#0#128#255'?'#8'MinValue'#5#0#0#0#0#0#0#0#128#255#191#8'TabOrd'
- +'er'#2#0#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#0#9'TTabSheet'#9'TabSheet3'
- +#7'Caption'#6#15'Image Intensity'#12'ClientHeight'#3'R'#1#11'ClientWidth'#3
- +#14#2#0#6'TLabel'#7'Label12'#4'Left'#2#24#6'Height'#2#17#3'Top'#3#163#0#5'Wi'
- +'dth'#2':'#7'Caption'#6#7'Maximum'#11'ParentColor'#8#0#0#6'TLabel'#7'Label13'
- +#4'Left'#2#24#6'Height'#2#17#3'Top'#3#129#0#5'Width'#2'6'#7'Caption'#6#7'Min'
- +'imum'#11'ParentColor'#8#0#0#6'TLabel'#7'Label23'#4'Left'#2#24#6'Height'#2#17
- +#3'Top'#2#28#5'Width'#2'%'#7'Caption'#6#5'Slope'#11'ParentColor'#8#0#0#6'TLa'
- +'bel'#7'Label22'#4'Left'#2#24#6'Height'#2#17#3'Top'#2'@'#5'Width'#2'4'#7'Cap'
- +'tion'#6#9'Intercept'#11'ParentColor'#8#0#0#6'TLabel'#7'Label30'#4'Left'#2#6
- +#6'Height'#2#17#3'Top'#2#4#5'Width'#2'q'#7'Caption'#6#19'Calibration Scaling'
- +#11'ParentColor'#8#0#0#6'TLabel'#7'Label33'#4'Left'#2#6#6'Height'#2#17#3'Top'
- +#2'g'#5'Width'#3#192#0#7'Caption'#6' Display Range (calibrated units)'#11'Pa'
- +'rentColor'#8#0#0#14'TFloatSpinEdit'#4'cmax'#4'Left'#2'^'#6'Height'#2#24#3'T'
- +'op'#3#161#0#5'Width'#2'n'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0
- +#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0
- +#224#31#188#190#25#192#8'TabOrder'#2#3#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#14
- +'TFloatSpinEdit'#4'cmin'#4'Left'#2'^'#6'Height'#2#24#3'Top'#2'}'#5'Width'#2
- +'n'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'
- +#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25#192#8
- +'TabOrder'#2#2#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#14'TFloatSpinEdit'#5'Scale'
- +#4'Left'#2'^'#6'Height'#2#24#3'Top'#2#24#5'Width'#2'n'#13'DecimalPlaces'#2#5
+ +'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#2#5'Value'#5#0#0#0#0#0#0#0#128
+ +#255'?'#0#0#14'TFloatSpinEdit'#13'quatern_dEdit'#4'Left'#3'L'#1#6'Height'#2
+ +#16#3'Top'#2'T'#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0
+ +#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0
+ +#0#0#0#0#0#8'TabOrder'#2#3#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloat'
+ +'SpinEdit'#13'qoffset_xEdit'#4'Left'#2'^'#6'Height'#2#16#3'Top'#2'u'#5'Width'
+ +#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxVal'
+ +'ue'#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2
+ +#4#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#13'qoffset_yEd'
+ +'it'#4'Left'#3#212#0#6'Height'#2#16#3'Top'#2'u'#5'Width'#2'd'#13'DecimalPlac'
+ +'es'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0
+ +#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#5#5'Value'#5#0#0#0
+ +#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#13'qoffset_zEdit'#4'Left'#3'L'#1#6
+ +'Height'#2#16#3'Top'#2'u'#5'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5
+ ,#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'#5
+ +#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#6#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0
+ +#14'TFloatSpinEdit'#8'QFacEdit'#4'Left'#3#140#0#6'Height'#2#16#3'Top'#2'.'#5
+ +'Width'#2'd'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8
+ +'MaxValue'#5#0#0#0#0#0#0#0#128#255'?'#8'MinValue'#5#0#0#0#0#0#0#0#128#255#191
+ +#8'TabOrder'#2#0#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#0#9'TTabSheet'#9'Ta'
+ +'bSheet3'#7'Caption'#6#15'Image Intensity'#12'ClientHeight'#3'R'#1#11'Client'
+ +'Width'#3#14#2#0#6'TLabel'#7'Label12'#4'Left'#2#24#6'Height'#2#17#3'Top'#3
+ +#163#0#5'Width'#2':'#7'Caption'#6#7'Maximum'#11'ParentColor'#8#0#0#6'TLabel'
+ +#7'Label13'#4'Left'#2#24#6'Height'#2#17#3'Top'#3#129#0#5'Width'#2'6'#7'Capti'
+ +'on'#6#7'Minimum'#11'ParentColor'#8#0#0#6'TLabel'#7'Label23'#4'Left'#2#24#6
+ +'Height'#2#17#3'Top'#2#28#5'Width'#2'%'#7'Caption'#6#5'Slope'#11'ParentColor'
+ +#8#0#0#6'TLabel'#7'Label22'#4'Left'#2#24#6'Height'#2#17#3'Top'#2'@'#5'Width'
+ +#2'4'#7'Caption'#6#9'Intercept'#11'ParentColor'#8#0#0#6'TLabel'#7'Label30'#4
+ +'Left'#2#6#6'Height'#2#17#3'Top'#2#4#5'Width'#2'q'#7'Caption'#6#19'Calibrati'
+ +'on Scaling'#11'ParentColor'#8#0#0#6'TLabel'#7'Label33'#4'Left'#2#6#6'Height'
+ +#2#17#3'Top'#2'g'#5'Width'#3#192#0#7'Caption'#6' Display Range (calibrated u'
+ +'nits)'#11'ParentColor'#8#0#0#14'TFloatSpinEdit'#4'cmax'#4'Left'#2'^'#6'Heig'
+ +'ht'#2#16#3'Top'#3#165#0#5'Width'#2'n'#13'DecimalPlaces'#2#5#9'Increment'#5#0
+ +#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValu'
+ +'e'#5#0#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#3#5'Value'#5#0#0#0#0#0#0#0
+ +#0#0#0#0#0#14'TFloatSpinEdit'#4'cmin'#4'Left'#2'^'#6'Height'#2#16#3'Top'#3
+ +#129#0#5'Width'#2'n'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128
+ +#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224
+ +#31#188#190#25#192#8'TabOrder'#2#2#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#14'TFl'
+ +'oatSpinEdit'#5'Scale'#4'Left'#2'^'#6'Height'#2#16#3'Top'#2#28#5'Width'#2'n'
+ +#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5
+ +#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25#192#8
+ +'TabOrder'#2#0#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#14'TFloatSpinEdit'#9'Inter'
+ +'cept'#4'Left'#2'^'#6'Height'#2#16#3'Top'#2'@'#5'Width'#2'n'#13'DecimalPlace'
+ +'s'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31
+ +#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#1#5
+ +'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#0#9'TTabSheet'#9'TabSheet1'#7'Caption'#6#10
+ +'Statistics'#12'ClientHeight'#3'R'#1#11'ClientWidth'#3#14#2#0#6'TLabel'#7'La'
+ +'bel35'#4'Left'#2#8#6'Height'#2#17#3'Top'#2#14#5'Width'#2'2'#7'Caption'#6#9
+ +'Intention'#11'ParentColor'#8#0#0#6'TLabel'#7'Label25'#4'Left'#2#24#6'Height'
+ +#2#17#3'Top'#2'.'#5'Width'#2'J'#7'Caption'#6#11'Parameter 1'#11'ParentColor'
+ +#8#0#0#6'TLabel'#7'Label27'#4'Left'#2#24#6'Height'#2#17#3'Top'#2'S'#5'Width'
+ +#2'J'#7'Caption'#6#11'Parameter 2'#11'ParentColor'#8#0#0#6'TLabel'#7'Label28'
+ +#4'Left'#2#24#6'Height'#2#17#3'Top'#2'v'#5'Width'#2'J'#7'Caption'#6#11'Param'
+ +'eter 3'#11'ParentColor'#8#0#0#9'TComboBox'#14'IntentCodeDrop'#4'Left'#2'L'#6
+ +'Height'#2#20#3'Top'#2#8#5'Width'#3#218#0#13'DropDownCount'#2','#10'ItemHeig'
+ +'ht'#2#0#13'Items.Strings'#1#6#14'Not statistics'#6#24'Correlation coefficie'
+ +'nt '#6#24'T-testation coefficient '#6#6'F-test'#6#7'Z-score'#6#11'Chi-squar'
+ +'ed'#6#11'Beta distri'#6#21'Binomial distribution'#6#18'Gamma distribution'#6
+ +#18'Gamma distribution'#6#19'Normal distribution'#6#22'Noncentral F statisti'
+ +'c'#6#22'Noncentral chi-squared'#6' Logistic distributiond statistic'#6#20'L'
+ +'aplace distribution'#6#20'Uniform distribution'#6#22'Noncentral t statistic'
+ +#6#20'Weibull distribution'#6#16'Chi distribution'#6#17'Inverse Gaussian '#6
+ +#20'Extreme value type I'#6#20'p-value value type I'#6#11'ln(p-value)'#6#11
+ +'log10(p-val'#6#14'Estimatevalue)'#6#8'Labelste'#6#6'NeuroN'#6#9'Generic M'#6
+ +#16'Symmetric Matrix'#6#25'Displacement Field/Vector'#6#25'Vectorcement Fiel'
+ +'d/Vector'#6#6'Points'#6#15'Triangle (mesh)'#6#10'Quaternion'#0#5'Style'#7#14
+ +'csDropDownList'#8'TabOrder'#2#3#0#0#14'TFloatSpinEdit'#13'intent_p1Edit'#4
+ +'Left'#2'n'#6'Height'#2#16#3'Top'#2'.'#5'Width'#3#138#0#13'DecimalPlaces'#2#5
+#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190
+#25'@'#8'MinValue'#5#0#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#0#5'Value'#5
- +#0#0#0#0#0#0#0#0#0#0#0#0#14'TFloatSpinEdit'#9'Intercept'#4'Left'#2'^'#6'Heig'
- +'ht'#2#24#3'Top'#2'<'#5'Width'#2'n'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0
- +#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'
- +#5#0#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#1#5'Value'#5#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#9'TTabSheet'#9'TabSheet1'#7'Caption'#6#10'Statistics'#12'ClientHeig'
- +'ht'#3'R'#1#11'ClientWidth'#3#14#2#0#6'TLabel'#7'Label35'#4'Left'#2#8#6'Heig'
- +'ht'#2#17#3'Top'#2#14#5'Width'#2'2'#7'Caption'#6#9'Intention'#11'ParentColor'
- +#8#0#0#6'TLabel'#7'Label25'#4'Left'#2#24#6'Height'#2#17#3'Top'#2'.'#5'Width'
- +#2'J'#7'Caption'#6#11'Parameter 1'#11'ParentColor'#8#0#0#6'TLabel'#7'Label27'
- +#4'Left'#2#24#6'Height'#2#17#3'Top'#2'S'#5'Width'#2'J'#7'Caption'#6#11'Param'
- +'eter 2'#11'ParentColor'#8#0#0#6'TLabel'#7'Label28'#4'Left'#2#24#6'Height'#2
- +#17#3'Top'#2'v'#5'Width'#2'J'#7'Caption'#6#11'Parameter 3'#11'ParentColor'#8
- +#0#0#9'TComboBox'#14'IntentCodeDrop'#4'Left'#2'L'#6'Height'#2#24#3'Top'#2#8#5
- +'Width'#3#218#0#13'DropDownCount'#2','#10'ItemHeight'#2#16#13'Items.Strings'
- +#1#6#14'Not statistics'#6#24'Correlation coefficient '#6#24'T-testation coef'
- +'ficient '#6#6'F-test'#6#7'Z-score'#6#11'Chi-squared'#6#11'Beta distri'#6#21
- +'Binomial distribution'#6#18'Gamma distribution'#6#18'Gamma distribution'#6
- +#19'Normal distribution'#6#22'Noncentral F statistic'#6#22'Noncentral chi-sq'
- +'uared'#6' Logistic distributiond statistic'#6#20'Laplace distribution'#6#20
- +'Uniform distribution'#6#22'Noncentral t statistic'#6#20'Weibull distributio'
- +'n'#6#16'Chi distribution'#6#17'Inverse Gaussian '#6#20'Extreme value type I'
- +#6#20'p-value value type I'#6#11'ln(p-value)'#6#11'log10(p-val'#6#14'Estimat'
- +'evalue)'#6#8'Labelste'#6#6'NeuroN'#6#9'Generic M'#6#16'Symmetric Matrix'#6
- +#25'Displacement Field/Vector'#6#25'Vectorcement Field/Vector'#6#6'Points'#6
- +#15'Triangle (mesh)'#6#10'Quaternion'#0#5'Style'#7#14'csDropDownList'#8'TabO'
- +'rder'#2#3#0#0#14'TFloatSpinEdit'#13'intent_p1Edit'#4'Left'#2'n'#6'Height'#2
- +#24#3'Top'#2'*'#5'Width'#3#138#0#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#14'TFloatSpinEdit'#13'intent_p2Edit'#4'Left'#2'n'#6
+ +'Height'#2#16#3'Top'#2'S'#5'Width'#3#138#0#13'DecimalPlaces'#2#5#9'Increment'
+ +#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'Min'
+ +'Value'#5#0#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#1#5'Value'#5#0#0#0#0#0
+ +#0#0#0#0#0#0#0#14'TFloatSpinEdit'#13'intent_p3Edit'#4'Left'#2'n'#6'Height'#2
+ +#16#3'Top'#2'w'#5'Width'#3#138#0#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0
+#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0
- +#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#0#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0
- +#0#14'TFloatSpinEdit'#13'intent_p2Edit'#4'Left'#2'n'#6'Height'#2#24#3'Top'#2
- +'O'#5'Width'#3#138#0#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128
- +#255'?'#8'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224
- +#31#188#190#25#192#8'TabOrder'#2#1#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#14'TFl'
- +'oatSpinEdit'#13'intent_p3Edit'#4'Left'#2'n'#6'Height'#2#24#3'Top'#2's'#5'Wi'
- +'dth'#3#138#0#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8
- +'MaxValue'#5#0#0#0#0#224#31#188#190#25'@'#8'MinValue'#5#0#0#0#0#224#31#188
- ,#190#25#192#8'TabOrder'#2#2#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0#0#0#9'TTabSheet'
- +#9'TabSheet2'#7'Caption'#6#4'fMRI'#12'ClientHeight'#3'M'#1#11'ClientWidth'#3
- +#18#2#0#6'TLabel'#7'Label11'#4'Left'#2#12#6'Height'#2#13#3'Top'#3#145#0#5'Wi'
- +'dth'#2'A'#7'Caption'#6#11'Slice Order'#11'ParentColor'#8#0#0#6'TLabel'#7'La'
- +'bel16'#4'Left'#2#12#6'Height'#2#13#3'Top'#2#8#5'Width'#2'?'#7'Caption'#6#11
- +'Time Offset'#11'ParentColor'#8#0#0#6'TLabel'#7'Label17'#4'Left'#2#14#6'Heig'
- +'ht'#2#13#3'Top'#2''''#5'Width'#2'N'#7'Caption'#6#14'Slice duration'#11'Pare'
- +'ntColor'#8#0#0#6'TLabel'#7'Label32'#4'Left'#2#12#6'Height'#2#13#3'Top'#2'J'
- +#5'Width'#2':'#7'Caption'#6#11'Slice Start'#11'ParentColor'#8#0#0#6'TLabel'#7
- +'Label20'#4'Left'#2#12#6'Height'#2#13#3'Top'#2'i'#5'Width'#2'7'#7'Caption'#6
- +#9'Slice End'#11'ParentColor'#8#0#0#6'TLabel'#7'Label31'#4'Left'#2#12#6'Heig'
- +'ht'#2#13#3'Top'#3#178#0#5'Width'#2'|'#7'Caption'#6#19'Frequency Dimension'
- +#11'ParentColor'#8#0#0#6'TLabel'#7'Label43'#4'Left'#2#12#6'Height'#2#13#3'To'
- +'p'#3#214#0#5'Width'#2'b'#7'Caption'#6#15'Phase Dimension'#11'ParentColor'#8
- +#0#0#6'TLabel'#7'Label45'#4'Left'#2#12#6'Height'#2#13#3'Top'#3#250#0#5'Width'
- +#2'['#7'Caption'#6#15'Slice Dimension'#11'ParentColor'#8#0#0#9'TComboBox'#13
- +'SliceCodeDrop'#4'Left'#2'W'#6'Height'#2#24#3'Top'#3#137#0#5'Width'#3#159#0
- +#10'ItemHeight'#2#16#13'Items.Strings'#1#6#7'Unknown'#6#21'Sequential Increa'
- +'sing'#6#21'Sequential Decreasing'#6#22'Alternating Increasing'#6#22'Alterna'
- +'ting Decreasing'#0#8'OnSelect'#7#13'ImageSzChange'#5'Style'#7#14'csDropDown'
- +'List'#8'TabOrder'#2#4#0#0#9'TComboBox'#11'FreqDimDrop'#4'Left'#3#146#0#6'He'
- +'ight'#2#24#3'Top'#3#174#0#5'Width'#2'd'#10'ItemHeight'#2#16#13'Items.String'
- +'s'#1#6#7'Unknown'#6#1'I'#6#1'J'#6#1'K'#0#8'OnSelect'#7#13'ImageSzChange'#5
- +'Style'#7#14'csDropDownList'#8'TabOrder'#2#5#0#0#9'TComboBox'#12'PhaseDimDro'
- +'p'#4'Left'#3#146#0#6'Height'#2#24#3'Top'#3#210#0#5'Width'#2'd'#10'ItemHeigh'
- +'t'#2#16#13'Items.Strings'#1#6#7'Unknown'#6#1'I'#6#1'J'#6#1'K'#0#8'OnSelect'
- +#7#13'ImageSzChange'#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#6#0#0#9'TCo'
- +'mboBox'#12'SliceDimDrop'#4'Left'#3#146#0#6'Height'#2#24#3'Top'#3#246#0#5'Wi'
- +'dth'#2'd'#10'ItemHeight'#2#16#13'Items.Strings'#1#6#7'Unknown'#6#1'I'#6#1'J'
- +#6#1'K'#0#8'OnSelect'#7#13'ImageSzChange'#5'Style'#7#14'csDropDownList'#8'Ta'
- +'bOrder'#2#7#0#0#9'TSpinEdit'#15'slice_startEdit'#4'Left'#2'x'#6'Height'#2#22
- +#3'Top'#2'F'#5'Width'#2'p'#8'TabOrder'#2#2#5'Value'#2#1#0#0#14'TFloatSpinEdi'
- +'t'#18'Slice_durationEdit'#4'Left'#2'x'#6'Height'#2#22#3'Top'#2'#'#5'Width'#2
- +'p'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'
- +#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#1#5
- +'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'toffsetEdit'#4
- +'Left'#2'x'#6'Height'#2#22#3'Top'#2#4#5'Width'#2'p'#13'DecimalPlaces'#2#5#9
- +'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0#200#5'@'#8
- +'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#0#5'Value'#5#0#0#0#0#0#0#0#128
- +#255'?'#0#0#9'TSpinEdit'#13'slice_endEdit'#4'Left'#2'x'#6'Height'#2#22#3'Top'
- +#2'e'#5'Width'#2'p'#8'TabOrder'#2#3#5'Value'#2#1#0#0#0#9'TTabSheet'#9'TabUnu'
- +'sed'#7'Caption'#6#8'Optional'#12'ClientHeight'#3'M'#1#11'ClientWidth'#3#18#2
- +#0#6'TLabel'#7'Label34'#4'Left'#2#3#6'Height'#2#13#3'Top'#2'+'#5'Width'#2';'
- +#7'Caption'#6#9'Data Type'#11'ParentColor'#8#0#0#6'TLabel'#6'Label5'#4'Left'
- +#2#3#6'Height'#2#13#3'Top'#2#8#5'Width'#2'0'#7'Caption'#6#9'Intention'#11'Pa'
- +'rentColor'#8#0#0#6'TLabel'#6'Label6'#4'Left'#3#12#1#6'Height'#2#13#3'Top'#2
- +'t'#5'Width'#2')'#7'Caption'#6#7'Extents'#11'ParentColor'#8#0#0#6'TLabel'#6
- +'Label9'#4'Left'#3#12#1#6'Height'#2#13#3'Top'#2'L'#5'Width'#2'F'#7'Caption'#6
- +#12'Sesion Error'#11'ParentColor'#8#0#0#6'TLabel'#7'Label10'#4'Left'#3#12#1#6
- +'Height'#2#13#3'Top'#3#148#0#5'Width'#2'K'#7'Caption'#6#13'Regular [114]'#11
- +'ParentColor'#8#0#0#6'TLabel'#7'Label14'#4'Left'#3#12#1#6'Height'#2#13#3'Top'
- +#2#8#5'Width'#2'#'#7'Caption'#6#5'G Min'#11'ParentColor'#8#0#0#6'TLabel'#7'L'
- +'abel15'#4'Left'#3#12#1#6'Height'#2#13#3'Top'#2'+'#5'Width'#2'&'#7'Caption'#6
- +#5'G Max'#11'ParentColor'#8#0#0#6'TLabel'#7'Label18'#4'Left'#2#3#6'Height'#2
- +#13#3'Top'#3#148#0#5'Width'#2'0'#7'Caption'#6#8'Aux File'#11'ParentColor'#8#0
- +#0#6'TLabel'#7'Label19'#4'Left'#2#3#6'Height'#2#13#3'Top'#2'o'#5'Width'#2'6'
- +#7'Caption'#6#7'DB Name'#11'ParentColor'#8#0#0#6'TLabel'#7'Label26'#4'Left'#2
- +#3#6'Height'#2#13#3'Top'#2'L'#5'Width'#2'!'#7'Caption'#6#5'Notes'#11'ParentC'
- +'olor'#8#0#0#5'TEdit'#15'intent_nameEdit'#4'Left'#2'L'#6'Height'#2#25#3'Top'
- +#2#6#5'Width'#3#152#0#9'MaxLength'#2#16#8'TabOrder'#2#0#4'Text'#6#11'intent_'
- +'name'#0#0#5'TEdit'#13'data_typeEdit'#4'Left'#2'L'#6'Height'#2#25#3'Top'#2')'
- +#5'Width'#3#152#0#9'MaxLength'#2#10#8'TabOrder'#2#1#4'Text'#6#9'data_type'#0
- +#0#5'TEdit'#11'CommentEdit'#4'Left'#2'L'#6'Height'#2#25#3'Top'#2'J'#5'Width'
- +#3#152#0#9'MaxLength'#2'P'#8'TabOrder'#2#2#4'Text'#6#11'CommentEdit'#0#0#5'T'
- ,'Edit'#3'db_'#4'Left'#2'L'#6'Height'#2#25#3'Top'#2'm'#5'Width'#3#152#0#9'Max'
- +'Length'#2#18#8'TabOrder'#2#3#4'Text'#6#3'db_'#0#0#5'TEdit'#3'aux'#4'Left'#2
- +'L'#6'Height'#2#25#3'Top'#3#148#0#5'Width'#3#152#0#9'MaxLength'#2#24#8'TabOr'
- +'der'#2#4#4'Text'#6#3'aux'#0#0#9'TSpinEdit'#4'gmax'#4'Left'#3'n'#1#6'Height'
- +#2#22#3'Top'#2')'#5'Width'#2'B'#8'TabOrder'#2#6#5'Value'#2#1#0#0#9'TSpinEdit'
- +#4'gmin'#4'Left'#3'n'#1#6'Height'#2#22#3'Top'#2#6#5'Width'#2'B'#8'TabOrder'#2
- +#5#5'Value'#2#1#0#0#9'TSpinEdit'#3'ses'#4'Left'#3'n'#1#6'Height'#2#22#3'Top'
- +#2'J'#5'Width'#2'B'#8'TabOrder'#2#7#5'Value'#2#1#0#0#9'TSpinEdit'#3'ext'#4'L'
- +'eft'#3'n'#1#6'Height'#2#22#3'Top'#2'r'#5'Width'#2'B'#8'TabOrder'#2#8#5'Valu'
- +'e'#2#1#0#0#9'TSpinEdit'#3'reg'#4'Left'#3'n'#1#6'Height'#2#22#3'Top'#3#148#0
- +#5'Width'#2'B'#8'MaxValue'#3#255#0#8'TabOrder'#2#9#5'Value'#2#1#0#0#0#0#10'T'
- +'StatusBar'#10'StatusBar1'#4'Left'#2#0#6'Height'#2#20#3'Top'#3'{'#1#5'Width'
- +#3#30#2#6'Panels'#14#1#5'Width'#3#140#0#0#1#5'Width'#2'2'#0#0#11'SimplePanel'
- +#8#0#0#9'TMainMenu'#9'MainMenu1'#4'left'#3#155#1#3'top'#2#6#0#9'TMenuItem'#5
- +'File1'#7'Caption'#6#5'&File'#0#9'TMenuItem'#5'Open1'#7'Caption'#6#11'Open h'
- +'eader'#8'ShortCut'#3'O@'#7'OnClick'#7#10'Open1Click'#0#0#9'TMenuItem'#5'Sav'
- +'e1'#7'Caption'#6#11'Save header'#8'ShortCut'#3'S@'#7'OnClick'#7#10'Save1Cli'
- +'ck'#0#0#9'TMenuItem'#5'Exit1'#7'Caption'#6#12'Close window'#8'ShortCut'#3'W'
- +'@'#7'OnClick'#7#10'Exit1Click'#0#0#0#9'TMenuItem'#5'Page1'#7'Caption'#6#4'&'
- +'Tab'#0#9'TMenuItem'#11'Dimensions1'#7'Caption'#6#10'Dimensions'#8'ShortCut'
- +#3'A@'#7'OnClick'#7#12'TabMenuClick'#0#0#9'TMenuItem'#10'Rotations1'#3'Tag'#2
- +#1#7'Caption'#6#8'Reorient'#8'ShortCut'#3'B@'#7'OnClick'#7#12'TabMenuClick'#0
- +#0#9'TMenuItem'#15'ImageIntensity1'#3'Tag'#2#2#7'Caption'#6#15'Image Intensi'
- +'ty'#8'ShortCut'#3'C@'#7'OnClick'#7#12'TabMenuClick'#0#0#9'TMenuItem'#11'Sta'
- +'tistics1'#3'Tag'#2#3#7'Caption'#6#10'Statistics'#8'ShortCut'#3'D@'#7'OnClic'
- +'k'#7#12'TabMenuClick'#0#0#9'TMenuItem'#14'FunctionalMRI1'#3'Tag'#2#4#7'Capt'
- +'ion'#6#14'Functional MRI'#8'ShortCut'#3'E@'#7'OnClick'#7#12'TabMenuClick'#0
- +#0#9'TMenuItem'#9'Optional1'#3'Tag'#2#5#7'Caption'#6#8'Optional'#8'ShortCut'
- +#3'F@'#7'OnClick'#7#12'TabMenuClick'#0#0#0#9'TMenuItem'#5'Help1'#7'Caption'#6
- +#5'&Help'#0#9'TMenuItem'#6'About1'#7'Caption'#6#8'About...'#7'OnClick'#7#11
- +'About1Click'#0#0#0#0#11'TOpenDialog'#10'OpenHdrDlg'#11'FilterIndex'#2#0#7'O'
- +'ptions'#11#15'ofFileMustExist'#0#4'left'#3#194#1#3'top'#2#6#0#0#11'TSaveDia'
- +'log'#10'SaveHdrDlg'#7'OnClose'#7#15'SaveHdrDlgClose'#5'Width'#2'4'#6'Filter'
- +#6'`NIfTI (*.hdr;*.nii)|*.hdr; *.nii|NIfTI separate header (*.hdr)|*.hdr|NIf'
- +'TI embedded header|*.nii'#11'FilterIndex'#2#0#4'left'#3#228#1#3'top'#2#6#0#0
- +#0
-]);
+ ,#0#0#0#224#31#188#190#25#192#8'TabOrder'#2#2#5'Value'#5#0#0#0#0#0#0#0#0#0#0#0
+ +#0#0#9'TTabSheet'#9'TabSheet2'#7'Caption'#6#4'fMRI'#12'ClientHeight'#3'M'#1
+ +#11'ClientWidth'#3#18#2#0#6'TLabel'#7'Label11'#4'Left'#2#12#6'Height'#2#13#3
+ +'Top'#3#145#0#5'Width'#2'A'#7'Caption'#6#11'Slice Order'#11'ParentColor'#8#0
+ +#0#6'TLabel'#7'Label16'#4'Left'#2#12#6'Height'#2#13#3'Top'#2#8#5'Width'#2'?'
+ +#7'Caption'#6#11'Time Offset'#11'ParentColor'#8#0#0#6'TLabel'#7'Label17'#4'L'
+ +'eft'#2#14#6'Height'#2#13#3'Top'#2''''#5'Width'#2'N'#7'Caption'#6#14'Slice d'
+ +'uration'#11'ParentColor'#8#0#0#6'TLabel'#7'Label32'#4'Left'#2#12#6'Height'#2
+ +#13#3'Top'#2'J'#5'Width'#2':'#7'Caption'#6#11'Slice Start'#11'ParentColor'#8
+ +#0#0#6'TLabel'#7'Label20'#4'Left'#2#12#6'Height'#2#13#3'Top'#2'i'#5'Width'#2
+ +'7'#7'Caption'#6#9'Slice End'#11'ParentColor'#8#0#0#6'TLabel'#7'Label31'#4'L'
+ +'eft'#2#12#6'Height'#2#13#3'Top'#3#178#0#5'Width'#2'|'#7'Caption'#6#19'Frequ'
+ +'ency Dimension'#11'ParentColor'#8#0#0#6'TLabel'#7'Label43'#4'Left'#2#12#6'H'
+ +'eight'#2#13#3'Top'#3#214#0#5'Width'#2'b'#7'Caption'#6#15'Phase Dimension'#11
+ +'ParentColor'#8#0#0#6'TLabel'#7'Label45'#4'Left'#2#12#6'Height'#2#13#3'Top'#3
+ +#250#0#5'Width'#2'['#7'Caption'#6#15'Slice Dimension'#11'ParentColor'#8#0#0#9
+ +'TComboBox'#13'SliceCodeDrop'#4'Left'#2'W'#6'Height'#2#20#3'Top'#3#137#0#5'W'
+ +'idth'#3#159#0#10'ItemHeight'#2#0#13'Items.Strings'#1#6#7'Unknown'#6#21'Sequ'
+ +'ential Increasing'#6#21'Sequential Decreasing'#6#22'Alternating Increasing'
+ +#6#22'Alternating Decreasing'#0#8'OnSelect'#7#13'ImageSzChange'#5'Style'#7#14
+ +'csDropDownList'#8'TabOrder'#2#4#0#0#9'TComboBox'#11'FreqDimDrop'#4'Left'#3
+ +#146#0#6'Height'#2#20#3'Top'#3#174#0#5'Width'#2'd'#10'ItemHeight'#2#0#13'Ite'
+ +'ms.Strings'#1#6#7'Unknown'#6#1'I'#6#1'J'#6#1'K'#0#8'OnSelect'#7#13'ImageSzC'
+ +'hange'#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#5#0#0#9'TComboBox'#12'Ph'
+ +'aseDimDrop'#4'Left'#3#146#0#6'Height'#2#20#3'Top'#3#210#0#5'Width'#2'd'#10
+ +'ItemHeight'#2#0#13'Items.Strings'#1#6#7'Unknown'#6#1'I'#6#1'J'#6#1'K'#0#8'O'
+ +'nSelect'#7#13'ImageSzChange'#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#6#0
+ +#0#9'TComboBox'#12'SliceDimDrop'#4'Left'#3#146#0#6'Height'#2#20#3'Top'#3#246
+ +#0#5'Width'#2'd'#10'ItemHeight'#2#0#13'Items.Strings'#1#6#7'Unknown'#6#1'I'#6
+ +#1'J'#6#1'K'#0#8'OnSelect'#7#13'ImageSzChange'#5'Style'#7#14'csDropDownList'
+ +#8'TabOrder'#2#7#0#0#9'TSpinEdit'#15'slice_startEdit'#4'Left'#2'x'#6'Height'
+ +#2#16#3'Top'#2'I'#5'Width'#2'p'#8'TabOrder'#2#2#5'Value'#2#1#0#0#14'TFloatSp'
+ +'inEdit'#18'Slice_durationEdit'#4'Left'#2'x'#6'Height'#2#16#3'Top'#2'&'#5'Wi'
+ +'dth'#2'p'#13'DecimalPlaces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'M'
+ +'axValue'#5#0#0#0#0#0#0#0#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOr'
+ +'der'#2#1#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFloatSpinEdit'#11'toff'
+ +'setEdit'#4'Left'#2'x'#6'Height'#2#16#3'Top'#2#7#5'Width'#2'p'#13'DecimalPla'
+ +'ces'#2#5#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#0#0
+ +#200#5'@'#8'MinValue'#5#0#0#0#0#0#0#0#0#0#0#8'TabOrder'#2#0#5'Value'#5#0#0#0
+ +#0#0#0#0#128#255'?'#0#0#9'TSpinEdit'#13'slice_endEdit'#4'Left'#2'x'#6'Height'
+ +#2#16#3'Top'#2'h'#5'Width'#2'p'#8'TabOrder'#2#3#5'Value'#2#1#0#0#0#9'TTabShe'
+ +'et'#9'TabUnused'#7'Caption'#6#8'Optional'#12'ClientHeight'#3'M'#1#11'Client'
+ +'Width'#3#18#2#0#6'TLabel'#7'Label34'#4'Left'#2#3#6'Height'#2#13#3'Top'#2'+'
+ +#5'Width'#2';'#7'Caption'#6#9'Data Type'#11'ParentColor'#8#0#0#6'TLabel'#6'L'
+ +'abel5'#4'Left'#2#3#6'Height'#2#13#3'Top'#2#8#5'Width'#2'0'#7'Caption'#6#9'I'
+ +'ntention'#11'ParentColor'#8#0#0#6'TLabel'#6'Label6'#4'Left'#3#12#1#6'Height'
+ +#2#13#3'Top'#2't'#5'Width'#2')'#7'Caption'#6#7'Extents'#11'ParentColor'#8#0#0
+ +#6'TLabel'#6'Label9'#4'Left'#3#12#1#6'Height'#2#13#3'Top'#2'L'#5'Width'#2'F'
+ +#7'Caption'#6#12'Sesion Error'#11'ParentColor'#8#0#0#6'TLabel'#7'Label10'#4
+ +'Left'#3#12#1#6'Height'#2#13#3'Top'#3#148#0#5'Width'#2'K'#7'Caption'#6#13'Re'
+ +'gular [114]'#11'ParentColor'#8#0#0#6'TLabel'#7'Label14'#4'Left'#3#12#1#6'He'
+ +'ight'#2#13#3'Top'#2#8#5'Width'#2'#'#7'Caption'#6#5'G Min'#11'ParentColor'#8
+ +#0#0#6'TLabel'#7'Label15'#4'Left'#3#12#1#6'Height'#2#13#3'Top'#2'+'#5'Width'
+ +#2'&'#7'Caption'#6#5'G Max'#11'ParentColor'#8#0#0#6'TLabel'#7'Label18'#4'Lef'
+ +'t'#2#3#6'Height'#2#13#3'Top'#3#148#0#5'Width'#2'0'#7'Caption'#6#8'Aux File'
+ +#11'ParentColor'#8#0#0#6'TLabel'#7'Label19'#4'Left'#2#3#6'Height'#2#13#3'Top'
+ +#2'o'#5'Width'#2'6'#7'Caption'#6#7'DB Name'#11'ParentColor'#8#0#0#6'TLabel'#7
+ +'Label26'#4'Left'#2#3#6'Height'#2#13#3'Top'#2'L'#5'Width'#2'!'#7'Caption'#6#5
+ +'Notes'#11'ParentColor'#8#0#0#5'TEdit'#15'intent_nameEdit'#4'Left'#2'L'#6'He'
+ +'ight'#2#25#3'Top'#2#6#5'Width'#3#152#0#9'MaxLength'#2#16#8'TabOrder'#2#0#4
+ +'Text'#6#11'intent_name'#0#0#5'TEdit'#13'data_typeEdit'#4'Left'#2'L'#6'Heigh'
+ +'t'#2#25#3'Top'#2')'#5'Width'#3#152#0#9'MaxLength'#2#10#8'TabOrder'#2#1#4'Te'
+ +'xt'#6#9'data_type'#0#0#5'TEdit'#11'CommentEdit'#4'Left'#2'L'#6'Height'#2#25
+ +#3'Top'#2'J'#5'Width'#3#152#0#9'MaxLength'#2'P'#8'TabOrder'#2#2#4'Text'#6#11
+ ,'CommentEdit'#0#0#5'TEdit'#3'db_'#4'Left'#2'L'#6'Height'#2#25#3'Top'#2'm'#5
+ +'Width'#3#152#0#9'MaxLength'#2#18#8'TabOrder'#2#3#4'Text'#6#3'db_'#0#0#5'TEd'
+ +'it'#3'aux'#4'Left'#2'L'#6'Height'#2#25#3'Top'#3#148#0#5'Width'#3#152#0#9'Ma'
+ +'xLength'#2#24#8'TabOrder'#2#4#4'Text'#6#3'aux'#0#0#9'TSpinEdit'#4'gmax'#4'L'
+ +'eft'#3'n'#1#6'Height'#2#16#3'Top'#2','#5'Width'#2'B'#8'TabOrder'#2#6#5'Valu'
+ +'e'#2#1#0#0#9'TSpinEdit'#4'gmin'#4'Left'#3'n'#1#6'Height'#2#16#3'Top'#2#9#5
+ +'Width'#2'B'#8'TabOrder'#2#5#5'Value'#2#1#0#0#9'TSpinEdit'#3'ses'#4'Left'#3
+ +'n'#1#6'Height'#2#16#3'Top'#2'M'#5'Width'#2'B'#8'TabOrder'#2#7#5'Value'#2#1#0
+ +#0#9'TSpinEdit'#3'ext'#4'Left'#3'n'#1#6'Height'#2#16#3'Top'#2'u'#5'Width'#2
+ +'B'#8'TabOrder'#2#8#5'Value'#2#1#0#0#9'TSpinEdit'#3'reg'#4'Left'#3'n'#1#6'He'
+ +'ight'#2#16#3'Top'#3#151#0#5'Width'#2'B'#8'MaxValue'#3#255#0#8'TabOrder'#2#9
+ +#5'Value'#2#1#0#0#0#0#10'TStatusBar'#10'StatusBar1'#4'Left'#2#0#6'Height'#2
+ +#15#3'Top'#3#147#1#5'Width'#3#30#2#6'Panels'#14#1#5'Width'#3#140#0#0#1#5'Wid'
+ +'th'#2'2'#0#0#11'SimplePanel'#8#0#0#9'TMainMenu'#9'MainMenu1'#4'left'#3#155#1
+ +#3'top'#2#6#0#9'TMenuItem'#5'File1'#7'Caption'#6#5'&File'#0#9'TMenuItem'#5'O'
+ +'pen1'#7'Caption'#6#11'Open header'#8'ShortCut'#3'O@'#7'OnClick'#7#10'Open1C'
+ +'lick'#0#0#9'TMenuItem'#5'Save1'#7'Caption'#6#11'Save header'#8'ShortCut'#3
+ +'S@'#7'OnClick'#7#10'Save1Click'#0#0#9'TMenuItem'#5'Exit1'#7'Caption'#6#12'C'
+ +'lose window'#8'ShortCut'#3'W@'#7'OnClick'#7#10'Exit1Click'#0#0#0#9'TMenuIte'
+ +'m'#5'Page1'#7'Caption'#6#4'&Tab'#0#9'TMenuItem'#11'Dimensions1'#7'Caption'#6
+ +#10'Dimensions'#8'ShortCut'#3'A@'#7'OnClick'#7#12'TabMenuClick'#0#0#9'TMenuI'
+ +'tem'#10'Rotations1'#3'Tag'#2#1#7'Caption'#6#8'Reorient'#8'ShortCut'#3'B@'#7
+ +'OnClick'#7#12'TabMenuClick'#0#0#9'TMenuItem'#15'ImageIntensity1'#3'Tag'#2#2
+ +#7'Caption'#6#15'Image Intensity'#8'ShortCut'#3'C@'#7'OnClick'#7#12'TabMenuC'
+ +'lick'#0#0#9'TMenuItem'#11'Statistics1'#3'Tag'#2#3#7'Caption'#6#10'Statistic'
+ +'s'#8'ShortCut'#3'D@'#7'OnClick'#7#12'TabMenuClick'#0#0#9'TMenuItem'#14'Func'
+ +'tionalMRI1'#3'Tag'#2#4#7'Caption'#6#14'Functional MRI'#8'ShortCut'#3'E@'#7
+ +'OnClick'#7#12'TabMenuClick'#0#0#9'TMenuItem'#9'Optional1'#3'Tag'#2#5#7'Capt'
+ +'ion'#6#8'Optional'#8'ShortCut'#3'F@'#7'OnClick'#7#12'TabMenuClick'#0#0#0#9
+ +'TMenuItem'#5'Help1'#7'Caption'#6#5'&Help'#0#9'TMenuItem'#6'About1'#7'Captio'
+ +'n'#6#8'About...'#7'OnClick'#7#11'About1Click'#0#0#0#0#11'TOpenDialog'#10'Op'
+ +'enHdrDlg'#11'FilterIndex'#2#0#7'Options'#11#15'ofFileMustExist'#0#4'left'#3
+ +#194#1#3'top'#2#6#0#0#11'TSaveDialog'#10'SaveHdrDlg'#7'OnClose'#7#15'SaveHdr'
+ +'DlgClose'#5'Width'#2'4'#6'Filter'#6'`NIfTI (*.hdr;*.nii)|*.hdr; *.nii|NIfTI'
+ +' separate header (*.hdr)|*.hdr|NIfTI embedded header|*.nii'#11'FilterIndex'
+ +#2#0#4'left'#3#228#1#3'top'#2#6#0#0#0
+]);
\ No newline at end of file
diff --git a/nifti_hdr_view.pas b/nifti_hdr_view.pas
old mode 100644
new mode 100755
index efbe32a..ede1182
--- a/nifti_hdr_view.pas
+++ b/nifti_hdr_view.pas
@@ -699,7 +699,19 @@ begin
{$ENDIF}
NIFTIhdr_ClearHdr(lHdr);
HdrForm.WriteHdrForm (lHdr); //show default header
-
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+ Open1.ShortCut := ShortCut(Word('O'), [ssMeta]);
+ Save1.ShortCut := ShortCut(Word('S'), [ssMeta]);
+ Exit1.ShortCut := ShortCut(Word('W'), [ssMeta]);
+ Dimensions1.ShortCut := ShortCut(Word('A'), [ssMeta]);
+ Rotations1.ShortCut := ShortCut(Word('B'), [ssMeta]);
+ ImageIntensity1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ Statistics1.ShortCut := ShortCut(Word('D'), [ssMeta]);
+ FunctionalMRI1.ShortCut := ShortCut(Word('E'), [ssMeta]);
+ Optional1.ShortCut := ShortCut(Word('F'), [ssMeta]);
+ {$ENDIF}
+ {$ENDIF}
end;
procedure THdrForm.ImageSzChange(Sender: TObject); //report size of image data
@@ -737,4 +749,4 @@ end;
initialization
{$I nifti_hdr_view.lrs}
{$ENDIF}
-end.
+end.
\ No newline at end of file
diff --git a/nifti_img.pas b/nifti_img.pas
old mode 100644
new mode 100755
index f22be60..03c7efc
--- a/nifti_img.pas
+++ b/nifti_img.pas
@@ -11,7 +11,8 @@ RXSpin,capmenu,PNGImage,SSE,ShellAPI,Spin,
{$ENDIF}
SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- Menus, ComCtrls, ExtCtrls, NIFTI_hdr, StdCtrls,Math,
+ Menus, ExtCtrls, NIFTI_hdr, //StdCtrls, ComCtrls,
+Math,
ClipBrd,define_types,
GraphicsMathLibrary,Distr,Stat,ReadInt,gzio2;
const
@@ -35,7 +36,7 @@ Type
//ResizeBeforeRescale - 0=intensity rescale, then resize; 1= nearest neighbor resize, then rescale;1=trilinear resize, then rescale;12:47 PM 7/13/2006
UseReorientHdr,XBarVisible,ThinPen,Mirror,OverlaySmooth,VOIchanged,VOImirrored,
SaveDefaultIni,KnownAlignment,Resliced,
- FlipAx,FlipSag,SingleRow,ResliceOnLoad,Prompt4DVolume,OrthoReslice: boolean;
+ FlipAx,FlipSag,SingleRow,ResliceOnLoad,Prompt4DVolume,OrthoReslice, ShowDraw: boolean;
MinChar,MaxChar: array [1..3] of char; //May07
StretchQuality : TStretchQuality;
VOIClr,XBarClr: TColor;
@@ -1014,8 +1015,8 @@ procedure ComputeTripleZoom;
//values are SHL 10, so a 1% signal change will be 1024
//this preserves precision (though at the moment we round to nearest 1%)
label 543,641;
-const
- kSHval = 1 shl 10;
+//const
+// kSHval = 1 shl 10;
procedure SetPct(lAfrac,lCfrac,lSfrac: single);
begin
ImgForm.PGImageAx.Tag := trunc(lAfrac*100);
@@ -2243,8 +2244,8 @@ begin
end;*)
procedure SaveAsVOIorNIFTI (var lImgBuffer: ByteP; lImgBufferItems, lImgBufferBPP,lnVol: integer; DefaultFormatVOI: boolean; var lNiftiHdr: TNIFTIHdr; lDefFilename: string);
-const
- kImgOffset = 352; //header is 348 bytes, but 352 is diisible by 8...
+//const
+// kImgOffset = 352; //header is 348 bytes, but 352 is diisible by 8...
var
lFileName,lExt: string;
begin
@@ -2306,6 +2307,7 @@ begin
FontSize := 12;
BGTransPct := 0;
LicenseID := 0;
+ ShowDraw := false;
ResliceOnLoad := false;
OrthoReslice := true;
Prompt4DVolume := true;
@@ -4253,10 +4255,10 @@ procedure ResliceScrnImg (var lBGImg: TBGImg; var lHdr: TMRIcroHdr; lTrilinearSm
lOverlap: boolean;
lMinY,lMinZ,lMaxY,lMaxZ: integer; //<- used by trilinear
lXreal,lYreal,lZreal,lXrM1,lYrM1,lZrM1, //<- used by trilinear
- lZr,lYr,lXr,lZx,lZy,lZz,lYx,lYy,lYz,lSwap: single;
+ lZr,lYr,lXr,lZx,lZy,lZz,lYx,lYy,lYz: single;//lSwap
lZ,lY,lX,lOutVolItems,lOutSliceSz,lInVolItems,
lXdimIn,lYDimIn,lZDimIn,lInSliceSz,
- lOutPos,lOutDimX,lOutDimY,lOutDimZ,lSrcPos,lXo,lYo,lZo: integer;
+ lOutPos,lOutDimX,lOutDimY,lOutDimZ,lXo,lYo,lZo: integer;//lSrcPos
lXxp,lXyp,lXzp: Pointer;
lXxra,lXyra,lXzra : SingleP;
lMatrix,lMatrixBG: TMatrix;
@@ -5151,8 +5153,9 @@ var
lReslice,lSwap,lGzipped: boolean;
lWordX: word;
lP05,lP01,lFWE05,lFWE01,lFDR05,lFDR01:single;
+ lMinI,lMaxI,lInc: integer;
lMultiImgSzOff,lMultiImgSz,lOffset,
- lVol,lnVol,lFileSz,lDataType,lInc,lFSz,lImgSamples,lMinI,lMaxI,lRow: Integer;
+ lVol,lnVol,lFileSz,lDataType,lFSz,lImgSamples: Int64; //,lRow
lP: Bytep;
lFName,lExt,lParseName: String;
F: file;
@@ -5219,9 +5222,9 @@ begin
lVol := 1;
if lnVol > 1 then begin
if lOffset < 0 then
- lFileSz := lMultiImgSzOff * {gAHdr.dim[4]}lnVol
+ lFileSz := lMultiImgSzOff * lnVol
else
- lFileSz := ({gAHdr.dim[4]} lnVol * lMultiImgSz) + lOffset;
+ lFileSz := (lnVol * lMultiImgSz) + lOffset;
lVol := 1; //alpha
if {not l4D} lBackgroundImg.Prompt4DVolume then begin
lVol := ReadIntForm.GetInt('Multi-volume file, please select volume to view.',1,1,lnVol);
@@ -5239,10 +5242,10 @@ begin
FileMode := 0; { Set file access to read only }
Reset(F, 1);
if (lGzipped) then begin
- if lOffset < 0 then
- lOffset := abs(lOffset) + (lMultiImgSzOff *(lVol-1))
- else
- lOffset := lOffset + (lMultiImgSz *(lVol-1));
+ if lOffset < 0 then
+ lOffset := abs(lOffset) + (lMultiImgSzOff *(lVol-1))
+ else
+ lOffset := lOffset + (lMultiImgSz *(lVol-1));
end else if lOffset < 0 then
Seek (F,abs(lOffset) + (lMultiImgSzOff *(lVol-1)) )
else
@@ -5252,7 +5255,7 @@ begin
kDT_SIGNED_INT,kDT_FLOAT: lImg2Load.ImgBufferBPP := 4;
kDT_DOUBLE: lImg2Load.ImgBufferBPP := 8;
kDT_UNSIGNED_CHAR : lImg2Load.ImgBufferBPP := 1;
- kDT_RGB: lImg2Load.ImgBufferBPP := 1;//rgb
+ kDT_RGB: lImg2Load.ImgBufferBPP := 1;//rgb
else begin
showmessage('Unable to read this image format '+inttostr(lDataType));
goto 456;
@@ -5285,15 +5288,16 @@ begin
//Next Load Image
if lGzipped then begin
lP := ByteP(lImg2Load.ImgBuffer);
- UnGZip(lFName,{gMultiBuf}lP,lOffset,lMultiImgSz);
+ UnGZip(lFName,lP,lOffset,lMultiImgSz);
end else
BlockRead(F,lImg2Load.ImgBuffer^,lMultiImgSz);
+
if IOResult <> 0 then
ShowMessage('Open image file error: '+inttostr(IOResult));
//Next: prepare image : byte swap, check for special..
case lDataType of
- kDT_RGB: ParseRGB(lImg2Load);//RGB
- kDT_SIGNED_SHORT,kDT_UINT16: begin //16-bit int
+ kDT_RGB: ParseRGB(lImg2Load);//RGB
+ kDT_SIGNED_SHORT,kDT_UINT16: begin //16-bit int
l16Buf := SmallIntP(lImg2Load.ImgBuffer );
if lSwap then
for lInc := 1 to lImgSamples do begin
@@ -5386,7 +5390,9 @@ begin
kDT_UNSIGNED_CHAR : ;
//else will be aborted at previous case
end;//case lDataType of
- if lImg2Load.NIFTIhdr.magic = kNIFTI_MAGIC_DCM then
+ if (lDataType = kDT_RGB) then
+ //do not transform
+ else if lImg2Load.NIFTIhdr.magic = kNIFTI_MAGIC_DCM then
DICOMMirrorImgBuffer(lImg2Load)
else if (lLoadBackground) and (not lReslice) and (lBackgroundImg.KnownAlignment) and (lBackgroundImg.OrthoReslice) then
ReorientToNearestOrtho(lBackgroundImg,lImg2Load,lLoadBackground)
diff --git a/nifti_img_view.lfm b/nifti_img_view.lfm
old mode 100644
new mode 100755
index c5a1eb3..460d63a
--- a/nifti_img_view.lfm
+++ b/nifti_img_view.lfm
@@ -20,7 +20,7 @@ object ImgForm: TImgForm
OnResize = FormResize
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '0.9.30.4'
+ LCLVersion = '1.0.2.0'
object ControlPanel: TPanel
Left = 0
Height = 40
@@ -965,6 +965,8 @@ object ImgForm: TImgForm
Height = 392
Top = 0
Width = 1025
+ HorzScrollBar.Page = 1021
+ VertScrollBar.Page = 388
Align = alClient
ClientHeight = 388
ClientWidth = 1021
@@ -1216,6 +1218,10 @@ object ImgForm: TImgForm
end
object DrawMenu: TMenuItem
Caption = '&Draw'
+ object HideDrawMenuItem: TMenuItem
+ Caption = 'Hide drawing tools'
+ OnClick = ToggleDrawMenu
+ end
object OpenVOI: TMenuItem
Caption = 'Open VOI...'
OnClick = OpenVOIClick
@@ -1425,6 +1431,14 @@ object ImgForm: TImgForm
OnClick = ToolSelectClick
end
end
+ object DrawHiddenMenu: TMenuItem
+ Caption = 'Draw'
+ Visible = False
+ object MenuItem2: TMenuItem
+ Caption = 'Show drawing tools'
+ OnClick = ToggleDrawMenu
+ end
+ end
object Controls1: TMenuItem
Caption = '&View'
object Display2: TMenuItem
diff --git a/nifti_img_view.lrs b/nifti_img_view.lrs
old mode 100644
new mode 100755
index 2815d41..40ed781
--- a/nifti_img_view.lrs
+++ b/nifti_img_view.lrs
@@ -8,7 +8,7 @@ LazarusResources.Add('TImgForm','FORMDATA',[
+#9'FormClose'#8'OnCreate'#7#10'FormCreate'#9'OnDestroy'#7#11'FormDestroy'#11
+'OnDropFiles'#7#13'FormDropFiles'#9'OnKeyDown'#7#11'FormKeyDown'#10'OnKeyPre'
+'ss'#7#12'FormKeyPress'#8'OnResize'#7#10'FormResize'#6'OnShow'#7#8'FormShow'
- +#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#8'0.9.30.4'#0#6'TPanel'#12
+ +#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#7'1.0.2.0'#0#6'TPanel'#12
+'ControlPanel'#4'Left'#2#0#6'Height'#2'('#3'Top'#2#0#5'Width'#3#1#4#5'Align'
+#7#5'alTop'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'('#11'ClientWidth'
+#3#1#4#11'ParentColor'#8#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#0
@@ -868,193 +868,197 @@ LazarusResources.Add('TImgForm','FORMDATA',[
+'Left'#2#0#6'Height'#3#136#1#3'Top'#2'('#5'Width'#3#1#4#5'Align'#7#8'alClien'
+'t'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#3#136#1#11'ClientWidth'#3#1#4
+#8'TabOrder'#2#2#0#10'TScrollBox'#11'TriplePanel'#3'Tag'#3#154#2#4'Left'#2#0
- +#6'Height'#3#136#1#3'Top'#2#0#5'Width'#3#1#4#5'Align'#7#8'alClient'#12'Clien'
- +'tHeight'#3#132#1#11'ClientWidth'#3#253#3#20'Constraints.MinWidth'#2#5#5'Col'
- +'or'#7#7'clBlack'#11'ParentColor'#8#8'TabOrder'#2#0#7'OnClick'#7#13'ImgPanel'
- +'Click'#0#6'TImage'#10'PGImageCor'#3'Tag'#2#2#6'Cursor'#7#7'crCross'#4'Left'
- +#2#1#6'Height'#2#12#3'Top'#2#1#5'Width'#2#12#8'AutoSize'#9#10'OnDblClick'#7
- +#18'PGImageCorDblClick'#11'OnMouseDown'#7#16'PGImageMouseDown'#11'OnMouseMov'
- +'e'#7#16'PGImageMouseMove'#9'OnMouseUp'#7#14'PGImageMouseUp'#7'Stretch'#9#0#0
- +#6'TImage'#10'PGImageSag'#3'Tag'#2#3#6'Cursor'#7#7'crCross'#4'Left'#3'C'#1#6
- +'Height'#2#12#3'Top'#2'n'#5'Width'#2#12#8'AutoSize'#9#10'OnDblClick'#7#18'PG'
- +'ImageCorDblClick'#11'OnMouseDown'#7#16'PGImageMouseDown'#11'OnMouseMove'#7
- +#16'PGImageMouseMove'#9'OnMouseUp'#7#14'PGImageMouseUp'#7'Stretch'#9#0#0#6'T'
- +'Image'#9'PGImageAx'#3'Tag'#2#1#6'Cursor'#7#7'crCross'#4'Left'#3#251#2#6'Hei'
- +'ght'#2#12#3'Top'#3#238#0#5'Width'#2#12#8'AutoSize'#9#10'OnDblClick'#7#18'PG'
- +'ImageCorDblClick'#11'OnMouseDown'#7#16'PGImageMouseDown'#11'OnMouseMove'#7
- +#16'PGImageMouseMove'#9'OnMouseUp'#7#14'PGImageMouseUp'#7'Stretch'#9#0#0#0#0
- +#9'TMainMenu'#9'MainMenu1'#4'left'#2'p'#3'top'#3#212#0#0#9'TMenuItem'#5'File'
- +'1'#7'Caption'#6#5'&File'#0#9'TMenuItem'#5'Open1'#7'Caption'#6#5'&Open'#8'Sh'
- +'ortCut'#3'O@'#7'OnClick'#7#10'Open1Click'#0#0#9'TMenuItem'#7'Recent1'#7'Cap'
- +'tion'#6#12'Open &recent'#0#0#9'TMenuItem'#10'Templates1'#7'Caption'#6#15'Op'
- +'en &templates'#0#0#9'TMenuItem'#11'CloseImages'#7'Caption'#6#13'&Close imag'
- +'es'#7'OnClick'#7#16'CloseImagesClick'#0#0#9'TMenuItem'#12'SaveasNIfTI1'#7'C'
- +'aption'#6#16'Save as NIfTI...'#8'ShortCut'#4'S'#192#0#0#7'OnClick'#7#17'Sav'
- +'easNIfTI1Click'#0#0#9'TMenuItem'#14'Saveaspicture1'#7'Caption'#6#15'&Save a'
- +'s bitmap'#8'ShortCut'#3'S@'#7'OnClick'#7#19'Saveaspicture1Click'#0#0#9'TMen'
- +'uItem'#5'Exit1'#7'Caption'#6#5'E&xit'#7'OnClick'#7#10'Exit1Click'#0#0#0#9'T'
- +'MenuItem'#5'Edit1'#7'Caption'#6#5'&Edit'#0#9'TMenuItem'#5'Copy1'#7'Caption'
- +#6#4'Copy'#8'ShortCut'#3'C@'#7'OnClick'#7#10'Copy1Click'#0#0#9'TMenuItem'#6
- +'Paste1'#7'Caption'#6#5'Paste'#8'ShortCut'#3'V@'#7'OnClick'#7#11'Paste1Click'
- +#0#0#9'TMenuItem'#5'Undo1'#7'Caption'#6#4'Undo'#8'ShortCut'#3'Z@'#7'OnClick'
- ,#7#10'Undo1Click'#0#0#0#9'TMenuItem'#11'OverlayMenu'#7'Caption'#6#8'&Overlay'
- +#0#9'TMenuItem'#11'OverlayOpen'#7'Caption'#6#3'Add'#8'ShortCut'#3'A@'#7'OnCl'
- +'ick'#7#16'OverlayOpenClick'#0#0#9'TMenuItem'#15'CloseOverlayImg'#7'Caption'
- +#6#14'Close overlays'#7'OnClick'#7#20'CloseOverlayImgClick'#0#0#9'TMenuItem'
- +#14'BGTransPctMenu'#7'Caption'#6#26'Transparency on background'#0#9'TMenuIte'
- +'m'#8'BGtrans0'#7'Caption'#6#9'0% opaque'#7'Checked'#9#10'GroupIndex'#3#251#0
- +#9'RadioItem'#9#7'OnClick'#7#15'BGtrans100Click'#0#0#9'TMenuItem'#9'BGtrans2'
- +'0'#3'Tag'#2#20#7'Caption'#6#3'20%'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7
- +'OnClick'#7#15'BGtrans100Click'#0#0#9'TMenuItem'#9'BGtrans40'#3'Tag'#2'('#7
- +'Caption'#6#3'40%'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15'BGt'
- +'rans100Click'#0#0#9'TMenuItem'#9'BGtrans50'#3'Tag'#2'2'#7'Caption'#6#3'50%'
- +#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15'BGtrans100Click'#0#0#9
- +'TMenuItem'#9'BGtrans60'#3'Tag'#2'<'#7'Caption'#6#3'60%'#10'GroupIndex'#3#251
+ +#6'Height'#3#136#1#3'Top'#2#0#5'Width'#3#1#4#18'HorzScrollBar.Page'#3#253#3
+ +#18'VertScrollBar.Page'#3#132#1#5'Align'#7#8'alClient'#12'ClientHeight'#3#132
+ +#1#11'ClientWidth'#3#253#3#20'Constraints.MinWidth'#2#5#5'Color'#7#7'clBlack'
+ +#11'ParentColor'#8#8'TabOrder'#2#0#7'OnClick'#7#13'ImgPanelClick'#0#6'TImage'
+ +#10'PGImageCor'#3'Tag'#2#2#6'Cursor'#7#7'crCross'#4'Left'#2#1#6'Height'#2#12
+ +#3'Top'#2#1#5'Width'#2#12#8'AutoSize'#9#10'OnDblClick'#7#18'PGImageCorDblCli'
+ +'ck'#11'OnMouseDown'#7#16'PGImageMouseDown'#11'OnMouseMove'#7#16'PGImageMous'
+ +'eMove'#9'OnMouseUp'#7#14'PGImageMouseUp'#7'Stretch'#9#0#0#6'TImage'#10'PGIm'
+ +'ageSag'#3'Tag'#2#3#6'Cursor'#7#7'crCross'#4'Left'#3'C'#1#6'Height'#2#12#3'T'
+ +'op'#2'n'#5'Width'#2#12#8'AutoSize'#9#10'OnDblClick'#7#18'PGImageCorDblClick'
+ +#11'OnMouseDown'#7#16'PGImageMouseDown'#11'OnMouseMove'#7#16'PGImageMouseMov'
+ +'e'#9'OnMouseUp'#7#14'PGImageMouseUp'#7'Stretch'#9#0#0#6'TImage'#9'PGImageAx'
+ +#3'Tag'#2#1#6'Cursor'#7#7'crCross'#4'Left'#3#251#2#6'Height'#2#12#3'Top'#3
+ +#238#0#5'Width'#2#12#8'AutoSize'#9#10'OnDblClick'#7#18'PGImageCorDblClick'#11
+ +'OnMouseDown'#7#16'PGImageMouseDown'#11'OnMouseMove'#7#16'PGImageMouseMove'#9
+ +'OnMouseUp'#7#14'PGImageMouseUp'#7'Stretch'#9#0#0#0#0#9'TMainMenu'#9'MainMen'
+ +'u1'#4'left'#2'p'#3'top'#3#212#0#0#9'TMenuItem'#5'File1'#7'Caption'#6#5'&Fil'
+ +'e'#0#9'TMenuItem'#5'Open1'#7'Caption'#6#5'&Open'#8'ShortCut'#3'O@'#7'OnClic'
+ +'k'#7#10'Open1Click'#0#0#9'TMenuItem'#7'Recent1'#7'Caption'#6#12'Open &recen'
+ +'t'#0#0#9'TMenuItem'#10'Templates1'#7'Caption'#6#15'Open &templates'#0#0#9'T'
+ +'MenuItem'#11'CloseImages'#7'Caption'#6#13'&Close images'#7'OnClick'#7#16'Cl'
+ +'oseImagesClick'#0#0#9'TMenuItem'#12'SaveasNIfTI1'#7'Caption'#6#16'Save as N'
+ +'IfTI...'#8'ShortCut'#4'S'#192#0#0#7'OnClick'#7#17'SaveasNIfTI1Click'#0#0#9
+ +'TMenuItem'#14'Saveaspicture1'#7'Caption'#6#15'&Save as bitmap'#8'ShortCut'#3
+ +'S@'#7'OnClick'#7#19'Saveaspicture1Click'#0#0#9'TMenuItem'#5'Exit1'#7'Captio'
+ +'n'#6#5'E&xit'#7'OnClick'#7#10'Exit1Click'#0#0#0#9'TMenuItem'#5'Edit1'#7'Cap'
+ +'tion'#6#5'&Edit'#0#9'TMenuItem'#5'Copy1'#7'Caption'#6#4'Copy'#8'ShortCut'#3
+ +'C@'#7'OnClick'#7#10'Copy1Click'#0#0#9'TMenuItem'#6'Paste1'#7'Caption'#6#5'P'
+ +'aste'#8'ShortCut'#3'V@'#7'OnClick'#7#11'Paste1Click'#0#0#9'TMenuItem'#5'Und'
+ ,'o1'#7'Caption'#6#4'Undo'#8'ShortCut'#3'Z@'#7'OnClick'#7#10'Undo1Click'#0#0#0
+ +#9'TMenuItem'#11'OverlayMenu'#7'Caption'#6#8'&Overlay'#0#9'TMenuItem'#11'Ove'
+ +'rlayOpen'#7'Caption'#6#3'Add'#8'ShortCut'#3'A@'#7'OnClick'#7#16'OverlayOpen'
+ +'Click'#0#0#9'TMenuItem'#15'CloseOverlayImg'#7'Caption'#6#14'Close overlays'
+ +#7'OnClick'#7#20'CloseOverlayImgClick'#0#0#9'TMenuItem'#14'BGTransPctMenu'#7
+ +'Caption'#6#26'Transparency on background'#0#9'TMenuItem'#8'BGtrans0'#7'Capt'
+ +'ion'#6#9'0% opaque'#7'Checked'#9#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'On'
+ +'Click'#7#15'BGtrans100Click'#0#0#9'TMenuItem'#9'BGtrans20'#3'Tag'#2#20#7'Ca'
+ +'ption'#6#3'20%'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15'BGtra'
+ +'ns100Click'#0#0#9'TMenuItem'#9'BGtrans40'#3'Tag'#2'('#7'Caption'#6#3'40%'#10
+ +'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15'BGtrans100Click'#0#0#9'T'
+ +'MenuItem'#9'BGtrans50'#3'Tag'#2'2'#7'Caption'#6#3'50%'#10'GroupIndex'#3#251
+#0#9'RadioItem'#9#7'OnClick'#7#15'BGtrans100Click'#0#0#9'TMenuItem'#9'BGtran'
- +'s80'#3'Tag'#2'P'#7'Caption'#6#3'80%'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7
- +'OnClick'#7#15'BGtrans100Click'#0#0#9'TMenuItem'#10'BGtrans100'#3'Tag'#2'd'#7
- +'Caption'#6#16'100% transparent'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnC'
- +'lick'#7#15'BGtrans100Click'#0#0#9'TMenuItem'#10'BGAdditive'#3'Tag'#2#255#7
- +'Caption'#6#8'Additive'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15
- +'BGtrans100Click'#0#0#0#9'TMenuItem'#19'OverlayTransPctMenu'#7'Caption'#6#30
- +'Transparency on other overlays'#0#9'TMenuItem'#9'N0opaque1'#7'Caption'#6#9
- +'0% opaque'#10'GroupIndex'#3#253#0#9'RadioItem'#9#7'OnClick'#7#17'OverlayTra'
- +'nsClick'#0#0#9'TMenuItem'#4'N201'#3'Tag'#2#20#7'Caption'#6#3'20%'#10'GroupI'
- +'ndex'#3#253#0#9'RadioItem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0#9'TMenu'
- +'Item'#4'N401'#3'Tag'#2'('#7'Caption'#6#3'40%'#10'GroupIndex'#3#253#0#9'Radi'
- +'oItem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0#9'TMenuItem'#4'N501'#3'Tag'
- +#2'2'#7'Caption'#6#3'50%'#10'GroupIndex'#3#253#0#9'RadioItem'#9#7'OnClick'#7
- +#17'OverlayTransClick'#0#0#9'TMenuItem'#4'N601'#3'Tag'#2'<'#7'Caption'#6#3'6'
- +'0%'#10'GroupIndex'#3#253#0#9'RadioItem'#9#7'OnClick'#7#17'OverlayTransClick'
- +#0#0#9'TMenuItem'#4'N801'#3'Tag'#2'P'#7'Caption'#6#3'80%'#10'GroupIndex'#3
- +#253#0#9'RadioItem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0#9'TMenuItem'#16
- +'N100transparent1'#3'Tag'#2'd'#7'Caption'#6#16'100% transparent'#10'GroupInd'
+ +'s60'#3'Tag'#2'<'#7'Caption'#6#3'60%'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7
+ +'OnClick'#7#15'BGtrans100Click'#0#0#9'TMenuItem'#9'BGtrans80'#3'Tag'#2'P'#7
+ +'Caption'#6#3'80%'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15'BGt'
+ +'rans100Click'#0#0#9'TMenuItem'#10'BGtrans100'#3'Tag'#2'd'#7'Caption'#6#16'1'
+ +'00% transparent'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15'BGtr'
+ +'ans100Click'#0#0#9'TMenuItem'#10'BGAdditive'#3'Tag'#2#255#7'Caption'#6#8'Ad'
+ +'ditive'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15'BGtrans100Cli'
+ +'ck'#0#0#0#9'TMenuItem'#19'OverlayTransPctMenu'#7'Caption'#6#30'Transparency'
+ +' on other overlays'#0#9'TMenuItem'#9'N0opaque1'#7'Caption'#6#9'0% opaque'#10
+ +'GroupIndex'#3#253#0#9'RadioItem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0#9
+ +'TMenuItem'#4'N201'#3'Tag'#2#20#7'Caption'#6#3'20%'#10'GroupIndex'#3#253#0#9
+ +'RadioItem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0#9'TMenuItem'#4'N401'#3
+ +'Tag'#2'('#7'Caption'#6#3'40%'#10'GroupIndex'#3#253#0#9'RadioItem'#9#7'OnCli'
+ +'ck'#7#17'OverlayTransClick'#0#0#9'TMenuItem'#4'N501'#3'Tag'#2'2'#7'Caption'
+ +#6#3'50%'#10'GroupIndex'#3#253#0#9'RadioItem'#9#7'OnClick'#7#17'OverlayTrans'
+ +'Click'#0#0#9'TMenuItem'#4'N601'#3'Tag'#2'<'#7'Caption'#6#3'60%'#10'GroupInd'
+'ex'#3#253#0#9'RadioItem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0#9'TMenuIt'
- +'em'#15'OverlayAdditive'#3'Tag'#2#255#7'Caption'#6#8'Additive'#7'Checked'#9
- +#10'GroupIndex'#3#253#0#9'RadioItem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0
- +#0#9'TMenuItem'#9'LayerMenu'#7'Caption'#6#11'Layer color'#7'Visible'#8#0#9'T'
- +'MenuItem'#9'Noneopen1'#7'Caption'#6#9'None open'#0#0#0#9'TMenuItem'#11'Laye'
- +'rrange1'#7'Caption'#6#15'Layer intensity'#7'Visible'#8#0#9'TMenuItem'#9'Non'
- +'eopen2'#7'Caption'#6#9'None open'#0#0#0#0#9'TMenuItem'#8'DrawMenu'#7'Captio'
- +'n'#6#5'&Draw'#0#9'TMenuItem'#7'OpenVOI'#7'Caption'#6#11'Open VOI...'#7'OnCl'
- +'ick'#7#12'OpenVOIClick'#0#0#9'TMenuItem'#7'SaveVOI'#7'Caption'#6#11'Save VO'
- +'I...'#7'OnClick'#7#12'SaveVOIClick'#0#0#9'TMenuItem'#8'CloseVOI'#7'Caption'
- +#6#12'Close VOI...'#7'OnClick'#7#13'CloseVOIClick'#0#0#9'TMenuItem'#8'VOICol'
- +'or'#7'Caption'#6#12'VOI color...'#7'OnClick'#7#13'VOIColorClick'#0#0#9'TMen'
- +'uItem'#29'Applyintensityfiltertovolume1'#7'Caption'#6#19'Intensity filter..'
- +'.'#8'ShortCut'#3'F@'#7'OnClick'#7'"Applyintensityfiltertovolume1Click'#0#0#9
- +'TMenuItem'#10'SmoothVOI1'#7'Caption'#6#13'Smooth VOI...'#7'OnClick'#7#15'Sm'
- +'oothVOI1Click'#0#0#9'TMenuItem'#17'MaskimagewithVOI1'#7'Caption'#6#19'Mask '
- +'image with VOI'#0#9'TMenuItem'#13'VOImaskDelete'#7'Caption'#6#23'Delete reg'
- +'ions with VOI'#7'OnClick'#7#12'VOImaskClick'#0#0#9'TMenuItem'#15'VOImaskPre'
- +'serve'#3'Tag'#2#1#7'Caption'#6#25'Preserve regions with VOI'#7'OnClick'#7#12
- +'VOImaskClick'#0#0#0#9'TMenuItem'#19'Overlaycomparisons1'#7'Caption'#6#19'Ov'
- +'erlay comparisons'#0#9'TMenuItem#IntersectionmutualtoVOIandoverlays1'#7'Cap'
- +'tion'#6#31'Intersection [VOI and overlays]'#7'OnClick'#7#18'ROIcomparisonCl'
- +'ick'#0#0#9'TMenuItem'#19'UnionVOIoroverlays1'#3'Tag'#2#1#7'Caption'#6#23'Un'
- +'ion [VOI or overlays]'#7'OnClick'#7#18'ROIcomparisonClick'#0#0#9'TMenuItem'
- +#22'MaskVOIbutnotoverlays1'#3'Tag'#2#2#7'Caption'#6#27'Mask [VOI but not ove'
- +'rlays]'#7'OnClick'#7#18'ROIcomparisonClick'#0#0#0#9'TMenuItem'#11'Statistic'
- +'s1'#7'Caption'#6#10'Statistics'#0#9'TMenuItem'#5'Beta1'#7'Caption'#6#21'Cre'
- +'ate overlap images'#7'OnClick'#7#13'CreateOverlap'#0#0#9'TMenuItem'#10'Chis'
- +'quare1'#7'Caption'#6#17'Subtraction Plots'#7'OnClick'#7#15'Chisquare1Click'
- +#0#0#9'TMenuItem'#13'BatchROImean1'#7'Caption'#6#18'Batch descriptives'#7'On'
- +'Click'#7#18'BatchROImean1Click'#0#0#9'TMenuItem'#14'Batchprobmaps1'#7'Capti'
- +'on'#6#15'Batch prob maps'#7'OnClick'#7#19'Batchprobmaps1Click'#0#0#9'TMenuI'
- ,'tem/Batchclusterprobmaps1Batchclusterprobmaps1Click'#7'Caption'#6#23'Batch '
- +'cluster prob maps'#7'OnClick'#7'4Batchclusterprobmaps1Batchclusterprobmaps1'
- +'ClickClick'#0#0#0#9'TMenuItem'#8'Convert1'#7'Caption'#6#7'Convert'#0#9'TMen'
- +'uItem'#7'ROIVOI1'#7'Caption'#6#10'ROI -> VOI'#7'OnClick'#7#12'ROIVOI1Click'
- +#0#0#9'TMenuItem'#7'VOI2NII'#7'Caption'#6#10'VOI -> NII'#7'OnClick'#7#12'VOI'
- +'2NIIClick'#0#0#9'TMenuItem'#6'NIIVOI'#7'Caption'#6#10'NII -> VOI'#7'OnClick'
- +#7#11'NIIVOIClick'#0#0#0#9'TMenuItem'#6'Nudge1'#7'Caption'#6#5'Nudge'#0#9'TM'
- +'enuItem'#3'Up1'#7'Caption'#6#4'Left'#7'OnClick'#7#8'Up1Click'#0#0#9'TMenuIt'
- +'em'#5'Left1'#3'Tag'#2#1#7'Caption'#6#5'Right'#7'OnClick'#7#8'Up1Click'#0#0#9
- +'TMenuItem'#6'LeftX1'#3'Tag'#2#2#7'Caption'#6#9'Posterior'#7'OnClick'#7#8'Up'
- +'1Click'#0#0#9'TMenuItem'#7'RightX1'#3'Tag'#2#3#7'Caption'#6#8'Anterior'#7'O'
- +'nClick'#7#8'Up1Click'#0#0#9'TMenuItem'#10'Posterior1'#3'Tag'#2#4#7'Caption'
- +#6#8'Inferior'#7'OnClick'#7#8'Up1Click'#0#0#9'TMenuItem'#10'Posterior2'#3'Ta'
- +'g'#2#5#7'Caption'#6#8'Superior'#7'OnClick'#7#8'Up1Click'#0#0#0#9'TMenuItem'
- +#2'n5'#7'Caption'#6#8'Advanced'#0#9'TMenuItem'#11'RescaleMenu'#7'Caption'#6
- +#14'Phase to rad/S'#7'OnClick'#7#16'RescaleMenuClick'#0#0#9'TMenuItem'#16'Br'
- +'ainExtraction1'#7'Caption'#6#16'Brain extraction'#7'OnClick'#7#12'BETmenuCl'
- +'ick'#0#0#9'TMenuItem'#10'CropEdges1'#7'Caption'#6#10'Crop edges'#7'OnClick'
- +#7#13'CropMenuClick'#0#0#9'TMenuItem'#10'Brainmask1'#7'Caption'#6#11'Brain m'
- +'ask '#7'OnClick'#7#15'BrainMask1Click'#0#0#9'TMenuItem'#25'GenerateSPM5mask'
- +'slesions1'#7'Caption'#6#16'Create SPM5 mask'#7'OnClick'#7#30'GenerateSPM5ma'
- +'skslesions1Click'#0#0#9'TMenuItem'#7'LRFlip1'#7'Caption'#6#7'LR Flip'#7'OnC'
- +'lick'#7#15'MirrorNII1Click'#0#0#9'TMenuItem'#22'ApplyClusterThreshold1'#7'C'
- +'aption'#6#23'Apply cluster threshold'#7'OnClick'#7#27'ApplyClusterThreshold'
- +'1Click'#0#0#9'TMenuItem'#24'ExportasRGBAnalyzeimage1'#7'Caption'#6#19'Expor'
- +'t as RGB image'#7'OnClick'#7#29'ExportasRGBAnalyzeimage1Click'#0#0#9'TMenuI'
- +'tem'#13'Resliceimage1'#7'Caption'#6#14'Reslice images'#7'OnClick'#7#18'Resl'
- +'iceimage1Click'#0#0#9'TMenuItem!AdjustimagessoVOIintensityiszero1'#7'Captio'
- +'n'#6'&Adjust images so VOI intensity is zero'#7'OnClick'#7'&AdjustimagessoV'
- +'OIintensityiszero1Click'#0#0#9'TMenuItem'#8'Extract1'#7'Caption'#6#15'Extra'
- +'ct objects'#7'OnClick'#7#13'Extract1Click'#0#0#0#9'TMenuItem'#19'Descriptiv'
- +'eMenuItem'#7'Caption'#6#11'Descriptive'#7'OnClick'#7#24'DescriptiveMenuItem'
- +'Click'#0#0#9'TMenuItem'#2'N1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#4'Pen1'#3
- +'Tag'#2#2#7'Caption'#6#3'Pen'#8'ShortCut'#2'p'#7'OnClick'#7#15'ToolSelectCli'
- +'ck'#0#0#9'TMenuItem'#13'Penautoclose1'#3'Tag'#2#3#7'Caption'#6#13'Autoclose'
- +' pen'#8'ShortCut'#2'q'#7'OnClick'#7#15'ToolSelectClick'#0#0#9'TMenuItem'#13
- +'CircleSquare1'#3'Tag'#2#4#7'Caption'#6#4'Fill'#8'ShortCut'#2'r'#7'OnClick'#7
- +#15'ToolSelectClick'#0#0#9'TMenuItem'#7'Circle2'#3'Tag'#2#5#7'Caption'#6#6'C'
- +'ircle'#8'ShortCut'#2's'#7'OnClick'#7#15'ToolSelectClick'#0#0#9'TMenuItem'#7
- +'Circle1'#3'Tag'#2#6#7'Caption'#6#14'Deselect tools'#8'ShortCut'#2't'#7'OnCl'
- +'ick'#7#15'ToolSelectClick'#0#0#0#9'TMenuItem'#9'Controls1'#7'Caption'#6#5'&'
- +'View'#0#9'TMenuItem'#8'Display2'#3'Tag'#2#2#7'Caption'#6#7'Display'#0#9'TMe'
- +'nuItem'#6'Axial1'#3'Tag'#2#1#9'AutoCheck'#9#7'Caption'#6#5'Axial'#10'GroupI'
- +'ndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'#0#0#9'TMenuIte'
- +'m'#8'Coronal1'#3'Tag'#2#3#9'AutoCheck'#9#7'Caption'#6#7'Coronal'#10'GroupIn'
- +'dex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'#0#0#9'TMenuItem'
- +#9'Sagittal1'#3'Tag'#2#2#9'AutoCheck'#9#7'Caption'#6#8'Sagittal'#10'GroupInd'
- +'ex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'#0#0#9'TMenuItem'
- +#9'Multiple1'#9'AutoCheck'#9#7'Caption'#6#8'Multiple'#7'Checked'#9#10'GroupI'
- +'ndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'#0#0#9'TMenuIte'
- +'m'#6'Axial2'#3'Tag'#2#255#9'AutoCheck'#9#7'Caption'#6#10'Axial only'#10'Gro'
- +'upIndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'#0#0#9'TMenu'
- +'Item'#8'Coronal2'#3'Tag'#2#253#9'AutoCheck'#9#7'Caption'#6#12'Coronal only'
- +#10'GroupIndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'#0#0#9
- +'TMenuItem'#9'Sagittal2'#3'Tag'#2#254#9'AutoCheck'#9#7'Caption'#6#13'Sagitta'
+ +'em'#4'N801'#3'Tag'#2'P'#7'Caption'#6#3'80%'#10'GroupIndex'#3#253#0#9'RadioI'
+ +'tem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0#9'TMenuItem'#16'N100transpare'
+ +'nt1'#3'Tag'#2'd'#7'Caption'#6#16'100% transparent'#10'GroupIndex'#3#253#0#9
+ +'RadioItem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0#9'TMenuItem'#15'Overlay'
+ +'Additive'#3'Tag'#2#255#7'Caption'#6#8'Additive'#7'Checked'#9#10'GroupIndex'
+ +#3#253#0#9'RadioItem'#9#7'OnClick'#7#17'OverlayTransClick'#0#0#0#9'TMenuItem'
+ +#9'LayerMenu'#7'Caption'#6#11'Layer color'#7'Visible'#8#0#9'TMenuItem'#9'Non'
+ +'eopen1'#7'Caption'#6#9'None open'#0#0#0#9'TMenuItem'#11'Layerrange1'#7'Capt'
+ +'ion'#6#15'Layer intensity'#7'Visible'#8#0#9'TMenuItem'#9'Noneopen2'#7'Capti'
+ +'on'#6#9'None open'#0#0#0#0#9'TMenuItem'#8'DrawMenu'#7'Caption'#6#5'&Draw'#0
+ +#9'TMenuItem'#16'HideDrawMenuItem'#7'Caption'#6#18'Hide drawing tools'#7'OnC'
+ +'lick'#7#14'ToggleDrawMenu'#0#0#9'TMenuItem'#7'OpenVOI'#7'Caption'#6#11'Open'
+ +' VOI...'#7'OnClick'#7#12'OpenVOIClick'#0#0#9'TMenuItem'#7'SaveVOI'#7'Captio'
+ +'n'#6#11'Save VOI...'#7'OnClick'#7#12'SaveVOIClick'#0#0#9'TMenuItem'#8'Close'
+ +'VOI'#7'Caption'#6#12'Close VOI...'#7'OnClick'#7#13'CloseVOIClick'#0#0#9'TMe'
+ +'nuItem'#8'VOIColor'#7'Caption'#6#12'VOI color...'#7'OnClick'#7#13'VOIColorC'
+ +'lick'#0#0#9'TMenuItem'#29'Applyintensityfiltertovolume1'#7'Caption'#6#19'In'
+ +'tensity filter...'#8'ShortCut'#3'F@'#7'OnClick'#7'"Applyintensityfiltertovo'
+ +'lume1Click'#0#0#9'TMenuItem'#10'SmoothVOI1'#7'Caption'#6#13'Smooth VOI...'#7
+ +'OnClick'#7#15'SmoothVOI1Click'#0#0#9'TMenuItem'#17'MaskimagewithVOI1'#7'Cap'
+ +'tion'#6#19'Mask image with VOI'#0#9'TMenuItem'#13'VOImaskDelete'#7'Caption'
+ +#6#23'Delete regions with VOI'#7'OnClick'#7#12'VOImaskClick'#0#0#9'TMenuItem'
+ +#15'VOImaskPreserve'#3'Tag'#2#1#7'Caption'#6#25'Preserve regions with VOI'#7
+ +'OnClick'#7#12'VOImaskClick'#0#0#0#9'TMenuItem'#19'Overlaycomparisons1'#7'Ca'
+ +'ption'#6#19'Overlay comparisons'#0#9'TMenuItem#IntersectionmutualtoVOIandov'
+ +'erlays1'#7'Caption'#6#31'Intersection [VOI and overlays]'#7'OnClick'#7#18'R'
+ +'OIcomparisonClick'#0#0#9'TMenuItem'#19'UnionVOIoroverlays1'#3'Tag'#2#1#7'Ca'
+ +'ption'#6#23'Union [VOI or overlays]'#7'OnClick'#7#18'ROIcomparisonClick'#0#0
+ +#9'TMenuItem'#22'MaskVOIbutnotoverlays1'#3'Tag'#2#2#7'Caption'#6#27'Mask [VO'
+ +'I but not overlays]'#7'OnClick'#7#18'ROIcomparisonClick'#0#0#0#9'TMenuItem'
+ +#11'Statistics1'#7'Caption'#6#10'Statistics'#0#9'TMenuItem'#5'Beta1'#7'Capti'
+ +'on'#6#21'Create overlap images'#7'OnClick'#7#13'CreateOverlap'#0#0#9'TMenuI'
+ +'tem'#10'Chisquare1'#7'Caption'#6#17'Subtraction Plots'#7'OnClick'#7#15'Chis'
+ +'quare1Click'#0#0#9'TMenuItem'#13'BatchROImean1'#7'Caption'#6#18'Batch descr'
+ ,'iptives'#7'OnClick'#7#18'BatchROImean1Click'#0#0#9'TMenuItem'#14'Batchprobm'
+ +'aps1'#7'Caption'#6#15'Batch prob maps'#7'OnClick'#7#19'Batchprobmaps1Click'
+ +#0#0#9'TMenuItem/Batchclusterprobmaps1Batchclusterprobmaps1Click'#7'Caption'
+ +#6#23'Batch cluster prob maps'#7'OnClick'#7'4Batchclusterprobmaps1Batchclust'
+ +'erprobmaps1ClickClick'#0#0#0#9'TMenuItem'#8'Convert1'#7'Caption'#6#7'Conver'
+ +'t'#0#9'TMenuItem'#7'ROIVOI1'#7'Caption'#6#10'ROI -> VOI'#7'OnClick'#7#12'RO'
+ +'IVOI1Click'#0#0#9'TMenuItem'#7'VOI2NII'#7'Caption'#6#10'VOI -> NII'#7'OnCli'
+ +'ck'#7#12'VOI2NIIClick'#0#0#9'TMenuItem'#6'NIIVOI'#7'Caption'#6#10'NII -> VO'
+ +'I'#7'OnClick'#7#11'NIIVOIClick'#0#0#0#9'TMenuItem'#6'Nudge1'#7'Caption'#6#5
+ +'Nudge'#0#9'TMenuItem'#3'Up1'#7'Caption'#6#4'Left'#7'OnClick'#7#8'Up1Click'#0
+ +#0#9'TMenuItem'#5'Left1'#3'Tag'#2#1#7'Caption'#6#5'Right'#7'OnClick'#7#8'Up1'
+ +'Click'#0#0#9'TMenuItem'#6'LeftX1'#3'Tag'#2#2#7'Caption'#6#9'Posterior'#7'On'
+ +'Click'#7#8'Up1Click'#0#0#9'TMenuItem'#7'RightX1'#3'Tag'#2#3#7'Caption'#6#8
+ +'Anterior'#7'OnClick'#7#8'Up1Click'#0#0#9'TMenuItem'#10'Posterior1'#3'Tag'#2
+ +#4#7'Caption'#6#8'Inferior'#7'OnClick'#7#8'Up1Click'#0#0#9'TMenuItem'#10'Pos'
+ +'terior2'#3'Tag'#2#5#7'Caption'#6#8'Superior'#7'OnClick'#7#8'Up1Click'#0#0#0
+ +#9'TMenuItem'#2'n5'#7'Caption'#6#8'Advanced'#0#9'TMenuItem'#11'RescaleMenu'#7
+ +'Caption'#6#14'Phase to rad/S'#7'OnClick'#7#16'RescaleMenuClick'#0#0#9'TMenu'
+ +'Item'#16'BrainExtraction1'#7'Caption'#6#16'Brain extraction'#7'OnClick'#7#12
+ +'BETmenuClick'#0#0#9'TMenuItem'#10'CropEdges1'#7'Caption'#6#10'Crop edges'#7
+ +'OnClick'#7#13'CropMenuClick'#0#0#9'TMenuItem'#10'Brainmask1'#7'Caption'#6#11
+ +'Brain mask '#7'OnClick'#7#15'BrainMask1Click'#0#0#9'TMenuItem'#25'GenerateS'
+ +'PM5maskslesions1'#7'Caption'#6#16'Create SPM5 mask'#7'OnClick'#7#30'Generat'
+ +'eSPM5maskslesions1Click'#0#0#9'TMenuItem'#7'LRFlip1'#7'Caption'#6#7'LR Flip'
+ +#7'OnClick'#7#15'MirrorNII1Click'#0#0#9'TMenuItem'#22'ApplyClusterThreshold1'
+ +#7'Caption'#6#23'Apply cluster threshold'#7'OnClick'#7#27'ApplyClusterThresh'
+ +'old1Click'#0#0#9'TMenuItem'#24'ExportasRGBAnalyzeimage1'#7'Caption'#6#19'Ex'
+ +'port as RGB image'#7'OnClick'#7#29'ExportasRGBAnalyzeimage1Click'#0#0#9'TMe'
+ +'nuItem'#13'Resliceimage1'#7'Caption'#6#14'Reslice images'#7'OnClick'#7#18'R'
+ +'esliceimage1Click'#0#0#9'TMenuItem!AdjustimagessoVOIintensityiszero1'#7'Cap'
+ +'tion'#6'&Adjust images so VOI intensity is zero'#7'OnClick'#7'&Adjustimages'
+ +'soVOIintensityiszero1Click'#0#0#9'TMenuItem'#8'Extract1'#7'Caption'#6#15'Ex'
+ +'tract objects'#7'OnClick'#7#13'Extract1Click'#0#0#0#9'TMenuItem'#19'Descrip'
+ +'tiveMenuItem'#7'Caption'#6#11'Descriptive'#7'OnClick'#7#24'DescriptiveMenuI'
+ +'temClick'#0#0#9'TMenuItem'#2'N1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#4'Pen1'
+ +#3'Tag'#2#2#7'Caption'#6#3'Pen'#8'ShortCut'#2'p'#7'OnClick'#7#15'ToolSelectC'
+ +'lick'#0#0#9'TMenuItem'#13'Penautoclose1'#3'Tag'#2#3#7'Caption'#6#13'Autoclo'
+ +'se pen'#8'ShortCut'#2'q'#7'OnClick'#7#15'ToolSelectClick'#0#0#9'TMenuItem'
+ +#13'CircleSquare1'#3'Tag'#2#4#7'Caption'#6#4'Fill'#8'ShortCut'#2'r'#7'OnClic'
+ +'k'#7#15'ToolSelectClick'#0#0#9'TMenuItem'#7'Circle2'#3'Tag'#2#5#7'Caption'#6
+ +#6'Circle'#8'ShortCut'#2's'#7'OnClick'#7#15'ToolSelectClick'#0#0#9'TMenuItem'
+ +#7'Circle1'#3'Tag'#2#6#7'Caption'#6#14'Deselect tools'#8'ShortCut'#2't'#7'On'
+ +'Click'#7#15'ToolSelectClick'#0#0#0#9'TMenuItem'#14'DrawHiddenMenu'#7'Captio'
+ +'n'#6#4'Draw'#7'Visible'#8#0#9'TMenuItem'#9'MenuItem2'#7'Caption'#6#18'Show '
+ +'drawing tools'#7'OnClick'#7#14'ToggleDrawMenu'#0#0#0#9'TMenuItem'#9'Control'
+ +'s1'#7'Caption'#6#5'&View'#0#9'TMenuItem'#8'Display2'#3'Tag'#2#2#7'Caption'#6
+ +#7'Display'#0#9'TMenuItem'#6'Axial1'#3'Tag'#2#1#9'AutoCheck'#9#7'Caption'#6#5
+ +'Axial'#10'GroupIndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'
+ +#0#0#9'TMenuItem'#8'Coronal1'#3'Tag'#2#3#9'AutoCheck'#9#7'Caption'#6#7'Coron'
+ +'al'#10'GroupIndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'#0
+ +#0#9'TMenuItem'#9'Sagittal1'#3'Tag'#2#2#9'AutoCheck'#9#7'Caption'#6#8'Sagitt'
+ +'al'#10'GroupIndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'#0
+ +#0#9'TMenuItem'#9'Multiple1'#9'AutoCheck'#9#7'Caption'#6#8'Multiple'#7'Check'
+ +'ed'#9#10'GroupIndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Click'
+ +#0#0#9'TMenuItem'#6'Axial2'#3'Tag'#2#255#9'AutoCheck'#9#7'Caption'#6#10'Axia'
+'l only'#10'GroupIndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagittal1Clic'
- +'k'#0#0#0#9'TMenuItem'#2'N3'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#12'Quicksmoo'
- +'th1'#7'Caption'#6#20'3D Smooth background'#7'OnClick'#7#17'Quicksmooth1Clic'
- +'k'#0#0#9'TMenuItem'#17'OverlaySmoothMenu'#7'Caption'#6#18'3D Smooth overlay'
- +'s'#7'OnClick'#7#22'OverlaySmoothMenuClick'#0#0#9'TMenuItem'#12'Menu2DSmooth'
- +#7'Caption'#6#13'2D Smooth all'#7'Checked'#9#7'OnClick'#7#17'Menu2DSmoothCli'
- +'ck'#0#0#9'TMenuItem'#2'N4'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#10'FlipLRmenu'
- +#7'Caption'#6#8'Flip L/R'#7'OnClick'#7#15'FlipLRmenuClick'#0#0#9'TMenuItem'#8
- +'YokeMenu'#7'Caption'#6#4'Yoke'#8'ShortCut'#3'Y@'#7'OnClick'#7#13'YokeMenuCl'
- ,'ick'#0#0#9'TMenuItem'#2'N2'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#15'MagnifyMe'
- +'nuItem'#7'Caption'#6#7'Magnify'#7'OnClick'#7#20'MagnifyMenuItemClick'#0#0#9
- +'TMenuItem'#10'Crosshair1'#7'Caption'#6#9'Crosshair'#7'OnClick'#7#15'ToolSel'
- +'ectClick'#0#0#9'TMenuItem'#9'MenuItem1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#7
- +'MNIMenu'#7'Caption'#6#15'MNI coordinates'#7'OnClick'#7#12'MNIMenuClick'#0#0
- +#9'TMenuItem'#10'Landmarks1'#7'Caption'#6#9'Landmarks'#7'OnClick'#7#15'Landm'
- +'arks1Click'#0#0#0#9'TMenuItem'#8'Display1'#7'Caption'#6#6'Window'#0#9'TMenu'
- +'Item'#10'ShowRender'#7'Caption'#6#6'Render'#8'ShortCut'#3'R@'#7'OnClick'#7
- +#15'ShowRenderClick'#0#0#9'TMenuItem'#14'ShowMultislice'#7'Caption'#6#10'Mul'
- +'tislice'#8'ShortCut'#3'M@'#7'OnClick'#7#19'ShowMultisliceClick'#0#0#9'TMenu'
- +'Item'#9'HistoMenu'#7'Caption'#6#9'Histogram'#8'ShortCut'#3'H@'#7'OnClick'#7
- +#14'HistoMenuClick'#0#0#9'TMenuItem'#10'N4DTraces1'#7'Caption'#6#9'4D Traces'
- +#8'ShortCut'#3'D@'#7'OnClick'#7#15'N4DTraces1Click'#0#0#9'TMenuItem'#7'Heade'
- +'r1'#7'Caption'#6#11'Information'#8'ShortCut'#3'I@'#7'OnClick'#7#12'Header1C'
- +'lick'#0#0#0#9'TMenuItem'#5'Help1'#7'Caption'#6#5'&Help'#0#9'TMenuItem'#12'P'
- +'references1'#7'Caption'#6#14'Preferences...'#7'OnClick'#7#17'Preferences1Cl'
- +'ick'#0#0#9'TMenuItem'#6'About1'#7'Caption'#6#5'About'#7'OnClick'#7#11'About'
- +'1Click'#0#0#0#0#11'TSaveDialog'#11'SaveDialog1'#7'OnClose'#7#16'SaveDialog1'
- +'Close'#10'DefaultExt'#6#4'.bmp'#6'Filter'#6#11'Bitmap|.bmp'#11'FilterIndex'
- +#2#0#4'left'#2#18#3'top'#3#212#0#0#0#12'TColorDialog'#12'ColorDialog1'#5'Col'
- +'or'#7#7'clBlack'#20'CustomColors.Strings'#1#6#13'ColorA=000000'#6#13'ColorB'
- +'=000080'#6#13'ColorC=008000'#6#13'ColorD=008080'#6#13'ColorE=800000'#6#13'C'
- +'olorF=800080'#6#13'ColorG=808000'#6#13'ColorH=808080'#6#13'ColorI=C0C0C0'#6
- +#13'ColorJ=0000FF'#6#13'ColorK=00FF00'#6#13'ColorL=00FFFF'#6#13'ColorM=FF000'
- +'0'#6#13'ColorN=FF00FF'#6#13'ColorO=FFFF00'#6#13'ColorP=FFFFFF'#6#13'ColorQ='
- +'C0DCC0'#6#13'ColorR=F0CAA6'#6#13'ColorS=F0FBFF'#6#13'ColorT=A4A0A0'#0#4'lef'
- +'t'#2'2'#3'top'#3#212#0#0#0#6'TTimer'#18'RefreshImagesTimer'#7'Enabled'#8#8
- +'Interval'#2#20#7'OnTimer'#7#23'RefreshImagesTimerTimer'#4'left'#2'R'#3'top'
- +#3#212#0#0#0#6'TTimer'#18'RescaleImagesTimer'#7'Enabled'#8#8'Interval'#2'2'#7
- +'OnTimer'#7#23'RescaleImagesTimerTimer'#4'left'#3#178#0#3'top'#3#212#0#0#0#6
- +'TTimer'#9'YokeTimer'#7'Enabled'#8#8'Interval'#3#200#0#7'OnTimer'#7#14'YokeT'
- +'imerTimer'#4'left'#3#24#1#3'top'#3#8#1#0#0#0
+ +'k'#0#0#9'TMenuItem'#8'Coronal2'#3'Tag'#2#253#9'AutoCheck'#9#7'Caption'#6#12
+ +'Coronal only'#10'GroupIndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14'Sagitta'
+ +'l1Click'#0#0#9'TMenuItem'#9'Sagittal2'#3'Tag'#2#254#9'AutoCheck'#9#7'Captio'
+ +'n'#6#13'Sagittal only'#10'GroupIndex'#3#234#0#9'RadioItem'#9#7'OnClick'#7#14
+ +'Sagittal1Click'#0#0#0#9'TMenuItem'#2'N3'#7'Caption'#6#1'-'#0#0#9'TMenuItem'
+ +#12'Quicksmooth1'#7'Caption'#6#20'3D Smooth background'#7'OnClick'#7#17'Quic'
+ +'ksmooth1Click'#0#0#9'TMenuItem'#17'OverlaySmoothMenu'#7'Caption'#6#18'3D Sm'
+ +'ooth overlays'#7'OnClick'#7#22'OverlaySmoothMenuClick'#0#0#9'TMenuItem'#12
+ ,'Menu2DSmooth'#7'Caption'#6#13'2D Smooth all'#7'Checked'#9#7'OnClick'#7#17'M'
+ +'enu2DSmoothClick'#0#0#9'TMenuItem'#2'N4'#7'Caption'#6#1'-'#0#0#9'TMenuItem'
+ +#10'FlipLRmenu'#7'Caption'#6#8'Flip L/R'#7'OnClick'#7#15'FlipLRmenuClick'#0#0
+ +#9'TMenuItem'#8'YokeMenu'#7'Caption'#6#4'Yoke'#8'ShortCut'#3'Y@'#7'OnClick'#7
+ +#13'YokeMenuClick'#0#0#9'TMenuItem'#2'N2'#7'Caption'#6#1'-'#0#0#9'TMenuItem'
+ +#15'MagnifyMenuItem'#7'Caption'#6#7'Magnify'#7'OnClick'#7#20'MagnifyMenuItem'
+ +'Click'#0#0#9'TMenuItem'#10'Crosshair1'#7'Caption'#6#9'Crosshair'#7'OnClick'
+ +#7#15'ToolSelectClick'#0#0#9'TMenuItem'#9'MenuItem1'#7'Caption'#6#1'-'#0#0#9
+ +'TMenuItem'#7'MNIMenu'#7'Caption'#6#15'MNI coordinates'#7'OnClick'#7#12'MNIM'
+ +'enuClick'#0#0#9'TMenuItem'#10'Landmarks1'#7'Caption'#6#9'Landmarks'#7'OnCli'
+ +'ck'#7#15'Landmarks1Click'#0#0#0#9'TMenuItem'#8'Display1'#7'Caption'#6#6'Win'
+ +'dow'#0#9'TMenuItem'#10'ShowRender'#7'Caption'#6#6'Render'#8'ShortCut'#3'R@'
+ +#7'OnClick'#7#15'ShowRenderClick'#0#0#9'TMenuItem'#14'ShowMultislice'#7'Capt'
+ +'ion'#6#10'Multislice'#8'ShortCut'#3'M@'#7'OnClick'#7#19'ShowMultisliceClick'
+ +#0#0#9'TMenuItem'#9'HistoMenu'#7'Caption'#6#9'Histogram'#8'ShortCut'#3'H@'#7
+ +'OnClick'#7#14'HistoMenuClick'#0#0#9'TMenuItem'#10'N4DTraces1'#7'Caption'#6#9
+ +'4D Traces'#8'ShortCut'#3'D@'#7'OnClick'#7#15'N4DTraces1Click'#0#0#9'TMenuIt'
+ +'em'#7'Header1'#7'Caption'#6#11'Information'#8'ShortCut'#3'I@'#7'OnClick'#7
+ +#12'Header1Click'#0#0#0#9'TMenuItem'#5'Help1'#7'Caption'#6#5'&Help'#0#9'TMen'
+ +'uItem'#12'Preferences1'#7'Caption'#6#14'Preferences...'#7'OnClick'#7#17'Pre'
+ +'ferences1Click'#0#0#9'TMenuItem'#6'About1'#7'Caption'#6#5'About'#7'OnClick'
+ +#7#11'About1Click'#0#0#0#0#11'TSaveDialog'#11'SaveDialog1'#7'OnClose'#7#16'S'
+ +'aveDialog1Close'#10'DefaultExt'#6#4'.bmp'#6'Filter'#6#11'Bitmap|.bmp'#11'Fi'
+ +'lterIndex'#2#0#4'left'#2#18#3'top'#3#212#0#0#0#12'TColorDialog'#12'ColorDia'
+ +'log1'#5'Color'#7#7'clBlack'#20'CustomColors.Strings'#1#6#13'ColorA=000000'#6
+ +#13'ColorB=000080'#6#13'ColorC=008000'#6#13'ColorD=008080'#6#13'ColorE=80000'
+ +'0'#6#13'ColorF=800080'#6#13'ColorG=808000'#6#13'ColorH=808080'#6#13'ColorI='
+ +'C0C0C0'#6#13'ColorJ=0000FF'#6#13'ColorK=00FF00'#6#13'ColorL=00FFFF'#6#13'Co'
+ +'lorM=FF0000'#6#13'ColorN=FF00FF'#6#13'ColorO=FFFF00'#6#13'ColorP=FFFFFF'#6
+ +#13'ColorQ=C0DCC0'#6#13'ColorR=F0CAA6'#6#13'ColorS=F0FBFF'#6#13'ColorT=A4A0A'
+ +'0'#0#4'left'#2'2'#3'top'#3#212#0#0#0#6'TTimer'#18'RefreshImagesTimer'#7'Ena'
+ +'bled'#8#8'Interval'#2#20#7'OnTimer'#7#23'RefreshImagesTimerTimer'#4'left'#2
+ +'R'#3'top'#3#212#0#0#0#6'TTimer'#18'RescaleImagesTimer'#7'Enabled'#8#8'Inter'
+ +'val'#2'2'#7'OnTimer'#7#23'RescaleImagesTimerTimer'#4'left'#3#178#0#3'top'#3
+ +#212#0#0#0#6'TTimer'#9'YokeTimer'#7'Enabled'#8#8'Interval'#3#200#0#7'OnTimer'
+ +#7#14'YokeTimerTimer'#4'left'#3#24#1#3'top'#3#8#1#0#0#0
]);
diff --git a/nifti_img_view.pas b/nifti_img_view.pas
old mode 100644
new mode 100755
index b79b03d..93c07dc
--- a/nifti_img_view.pas
+++ b/nifti_img_view.pas
@@ -51,6 +51,9 @@ Axial2: TMenuItem;
Coronal2: TMenuItem;
Landmarks1: TMenuItem;
Extract1: TMenuItem;
+HideDrawMenuItem: TMenuItem;
+DrawHiddenMenu: TMenuItem;
+MenuItem2: TMenuItem;
Sagittal2: TMenuItem;
Sagittal1: TMenuItem;
Multiple1: TMenuItem;
@@ -185,6 +188,7 @@ MNIMenu: TMenuItem;
Posterior2: TMenuItem;
YokeMenu: TMenuItem;
procedure Extract1Click(Sender: TObject);
+ procedure ToggleDrawMenu(Sender: TObject);
procedure SaveVOIcore(lPromptFilename: boolean);
procedure FormOpenFileMethod(const FileName : string);
procedure Landmarks1Click(Sender: TObject);
@@ -572,7 +576,7 @@ begin
//Booleans
lIniFile.WriteString('BOOL', 'Reslice',Bool2Char(gBGImg.ResliceOnLoad));
lIniFile.WriteString('BOOL', 'ResliceOrtho',Bool2Char(gBGImg.OrthoReslice));
- lIniFile.WriteString('BOOL', 'ShowDraw',Bool2Char(ToolPanel.Visible));
+ lIniFile.WriteString('BOOL', 'ShowDraw',Bool2Char(gBGImg.ShowDraw));
lIniFile.WriteString('BOOL', 'ThinPen',Bool2Char(gBGImg.ThinPen));
lIniFile.WriteString('BOOL', 'Smooth2D',Bool2Char(Menu2DSmooth.checked));
lIniFile.WriteString('BOOL', 'XBar',Bool2Char(XBarBtn.Down));
@@ -647,6 +651,13 @@ begin
myreg.free;
end;
+procedure WriteIni2Form (lBGImg: TBGImg);
+begin
+ ImgForm.ToolPanel.Visible := lBGImg.ShowDraw;
+ ImgForm.DrawMenu.Visible := lBGImg.ShowDraw;
+ ImgForm.DrawHiddenMenu.Visible := not lBGImg.ShowDraw;
+end;
+
procedure TImgForm.SetIniMenus;
begin
XBarBtn.Down := gBGImg.XBarVisible;
@@ -687,8 +698,8 @@ begin
gBGImg.ResliceOnLoad := IniBool(lIniFile,'Reslice',gBGImg.ResliceOnLoad);
gBGImg.OrthoReslice := IniBool(lIniFile,'ResliceOrtho',gBGImg.OrthoReslice);
gBGImg.ThinPen := IniBool(lIniFile, 'ThinPen',True);
- ToolPanel.Visible := IniBool(lIniFile, 'ShowDraw',True);
- DrawMenu.Visible := ToolPanel.visible;
+ gBGImg.ShowDraw := IniBool(lIniFile, 'ShowDraw',gBGImg.ShowDraw);
+ WriteIni2Form(gBGImg);
if IniBool(lIniFile,'Smooth2D',Menu2DSmooth.checked) then
gBGImg.StretchQuality := sqHigh
else
@@ -1388,12 +1399,16 @@ begin
XViewEdit.MaxValue := gBGImg.ScrnDim[1];//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[1];
YViewEdit.MaxValue := gBGImg.ScrnDim[2];//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[2];
ZViewEdit.MaxValue :=gBGImg.ScrnDim[3];// gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[3];
- XViewEdit.Value := round(gBGImg.ScrnOri[1]);//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[1] div 2;
+ (*XViewEdit.Value := round(gBGImg.ScrnOri[1]);//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[1] div 2;
YViewEdit.Value := round(gBGImg.ScrnOri[2]);//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[2]div 2;
lVal := round(gBGImg.ScrnOri[3]);
if lVal < 1 then
lVal := 1;
- ZViewEdit.Value := lVal;//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[3] div 2;
+ ZViewEdit.Value := lVal;//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[3] div 2;*)
+
+ XViewEdit.Value := Bound ( round(gBGImg.ScrnOri[1]),1,round(XViewEdit.MaxValue));
+ YViewEdit.Value := Bound ( round(gBGImg.ScrnOri[2]),1,round(YViewEdit.MaxValue));
+ ZViewEdit.Value := Bound ( round(gBGImg.ScrnOri[3]),1,round(ZViewEdit.MaxValue));
ImgForm.Caption := extractfilename(paramstr(0))+' - '+lFilename;
StatusLabel.caption := 'opened: '+lFilename;
Result := true;
@@ -3292,6 +3307,12 @@ begin
end;
end;
+procedure TImgForm.ToggleDrawMenu(Sender: TObject);
+begin
+ gBGImg.ShowDraw := not DrawMenu.Visible;
+ WriteIni2Form(gBGImg);
+end;
+
procedure TImgForm.SaveVOIClick(Sender: TObject);
var lHdr: TMRIcroHdr;
lNIFTIhdr: TNIFTIhdr;
diff --git a/niftiview.ico b/niftiview.ico
old mode 100644
new mode 100755
diff --git a/npm/Copy of npm.cfg b/npm/Copy of npm.cfg
old mode 100644
new mode 100755
diff --git a/npm/Copy of prefs.pas b/npm/Copy of prefs.pas
old mode 100644
new mode 100755
diff --git a/npm/Copy of turbolesion.pas b/npm/Copy of turbolesion.pas
old mode 100644
new mode 100755
diff --git a/npm/LesionStatThds.pas b/npm/LesionStatThds.pas
old mode 100644
new mode 100755
index 1679d2e..00f59aa
--- a/npm/LesionStatThds.pas
+++ b/npm/LesionStatThds.pas
@@ -1,10 +1,12 @@
unit LesionStatThds;
-
+{$Include ..\common\isgui.inc}
interface
uses
- SysUtils,
- ComCtrls,Classes, Graphics, ExtCtrls, define_types,stats,StatThdsUtil,Brunner,lesion_pattern;
+ // ComCtrls,Classes, Graphics, ExtCtrls,
+ {$IFDEF GUI} ComCtrls,{$ENDIF}
+ SysUtils, Classes, dialogsx,
+ define_types,stats,StatThdsUtil,Brunner,lesion_pattern;
@@ -25,6 +27,7 @@ type
procedure VisualProg(lPos: Integer);
procedure Analyze(lttest,lBM: boolean; lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount,lControlsIn : integer; lPlankImg:bytep;lOutImgMn,lOutImgBM,lOutImgT,lOutImgAUC,lSymptomRA: SingleP); virtual; abstract;
public
+ property Terminated;
constructor Create(lBar: TProgressBar;lttest,lBM: boolean; lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount,lControlsIn : integer; lPlankImg:ByteP;lOutImgMn,lOutImgBM,lOutImgT,lOutImgAUC,lSymptomRA: SingleP);
end;
@@ -187,7 +190,8 @@ end;
constructor TLesionStatThread .Create(lBar: TProgressBar; lttest,lBM: boolean; lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount,lControlsIn : integer; lPlankImg: byteP;lOutImgMn,lOutImgBM,lOutImgT,lOutImgAUC,lSymptomRA: SingleP);
begin
- lBarX := lBar;
+
+ lBarX := lBar;
lttestx := lttest;
lBMx:= lBM;
lThreadX := lThread;
@@ -207,6 +211,7 @@ begin
lnCritX := lnCrit;
FreeOnTerminate := True;
inherited Create(False);
+ //inherited Create(CreateSuspended);
end;
{ The Execute method is called when the thread starts }
@@ -214,6 +219,7 @@ end;
procedure TLesionStatThread .Execute;
begin
Analyze(lttestx,lBMx, lnCritX,lnPermuteX,lThreadx,lThreadStartx,lThreadEndx,lStartVoxx,lVoxPerPlankx,lImagesCountx,lControlsx,lPlankImgX,lOutImgMnx,lOutImgBMx,lOutImgTx,lOutImgAUCx,lSymptomRAx);
+
end;
@@ -444,4 +450,4 @@ begin //Binomial StatThread
freemem(lLesionOrderp)
end;
-end.
+end.
\ No newline at end of file
diff --git a/npm/Mat.pas b/npm/Mat.pas
old mode 100644
new mode 100755
index d238441..020cb09
--- a/npm/Mat.pas
+++ b/npm/Mat.pas
@@ -6,7 +6,7 @@ unit Mat;
interface
-Uses SysUtils, Classes, Vector,dialogs;
+Uses SysUtils, Classes, Vector,dialogsx;
//var gMat: boolean = false;
type EMatrixError = class (Exception);
@@ -2393,4 +2393,4 @@ begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/npm/ReadFloat.dfm b/npm/ReadFloat.dfm
old mode 100644
new mode 100755
diff --git a/npm/ReadFloat.pas b/npm/ReadFloat.pas
old mode 100644
new mode 100755
diff --git a/npm/ReadInt.dfm b/npm/ReadInt.dfm
old mode 100644
new mode 100755
diff --git a/npm/ReadInt.lfm b/npm/ReadInt.lfm
old mode 100644
new mode 100755
diff --git a/npm/ReadInt.lrs b/npm/ReadInt.lrs
old mode 100644
new mode 100755
diff --git a/npm/ReadInt.pas b/npm/ReadInt.pas
old mode 100644
new mode 100755
diff --git a/npm/StatThds.pas b/npm/StatThds.pas
old mode 100644
new mode 100755
index afd7927..613748c
--- a/npm/StatThds.pas
+++ b/npm/StatThds.pas
@@ -1,9 +1,11 @@
unit StatThds;
-
+ {$Include ..\common\isgui.inc}
interface
uses
- ComCtrls,Classes, Graphics, ExtCtrls, define_types,stats,StatThdsUtil,Brunner,lesion_pattern;
+ {$IFDEF GUI} ComCtrls,{$ENDIF}
+ //ComCtrls, Graphics, ExtCtrls,
+ Classes, define_types,stats,StatThdsUtil,Brunner,lesion_pattern, dialogsx;
@@ -15,10 +17,10 @@ type
lttestx,lBMx: boolean;
lnCritx,lBarPosX,lnPermuteX,lThreadx,lThreadStartx,lThreadEndx,lStartVoxx,lVoxPerPlankx,lImagesCountx,lnGroup1x : integer;
lMaskImgx,lPlankImgx,lOutImgMnx,lOutImgBMx,lOutImgTx,lSymptomRAx: SingleP;
- //lBarX: TProgressBar;
procedure DoVisualSwap;
protected
procedure Execute; override;
+ //procedure Terminate;
procedure VisualProg(lPos: Integer);
procedure Analyze(lttest,lBM: boolean; lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount,lnGroup1 : integer; lMaskImg,lPlankImg,lOutImgMn,lOutImgBM,lOutImgT,lSymptomRA: SingleP); virtual; abstract;
public
@@ -51,6 +53,7 @@ type
end;
implementation
+uses unpm;
//uses Stat;
@@ -159,13 +162,17 @@ end;
procedure TStatThread.DoVisualSwap;
begin
+ {$IFDEF GUI}
lBarX.Position := lBarPosX;
+ {$ENDIF}
end;
procedure TStatThread.VisualProg(lPos: Integer);
begin
+ {$IFDEF GUI}
lBarPosX := lPos;
{$IFDEF FPC}Synchronize(@DoVisualSwap); {$ELSE} Synchronize(DoVisualSwap);{$ENDIF}
+ {$ENDIF}
end;
constructor TStatThread.Create(lBar: TProgressBar; lttest,lBM: boolean; lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount,lnGroup1 : integer; lMaskImg,lPlankImg,lOutImgMn,lOutImgBM,lOutImgT,lSymptomRA: SingleP);
@@ -201,7 +208,12 @@ begin
Analyze(lttestx,lBMx, lnCritX,lnPermuteX,lThreadx,lThreadStartx,lThreadEndx,lStartVoxx,lVoxPerPlankx,lImagesCountx,lnGroup1x,lMaskImgx,lPlankImgX,lOutImgMnx,lOutImgBMx,lOutImgTx,lSymptomRAx);
end;
-
+(*procedure TStatThread.Terminate;
+begin
+ Dec(gThreadsRunning);
+ NPMmsg('Thread done');
+ inherited Terminate;
+end; *)
{ Nearest Nighbor }
procedure TNNStat.Analyze(lttest,lBM: boolean; lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount,lnGroup1 : integer; lMaskImg,lPlankImg,lOutImgMn,lOutImgBM,lOutImgT,lSymptomRA: SingleP);
@@ -243,6 +255,7 @@ begin //statthread
end; //in brain mask - compute
end; //for each voxel
freemem(lObsP);
+ Terminate;
end;
@@ -562,4 +575,4 @@ begin //statthread
end;*)
-end.
+end.
\ No newline at end of file
diff --git a/npm/StatThdsUtil.pas b/npm/StatThdsUtil.pas
old mode 100644
new mode 100755
index d4b32b1..f7d1117
--- a/npm/StatThdsUtil.pas
+++ b/npm/StatThdsUtil.pas
@@ -1,19 +1,18 @@
unit StatThdsUtil;
interface
-
-
uses
- ComCtrls,Classes, Graphics, ExtCtrls, define_types,stats,dialogs;
+ //ComCtrls,Graphics, ExtCtrls,
+ Classes, define_types,dialogsx;
const
kMaxThreads = 16;
kSh = 10; //bits to shift
kMaxImages = 1024;
kMaxPermute = 4000;
- kPlankMB : integer = 512;
+ //kPlankMB : integer = 512;
var
gnCPUThreads, gThreadsRunning: Integer;
- kPlankSz : integer;// =1024 {bytes/kb} * 1024 {bytes/mb} * kPlankMB; //e.g. 512 MB
+ kPlankSz : int64;// =1024 {bytes/kb} * 1024 {bytes/mb} * kPlankMB; //e.g. 512 MB
gDataTypeRA: array [0..kMaxImages] of integer;
gOffsetRA,gScaleRA,gInterceptRA: array [0..kMaxImages] of single;
gnVoxTestedRA : array [0..kMaxThreads] of integer;
@@ -30,7 +29,7 @@ var lT,lP: integer;
begin
if lnThreads < 1 then exit;
if lnPermute > kMaxPermute then
- showmessage('Error: recompile with larger kMaxPermute');
+ ShowMsg('Error: recompile with larger kMaxPermute');
for lT := 1 to lnThreads do
gnVoxTestedRA[lT] := 0;
if lnPermute < 1 then exit;
@@ -50,7 +49,7 @@ var lT,lP: integer;
begin
if lnThreads < 1 then exit;
if lnPermute > kMaxPermute then
- showmessage('Error: recompile with larger kMaxPermute');
+ ShowMsg('Error: recompile with larger kMaxPermute');
for lT := 1 to lnThreads do
gnVoxTestedRA[lT] := 0;
if lnPermute < 1 then exit;
@@ -104,4 +103,4 @@ begin
end; //SumThreadData
-end.
+end.
\ No newline at end of file
diff --git a/npm/Vector.pas b/npm/Vector.pas
old mode 100644
new mode 100755
index 109a8e6..d2f893b
--- a/npm/Vector.pas
+++ b/npm/Vector.pas
@@ -1,5 +1,5 @@
unit Vector;
-
+{$Include ..\common\isgui.inc}
interface
uses SysUtils;
@@ -541,4 +541,4 @@ begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/npm/_npmcl.bat b/npm/_npmcl.bat
new file mode 100755
index 0000000..2b8ab25
--- /dev/null
+++ b/npm/_npmcl.bat
@@ -0,0 +1,6 @@
+
+lazbuild ./npmcl.lpr --cpu=x86_64 --compiler="/usr/local/bin/ppcx64"
+mv ./npmcl ./npmcl64
+
+lazbuild ./npmcl.lpr
+
diff --git a/npm/anacom.pas b/npm/anacom.pas
old mode 100644
new mode 100755
diff --git a/npm/associate.pas b/npm/associate.pas
old mode 100644
new mode 100755
diff --git a/npm/brunner.pas b/npm/brunner.pas
old mode 100644
new mode 100755
diff --git a/npm/design.dfm b/npm/design.dfm
old mode 100644
new mode 100755
diff --git a/npm/design.lfm b/npm/design.lfm
old mode 100644
new mode 100755
diff --git a/npm/design.lrs b/npm/design.lrs
old mode 100644
new mode 100755
diff --git a/npm/design.pas b/npm/design.pas
old mode 100644
new mode 100755
diff --git a/npm/dice.ico b/npm/dice.ico
old mode 100644
new mode 100755
diff --git a/npm/dmath/GraphicsMathLibrary.pas b/npm/dmath/GraphicsMathLibrary.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/Matrices.pas b/npm/dmath/Matrices.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/Regress.pas b/npm/dmath/Regress.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/_clean.bat b/npm/dmath/_clean.bat
old mode 100644
new mode 100755
diff --git a/npm/dmath/eigen.pas b/npm/dmath/eigen.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fcomp.pas b/npm/dmath/fcomp.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitexlin.pas b/npm/dmath/fitexlin.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitexpo.pas b/npm/dmath/fitexpo.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitfrac.pas b/npm/dmath/fitfrac.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fithill.pas b/npm/dmath/fithill.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitiexpo.pas b/npm/dmath/fitiexpo.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitlin.pas b/npm/dmath/fitlin.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitlogis.pas b/npm/dmath/fitlogis.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitmich.pas b/npm/dmath/fitmich.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitmult.pas b/npm/dmath/fitmult.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitpka.pas b/npm/dmath/fitpka.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitpoly.pas b/npm/dmath/fitpoly.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fitpower.pas b/npm/dmath/fitpower.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fmath.pas b/npm/dmath/fmath.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/fourier.pas b/npm/dmath/fourier.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/matcomp.pas b/npm/dmath/matcomp.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/math387.inc b/npm/dmath/math387.inc
old mode 100644
new mode 100755
diff --git a/npm/dmath/mathp2.inc b/npm/dmath/mathp2.inc
old mode 100644
new mode 100755
diff --git a/npm/dmath/mcmc.pas b/npm/dmath/mcmc.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/models.pas b/npm/dmath/models.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/optim.pas b/npm/dmath/optim.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/pastring.pas b/npm/dmath/pastring.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/plot.inc b/npm/dmath/plot.inc
old mode 100644
new mode 100755
diff --git a/npm/dmath/plot.pas b/npm/dmath/plot.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/plotvar.inc b/npm/dmath/plotvar.inc
old mode 100644
new mode 100755
diff --git a/npm/dmath/polynom.pas b/npm/dmath/polynom.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/regmultdelphi.pas b/npm/dmath/regmultdelphi.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/simopt.pas b/npm/dmath/simopt.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/stat.pas b/npm/dmath/stat.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/texplot.pas b/npm/dmath/texplot.pas
old mode 100644
new mode 100755
diff --git a/npm/dmath/winplot.pas b/npm/dmath/winplot.pas
old mode 100644
new mode 100755
diff --git a/npm/extrafpc.cfg b/npm/extrafpc.cfg
old mode 100644
new mode 100755
diff --git a/npm/filename.pas b/npm/filename.pas
old mode 100644
new mode 100755
diff --git a/npm/firth.pas b/npm/firth.pas
old mode 100644
new mode 100755
index bc3785e..572350c
--- a/npm/firth.pas
+++ b/npm/firth.pas
@@ -2,28 +2,28 @@ unit firth;
interface
uses
- ComCtrls,Classes, Graphics, ExtCtrls, define_types,{stats,}StatThdsUtil,lesion_pattern,Mat,Math,Distr,Vector;
+ {$Include ..\common\isgui.inc}
+ //ComCtrls,Classes, Graphics, ExtCtrls,
+ //{$IFDEF FPC}ComCtrls, {$ENDIF}
+ {$IFDEF GUI} ComCtrls,{$ENDIF} //progressbar
+ classes,define_types,{stats,}StatThdsUtil,lesion_pattern,Mat,Math,Distr,Vector,dialogsx, unpm, SysUtils;
procedure FirthAnalyzeNoThread(lnCond, lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount : integer; lPlankImg: bytep;lOutImgMn,lSymptomRA: SingleP;lOutImg: SingleRAp);
-
-
implementation
-uses npmform, dialogs;
-procedure VisualProg(lPos: Integer);
+procedure VisualProg(lPos,lTestNumber: Integer);
begin
- MainForm.ProgressBar1.Position := lPos;
- MainForm.Refresh;
+ NPMTitleMsg(inttostr(lTestNumber));
+ NPMProgressBar( lPos);
end;
-
var
finalloglik: SingleP0;
KxKA1,KxKB1,KxKA,KxKB :TMatrix;
Kvec,Kvec1 : TVector;
Kveci,kVeci1 : TVectori;
- betak,xbeta,y,pi,ustar,
+ betak,xbeta,yin,pi,ustar,
XXx,XXXW2,XXFisher,XXcovs,XXXWPrime,
deltahalfs,deltat,delta,covs,x,Fisher,XW2,W,XWprime,Hprime,H,ustarmat,negx: TMatrix;
lBarX: TProgressBar;
@@ -129,17 +129,17 @@ begin
for inc := 1 to n do begin
lDenom := (1 + exp( xbeta[inc,1]));
if lDenom = 0 then
- showmessage('yikes')
+ showMsg('yikes')
else
pi[inc,1] := 1/lDenom;
end;
result := 0;
for inc := 1 to n do
- if y[inc,1] = 1 then
+ if yin[inc,1] = 1 then
//if pi[inc,1] <> 1 then
result := result+ln(pi[inc,1]);
for inc := 1 to n do
- if y[inc,1] = 0 then
+ if yin[inc,1] = 0 then
//if pi[inc,1] <> 1 then
result := result+ln(1-pi[inc,1]);
if firth then
@@ -164,7 +164,7 @@ begin
i := 1;
repeat
inc(i);
- if y[i,1] <> y[1,1] then
+ if yin[i,1] <> yin[1,1] then
variability := true;
until (i= (numSubj)) or (variability);
if not variability then
@@ -196,7 +196,7 @@ begin
//now start computations
sumy := 0;
for i := 1 to n do
- sumy := sumy + round(y[i,1]);
+ sumy := sumy + round(yin[i,1]);
if (sumy <= 0) or (sumy >= n) then begin
//serious error: no variability. This should have been detected earlier in the procedure when yin was tested for variability
goto 666;
@@ -233,7 +233,7 @@ begin
HPrime.mult(XWPrime,covs);
H.mult(HPrime,XW2);
//WriteMatrix(covs);
- ustar.Sub(y,pi);
+ ustar.Sub(yin,pi);
if firth then
Diag2Vec;
crossprodustar;
@@ -287,7 +287,7 @@ begin
Sumy0 := 0;
Sumy1 := 0;
for iter := 1 to n do begin
- if y[iter,1] = 0 then
+ if yin[iter,1] = 0 then
Sumy0 := Sumy0 + x.M[i+1,iter] //+1: M indexed from 1, ZVal indexed from 0
else
Sumy1 := Sumy1 + x.M[i+1,iter]; //+1 M indexed from 1
@@ -315,16 +315,37 @@ label
const
knPrevPattern = 10;
var
-
-
lPrevPatternRA: array[1..knPrevPattern] of TLesionPattern;
lPattern: TLesionPattern;
lObs: Bytep;
lPrevZVals: array [1..knPrevPattern] of SingleP0;
lZVals: SingleP0;
lPatternPos,lC,lnLesion,lPosPct,lPos,lPos2,lPos2Offset,lnCritLocal,n,k: integer;
-begin //statthread
+(* myFile : TextFile;
+procedure Hdr2File;
+var
+ myI: integer;
+begin
+ for myI := 1 to (lImagesCount*lnCond ) do begin
+ write(myFile, floattostr(lSymptomRA^[myI])+kTab);
+ end;
+ WriteLn(myFile, '');
+end;
+
+procedure Data2File;
+var
+ myI: integer;
+begin
+ for myI := 1 to (lImagesCount ) do begin
+ write(myFile, inttostr(round(yIn[myI,1]))+kTab);
+ end;
+ WriteLn(myFile, '');
+end; *)
+begin //statthread
+ (*Assign(myFile,'/Users/rorden/logreg.txt');
+ ReWrite(myFile);
+ Hdr2File; *)
lnCritLocal := lnCrit;
if lnCritLocal < 1 then
lnCritLocal := 1;
@@ -334,7 +355,7 @@ begin //statthread
Getmem(lPrevZVals[lPos],(lnCond+1)*sizeof(single));
n := lImagesCount;
k := lnCond + 1;
- y := TMatrix.Create(n,1);
+ yin:= TMatrix.Create(n,1);
GetMem(finalloglik,(k+1)*sizeof(single));//finalloglik := TVector.Create(k+1);
x := TMatrix.Create (k, n);
betak:=TMatrix.Create(1,k);
@@ -374,21 +395,21 @@ Kveci1 := TVectori.Create(k-1);
lPrevPatternRA[lPatternPos] := EmptyOrder;
lPatternPos := 1;
for lPos2 := lThreadStart to lThreadEnd do begin
- if (lThread = 1) and ((lPos2 mod lPosPct) = 0) then
- VisualProg(round((lPos2/(lThreadEnd-lThreadStart))*100));
+ if (lThread = 1) and ((lPos2 mod lPosPct) = 0) or ((gnVoxTestedRA[lThread] mod 100) = 0) then
+ VisualProg(round((lPos2/(lThreadEnd-lThreadStart))*100), gnVoxTestedRA[lThread]);
lPos2Offset := lPos2+lStartVox-1;
lnLesion := 0;
for lPos := 1 to lImagesCount do begin
if lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2] = 0 then begin
//no lesion
- y[lPos,1] := 0;
+ yin[lPos,1] := 0;
lObs^[lPos] := 0;
end else begin
//lesion
inc(lnLesion);
lObs^[lPos] := 1;
- y[lPos,1] := 1; //note: lObs indexed from zero!
+ yin[lPos,1] := 1; //note: lObs indexed from zero!
end;
end;
lOutImgMn^[lPos2Offset] := lnLesion;///lImages.Count;
@@ -398,13 +419,13 @@ Kveci1 := TVectori.Create(k-1);
while (lPos <= knPrevPattern) and not (SameOrder(lPattern,lPrevPatternRA[lPos],lImagesCount)) do
inc(lPos);
if SameOrder(lPattern,lPrevPatternRA[lPos],lImagesCount) then begin
- inc(gnVoxTestedRA[lThread]);
+
//logistfx(lObs,lSymptomRA, lZvals, lImagesCount,lnCond,false);
for lC := 1 to lnCond do
lOutImg^[lC]^[lPos2Offset] := lPrevZvals[lPos]^[lC];
end else begin //new pattern - need to compute
inc(gnVoxTestedRA[lThread]);
- logistfx(lSymptomRA, lZvals, lImagesCount,lnCond,false);
+ //logistfx(lSymptomRA, lZvals, lImagesCount,lnCond,false);
for lC := 1 to lnCond do
lOutImg^[lC]^[lPos2Offset] := lZvals^[lC];
lPrevPatternRA[lPatternPos] := lPattern;
@@ -425,7 +446,7 @@ Kveci1 := TVectori.Create(k-1);
freemem(lPrevZVals[lPos]);
freemem(lZVals);
-y.free;
+yin.free;
x.free;
betak.free;
covs.free;
@@ -462,4 +483,4 @@ Kveci1.free;
end;
end.
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/npm/firthThds.pas b/npm/firthThds.pas
old mode 100644
new mode 100755
index bc865c9..70eb78f
--- a/npm/firthThds.pas
+++ b/npm/firthThds.pas
@@ -3,8 +3,11 @@ unit firthThds;
//creates multiple threads
//Requires firth
interface
-uses
- ComCtrls,Classes, Graphics, ExtCtrls, define_types,{stats,}StatThdsUtil,lesion_pattern,Mat,Math,Distr,Vector;
+{$Include ..\common\isgui.inc}
+uses
+ //ComCtrls,Graphics, ExtCtrls,
+ {$IFDEF GUI}ComCtrls, {$ENDIF}
+ Classes, define_types,{stats,}StatThdsUtil,lesion_pattern,Mat,Math,Distr,Vector,dialogsx,Forms,SysUtils;
type
@@ -12,25 +15,26 @@ type
private
finalloglik: SingleP0;
KxKA1,KxKB1,KxKA,KxKB :TMatrix;
-Kvec,Kvec1 : TVector;
-Kveci,kVeci1 : TVectori;
-
-
+ Kvec,Kvec1 : TVector;
+ Kveci,kVeci1 : TVectori;
betak,xbeta,y,pi,ustar,
XXx,XXXW2,XXFisher,XXcovs,XXXWPrime,
deltahalfs,deltat,delta,covs,x,Fisher,XW2,W,XWprime,Hprime,H,ustarmat,negx: TMatrix;
lBarX: TProgressBar;
- lnCondx,lnCritx,lBarPosX,lnPermuteX,lThreadx,lThreadStartx,lThreadEndx,lStartVoxx,lVoxPerPlankx,lImagesCountx : integer;
+ lFormX: TForm;
+ lShowProgressX: boolean;
+ lnCondx,lnCritx,lBarPosX,lTestPosX, lnPermuteX,lThreadx,lThreadStartx,lThreadEndx,lStartVoxx,lVoxPerPlankx,lImagesCountx : integer;
lPlankImgx: byteP;lOutImgMnx,lSymptomRAx: SingleP;
lOutImgX: SingleRAp;
//lBarX: TProgressBar;
procedure DoVisualSwap;
protected
procedure Execute; override;
- procedure VisualProg(lPos: Integer);
+
+ procedure VisualProg(lPos,lTestNumber: Integer);
procedure Analyze(lnCond,lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount : integer; lPlankImg: bytep;lOutImgMn,lSymptomRA: SingleP; lOutImg: SingleRAp); virtual; abstract;
public
- constructor Create(lBar: TProgressBar; lnCond,lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount : integer; lPlankImg: byteP;lOutImgMn,lSymptomRA: SingleP; lOutImg: SingleRAp);
+ constructor Create(lShowProgress: boolean; lForm: TForm; lBar: TProgressBar; lnCond,lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount : integer; lPlankImg: byteP;lOutImgMn,lSymptomRA: SingleP; lOutImg: SingleRAp);
end;
TFirthThreadStat = class(TMultiRegThread )
@@ -46,17 +50,22 @@ implementation
procedure TMultiRegThread .DoVisualSwap;
begin
lBarX.Position := lBarPosX;
+ lFormX.Caption := inttostr(lTestPosX);
end;
-procedure TMultiRegThread.VisualProg(lPos: Integer);
+procedure TMultiRegThread.VisualProg(lPos,lTestNumber: Integer);
begin
lBarPosX := lPos;
+ lTestPosX := lTestNumber;
+ //NPMTitleMsg(inttostr(lTestNumber));
{$IFDEF FPC}Synchronize(@DoVisualSwap); {$ELSE} Synchronize(DoVisualSwap);{$ENDIF}
end;
-constructor TMultiRegThread.Create(lBar: TProgressBar; lnCond,lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount : integer; lPlankImg: bytep;lOutImgMn,lSymptomRA: SingleP;lOutImg: SingleRAp);
+constructor TMultiRegThread.Create(lShowProgress: boolean; lForm: TForm; lBar: TProgressBar; lnCond,lnCrit,lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImagesCount : integer; lPlankImg: bytep;lOutImgMn,lSymptomRA: SingleP;lOutImg: SingleRAp);
begin
+ lShowProgressX := lShowProgress;
lBarX := lBar;
+ lFormX := lForm;
lThreadX := lThread;
lThreadStartX := lThreadStart;
lThreadEndX := lThreadEnd;
@@ -413,8 +422,8 @@ Kveci1 := TVectori.Create(k-1);
lPrevPatternRA[lPatternPos] := EmptyOrder;
lPatternPos := 1;
for lPos2 := lThreadStart to lThreadEnd do begin
- if (lThread = 1) and ((lPos2 mod lPosPct) = 0) then
- VisualProg(round((lPos2/(lThreadEnd-lThreadStart))*100));
+ if (lShowProgressX) and ( ((lPos2 mod lPosPct) = 0) or ((lPos2 mod 200) = 0) ) then
+ VisualProg(round((lPos2/(lThreadEnd-lThreadStart))*100),lPos2);
if Terminated then exit;
lPos2Offset := lPos2+lStartVox-1;
lnLesion := 0;
@@ -636,4 +645,4 @@ end; (**)
-end.
+end.
\ No newline at end of file
diff --git a/npm/fpc-res.or b/npm/fpc-res.or
old mode 100644
new mode 100755
diff --git a/npm/fpc-res.res b/npm/fpc-res.res
old mode 100644
new mode 100755
diff --git a/npm/hdr.pas b/npm/hdr.pas
old mode 100644
new mode 100755
index 37037e6..5641c5c
--- a/npm/hdr.pas
+++ b/npm/hdr.pas
@@ -1,7 +1,8 @@
unit hdr;
interface
{$H+}
-uses nifti_hdr,define_types,classes;
+{$Include ..\common\isgui.inc}
+uses nifti_hdr,define_types,classes, unpm;
procedure MakeStatHdr (var lBGHdr,lStatHdr: TniftiHdr; lMinIntensity,lMaxIntensity,lIntent_p1,lIntent_p2,lIntent_p3: single; lIntent_code: smallint;lIntentName: string);
procedure MakeHdr (var lBGHdr,lStatHdr: TniftiHdr);
@@ -25,17 +26,13 @@ procedure DeleteDecompressed4D(lDecomName: string);
implementation
uses
{$IFDEF FPC} gzio2,Controls,
-
{$ELSE} {gzio,ZLib,}DiskSpaceKludge,gziod,{$ENDIF}
{$IFNDEF UNIX}Windows, {$ENDIF}
-
- Dialogs ,SysUtils,StatThdsUtil,npmform;
+{$IFDEF GUI}Dialogs,{$ENDIF}
+ Dialogsx ,SysUtils,StatThdsUtil;
//define_types,GraphicsMathLibrary;
{$IFDEF FPC} {$mode objfpc}{$H+} {$ENDIF}
-procedure MsgX (lStr: string);
-begin
- //msgx
-end;
+
procedure DeleteDecompressed4D(lDecomName: string);
begin
@@ -55,12 +52,12 @@ begin
result := false;
lHdrName := Filename4D(lHdrNameIn);
if not NIFTIhdr_LoadHdr(lHdrName,lHdr) then begin
- MainForm.NPMmsg('Unable to load image '+lHdrName);
+ NPMmsg('Unable to load image '+lHdrName);
exit;
end;
lVox := ComputeImageDataBytes8bpp(lHdr);
if lVox <> lMaskVoxels then begin
- MainForm.NPMmsg('Voxels differ for '+lHdrName+' expected '+inttostr(lMaskVoxels)+' described '+inttostr(lVox));
+ NPMmsg('Voxels differ for '+lHdrName+' expected '+inttostr(lMaskVoxels)+' described '+inttostr(lVox));
exit;
end;
(*if (lHdr.NIFTIhdr.bitpix <> 8) and (lHdr.NIFTIhdr.datatype <> kDT_FLOAT) and (lHdr.NIFTIhdr.datatype <> kDT_SIGNED_INT) then begin
@@ -70,7 +67,7 @@ begin
if UpCaseExt(lHdrName) = '.HDR' then
lHdrName := changefileext(lHdrName,'.img');
if (not GzExt(lHdrName) ) and (FSize(lHdrName) < lMaskVoxels) then begin
- showmessage('The uncompressed image data should be at least '+inttostr(lMaskVoxels)+' bytes. '+lHdrName);
+ ShowMsg('The uncompressed image data should be at least '+inttostr(lMaskVoxels)+' bytes. '+lHdrName);
exit;
end;
result := true;
@@ -155,29 +152,29 @@ begin
result := false;
lHdrName := Filename4D(lHdrNameIn);
if not NIFTIhdr_LoadHdr(lHdrName,lHdr) then begin
- MainForm.NPMmsg('Unable to load image '+lHdrName);
+ NPMmsg('Unable to load image '+lHdrName+' Possible solution: make sure VAL file and images are in the same folder');
exit;
end;
(*lVox := ComputeImageDataBytes8bpp(lHdr);
lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
if lVox <> lMaskVoxels then begin
- MainForm.NPMmsg('Voxels differ for '+lHdrName+' expected '+inttostr(lMaskVoxels)+' described '+inttostr(lVox));
+ NPMmsg('Voxels differ for '+lHdrName+' expected '+inttostr(lMaskVoxels)+' described '+inttostr(lVox));
exit;
end; *)
for lDim := 1 to 3 do begin
if (lHdr.NIFTIhdr.dim[lDim] <> lMaskHdr.NIFTIhdr.dim[lDim]) then begin
- MainForm.NPMmsg('Dimension '+inttostr(lDim)+' of '+lHdrName+' does not match '+lMaskHdr.HdrFileName);
+ NPMmsg('Dimension '+inttostr(lDim)+' of '+lHdrName+' does not match '+lMaskHdr.HdrFileName);
exit;
end;
end;
if (not lHdr.NIfTItransform) then
- MainForm.NPMmsg('Warning: no spatial transform for '+lHdrName+' (Analyze not NIfTI). Please ensure images are coregistered.')
+ NPMmsg('Warning: no spatial transform for '+lHdrName+' (Analyze not NIfTI). Please ensure images are coregistered.')
else if (not lMaskHdr.NIfTItransform) then
- MainForm.NPMmsg('Warning: no spatial transform for '+lMaskHdr.HdrFileName+' (Analyze not NIfTI). Please ensure images are coregistered.')
+ NPMmsg('Warning: no spatial transform for '+lMaskHdr.HdrFileName+' (Analyze not NIfTI). Please ensure images are coregistered.')
else begin
if not SameTransform (lHdr.NIFTIhdr, lMaskHdr.NIFTIhdr) then begin
- MainForm.NPMmsg('Warning: spatial transforms differ for '+lHdrName+' and '+lMaskHdr.HdrFileName);
- MainForm.NPMmsg(TransformTxt(lHdr.NIFTIhdr)+' <> '+ TransformTxt(lMaskHdr.NIFTIhdr));
+ NPMmsg('Warning: spatial transforms differ for '+lHdrName+' and '+lMaskHdr.HdrFileName);
+ NPMmsg(TransformTxt(lHdr.NIFTIhdr)+' <> '+ TransformTxt(lMaskHdr.NIFTIhdr));
end;
end;
(*if (lHdr.NIFTIhdr.bitpix <> 8) and (lHdr.NIFTIhdr.datatype <> kDT_FLOAT) and (lHdr.NIFTIhdr.datatype <> kDT_SIGNED_INT) then begin
@@ -187,7 +184,7 @@ begin
if UpCaseExt(lHdrName) = '.HDR' then
lHdrName := changefileext(lHdrName,'.img');
if (not GzExt(lHdrName) ) and (FSize(lHdrName) < (lHdr.NIFTIhdr.dim[1]*lHdr.NIFTIhdr.dim[2]*lHdr.NIFTIhdr.dim[3])) then begin
- showmessage('The file size appears too small '+lHdrName);
+ ShowMsg('The file size appears too small '+lHdrName);
exit;
end;
result := true;
@@ -210,10 +207,10 @@ begin
lHdrName:= lG[lC-1];
if not CheckVoxelsX(lHdrName, lMaskHdr,lC) then begin
if not fileexists (lHdrName) then
- MainForm.NPMmsg('File not found "'+lHdrName+'"')
+ NPMmsg('File not found "'+lHdrName+'". Possible solution: make sure VAL file and images are in the same folder')
else
- MainForm.NPMmsg('Problem with "'+lHdrName);
+ NPMmsg('Problem with "'+lHdrName);
exit;
end;
end;
@@ -229,7 +226,7 @@ begin
if lG.count < 1 then exit;
lS := lG[0];
if not NIFTIhdr_LoadHdr(lS,lMaskHdr) then begin
- MainForm.NPMmsg('Unable to load image '+lS);
+ NPMmsg('Unable to load image '+lS);
exit;
end;
result := CheckVoxelsGroupX(lG,lMaskHdr);
@@ -343,7 +340,6 @@ begin
while fileexists(result) do //make sure we do not overwrite anything
result := lFilename +inttostr(random(9999))+'.nii';
//unzip
- Msgx('Decompressing 4D image '+lFilename+ ' -> '+result);
Gunzip(lFilename,result);
//set image names to point to uncompressed volume
for lP := 1 to lImageNames.Count do
@@ -407,16 +403,29 @@ begin
lImgBuffer := ByteP(lImg);
lExt := UpCaseExt(lFileName);
if DiskFreeEx(lFilename) < (kImgOffset+(lImgBufferItems*lImgBufferBPP*lnVol)) then begin
- case MessageDlg('Very little space on the selected drive. Attempt to save to this disk?', mtConfirmation,
- [mbYes, mbCancel], 0) of
+ {$IFDEF GUI}
+
+ case MsgDlg('Very little space on the selected drive. Attempt to save to this disk?', mtConfirmation,[mbYes, mbCancel], 0) of
{$IFDEF FPC}mrCancel: exit; {$ELSE} id_Cancel: exit;{$ENDIF}
end; //case
+ {$ELSE}
+ ShowMsg('Very little space on the selected drive. Data may be lost.');
+ {$ENDIF}
end;
if FileExistsEX(lFileName) then begin
- case MessageDlg('Overwrite the file named '+lFileName+'?', mtConfirmation,
- [mbYes, mbCancel], 0) of
+ {$IFDEF GUI}
+ if (ParamCount < 1) then begin
+ case MsgDlg('Overwrite the file named '+lFileName+'?', mtConfirmation,[mbYes, mbCancel], 0) of //MessageDlg
{$IFDEF FPC}mrCancel: exit; {$ELSE} id_Cancel: exit;{$ENDIF} //requires Uses Controls
- end; //case
+ end; //case
+ end else begin
+ NPMMsg('Warning: overwriting '+lFilename);
+
+ end;
+ {$ELSE}
+ ShowMsg('Warning: overwriting '+lFilename);
+ {$ENDIF}
+ DeleteFile(lFilename);
end; //file exists
if (lExt='.VOI') then begin
lHdr.intent_name[1] := 'B';//Binary
@@ -462,7 +471,7 @@ begin
//lHdr.scl_slope := (lHdr.WindowScaledMax-lHdr.WindowScaledMin) /255;
end;
else begin
- showmessage('Error: Unsupported bytes per voxel: '+inttostr(lImgBufferBPP));
+ showmsg('Error: Unsupported bytes per voxel: '+inttostr(lImgBufferBPP));
exit;
end;
end;
@@ -576,4 +585,4 @@ begin
SaveAsVOIorNIFTIcore (lOutNameMod, lHdr, SingleP(lImg),lnVol,1);
end;
-end.
+end.
\ No newline at end of file
diff --git a/npm/lesion_pattern.pas b/npm/lesion_pattern.pas
old mode 100644
new mode 100755
diff --git a/npm/montecarlo.pas b/npm/montecarlo.pas
old mode 100644
new mode 100755
index 01b9b76..fdd1d5e
--- a/npm/montecarlo.pas
+++ b/npm/montecarlo.pas
@@ -5,7 +5,7 @@ interface
uses
define_types,SysUtils,
part,StatThds,statcr,StatThdsUtil,Brunner,DISTR,nifti_img, hdr,
- Messages, Classes, Graphics, Controls, Forms, Dialogs,
+ Messages, Classes, Graphics, Controls, Forms, Dialogsx,
StdCtrls, ComCtrls,ExtCtrls,Menus, overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr,
{$IFDEF FPC} LResources,gzio2,
diff --git a/npm/nifti_img.pas b/npm/nifti_img.pas
old mode 100644
new mode 100755
index 327b405..dacbd11
--- a/npm/nifti_img.pas
+++ b/npm/nifti_img.pas
@@ -1,8 +1,7 @@
unit nifti_img;
-//only for Delphi - not Freepascal
-//Unit for running multiple regression
interface
-uses define_types,Classes,nifti_hdr,sysutils,dialogs
+{$Include ..\common\isgui.inc}
+uses hdr,define_types,Classes,nifti_hdr,sysutils,dialogsx, unpm
{$IFDEF FPC},gzio2
{$ELSE}
,gziod
@@ -16,7 +15,7 @@ function LoadImg8(lInName: string; lImgData: ByteP; lStart, lEnd,linvox_offset,l
implementation
-uses npmform,hdr;
+
function LoadImg(lInName: string; lImgData: SingleP; lStart, lEnd,linvox_offset,lRApos,lDataType,lVolVox: integer): boolean;
var
@@ -30,14 +29,14 @@ begin
result := false;
if (lStart >= lEnd) or (lStart < 1) or (lEnd < 1) then begin
- MainForm.NPMmsg('Error: LoadImg '+inttostr(lStart)+'>='+inttostr(lEnd)+' or zero');
+ NPMmsg('Error: LoadImg '+inttostr(lStart)+'>='+inttostr(lEnd)+' or zero');
exit;
end;
if Files4D(lInName) then begin
lImgName := Filename4D(lInName);
lP2 := BPP (lDataType);
if lP2 = 0 then begin
- Showmessage(lImgName +' is an unsupported file type');
+ ShowMsg(lImgName +' is an unsupported file type');
exit;
end;
lvox_offset := linvox_offset+ ((Vol4D(lInName)-1)* (lP2 * lVolVox));
@@ -49,7 +48,7 @@ begin
lImgName := changefileext(lImgName,'.img');
lFSize := FSize(lImgName);
if (not GzExt(lImgName)) and (lFSize < (lEnd+ lvox_offset)) then begin
- MainForm.NPMmsg('Error: LoadImg '+lImgName+' FSize = '+inttostr(lFSize)+' Expected '+inttostr(lEnd+ lvox_offset));
+ NPMmsg('Error: LoadImg '+lImgName+' FSize = '+inttostr(lFSize)+' Expected '+inttostr(lEnd+ lvox_offset));
exit;
end;
filemode := 0;
@@ -105,7 +104,7 @@ begin
lImgData^[lRApos+lInc-1] := 0;
end;
end else begin
- showmessage(lImgName + ' is an unsupported compressed data type '+inttostr(lDataType));
+ ShowMsg(lImgName + ' is an unsupported compressed data type '+inttostr(lDataType));
exit;
end;
end else begin
@@ -122,7 +121,7 @@ begin
getmem(lSmallIntP, sizeof(smallint)* ((lEnd+1)-lStart));
reset(lFdata,2);
if (lvox_offset mod 2) <> 0 then begin
- showmessage('Error: this software can only read headers with dataoffsets that are divisible by 4.');
+ ShowMsg('Error: this software can only read headers with dataoffsets that are divisible by 4.');
end;
seek(lFdata,(lvox_offset div 2)+ (lStart-1));
BlockRead(lFdata, lSmallIntP^, (lEnd+1)-lStart);
@@ -133,7 +132,7 @@ begin
//next: 4 byte data
reset(lFdata,4);
if (lvox_offset mod 4) <> 0 then begin
- showmessage('Error: this software can only read headers with dataoffsets that are divisible by 4.');
+ ShowMsg('Error: this software can only read headers with dataoffsets that are divisible by 4.');
end;
seek(lFdata,(lvox_offset div 4)+ (lStart-1) );
BlockRead(lFdata, lImgData[lRApos], (lEnd+1)-lStart);
@@ -147,7 +146,7 @@ begin
lImgData^[lRApos+lInc-1] := 0;
end;
end else
- showmessage('Unsupported COMPRESSED data type '+inttostr(lDataType));
+ ShowMsg('Unsupported COMPRESSED data type '+inttostr(lDataType));
closefile(lFdata);
end; //not gz
result := true;
@@ -172,7 +171,7 @@ begin
lImgName := Filename4D(lInName);
lP2 := BPP (lDataType);
if lP2 = 0 then begin
- Showmessage(lImgName +' is an unsupported file type');
+ ShowMsg(lImgName +' is an unsupported file type');
exit;
end;
lvox_offset := linvox_offset+ ((Vol4D(lInName)-1)* (lP2 * lVolVox));
@@ -240,7 +239,7 @@ begin
lImgData^[lRApos+lInc-1] := 0;
end;
end else begin
- showmessage(lImgName + ' is an unsupported compressed data type '+inttostr(lDataType));
+ ShowMsg(lImgName + ' is an unsupported compressed data type '+inttostr(lDataType));
exit;
end;
end else begin
@@ -257,7 +256,7 @@ begin
getmem(lSmallIntP, sizeof(smallint)* ((lEnd+1)-lStart));
reset(lFdata,2);
if (lvox_offset mod 2) <> 0 then begin
- showmessage('Error: this software can only read headers with dataoffsets that are divisible by 4.');
+ ShowMsg('Error: this software can only read headers with dataoffsets that are divisible by 4.');
end;
seek(lFdata,(lvox_offset div 2)+ (lStart-1));
BlockRead(lFdata, lSmallIntP^, (lEnd+1)-lStart);
@@ -268,7 +267,7 @@ begin
//next: 4 byte data
reset(lFdata,4);
if (lvox_offset mod 4) <> 0 then begin
- showmessage('Error: this software can only read headers with dataoffsets that are divisible by 4.');
+ ShowMsg('Error: this software can only read headers with dataoffsets that are divisible by 4.');
end;
seek(lFdata,(lvox_offset div 4)+ (lStart-1) );
BlockRead(lFdata, lImgData[lRApos], (lEnd+1)-lStart);
@@ -282,7 +281,7 @@ begin
lImgData^[lRApos+lInc-1] := 0;
end;
end else
- showmessage('Unsupported COMPRESSED data type '+inttostr(lDataType));
+ ShowMsg('Unsupported COMPRESSED data type '+inttostr(lDataType));
closefile(lFdata);
end; //not gz
result := true;
@@ -300,14 +299,14 @@ var
begin
result := false;
if (lStart >= lEnd) or (lStart < 1) or (lEnd < 1) then begin
- MainForm.NPMmsg('Error: LoadImg '+inttostr(lStart)+'>='+inttostr(lEnd)+' or zero');
+ NPMmsg('Error: LoadImg '+inttostr(lStart)+'>='+inttostr(lEnd)+' or zero');
exit;
end;
if Files4D(lInName) then begin
lImgName := Filename4D(lInName);
lP2 := BPP (lDataType);
if lP2 = 0 then begin
- Showmessage(lImgName +' is an unsupported file type');
+ ShowMsg(lImgName +' is an unsupported file type');
exit;
end;
lvox_offset := linvox_offset+ ((Vol4D(lInName)-1)* (lP2 * lVolVox));
@@ -319,7 +318,7 @@ begin
lImgName := changefileext(lImgName,'.img');
lFSize := FSize(lImgName);
if (not GzExt(lImgName)) and (lFSize < (lEnd+ lvox_offset)) then begin
- MainForm.NPMmsg('Error: LoadImg '+lImgName+' FSize = '+inttostr(lFSize)+' Expected '+inttostr(lEnd+ lvox_offset));
+ NPMmsg('Error: LoadImg '+lImgName+' FSize = '+inttostr(lFSize)+' Expected '+inttostr(lEnd+ lvox_offset));
exit;
end;
filemode := 0;
@@ -363,7 +362,7 @@ begin
end;
freemem(lByteP);
end else begin
- showmessage(lImgName + ' is an unsupported compressed data type '+inttostr(lDataType));
+ ShowMsg(lImgName + ' is an unsupported compressed data type '+inttostr(lDataType));
exit;
end;
end else begin
@@ -380,7 +379,7 @@ begin
getmem(lSmallIntP, sizeof(smallint)* ((lEnd+1)-lStart));
reset(lFdata,2);
if (lvox_offset mod 2) <> 0 then begin
- showmessage('Error: this software can only read headers with dataoffsets that are divisible by 4.');
+ ShowMsg('Error: this software can only read headers with dataoffsets that are divisible by 4.');
end;
seek(lFdata,(lvox_offset div 2)+ (lStart-1));
BlockRead(lFdata, lSmallIntP^, (lEnd+1)-lStart);
@@ -391,7 +390,7 @@ begin
//next: 4 byte data
reset(lFdata,4);
if (lvox_offset mod 4) <> 0 then begin
- showmessage('Error: this software can only read headers with dataoffsets that are divisible by 4.');
+ ShowMsg('Error: this software can only read headers with dataoffsets that are divisible by 4.');
end;
seek(lFdata,(lvox_offset div 4)+ (lStart-1) );
getmem(lByteP, ((lEnd+1)-lStart)*sizeof(single));
@@ -417,10 +416,10 @@ begin
freemem(lByteP);
end else
- showmessage('Unsupported COMPRESSED data type '+inttostr(lDataType));
+ ShowMsg('Unsupported COMPRESSED data type '+inttostr(lDataType));
closefile(lFdata);
end; //not gz
result := true;
end;
-end.
+end.
\ No newline at end of file
diff --git a/npm/npm.app/Contents/Info.plist b/npm/npm.app/Contents/Info.plist
old mode 100644
new mode 100755
diff --git a/npm/npm.app/Contents/MacOS/npm b/npm/npm.app/Contents/MacOS/npm
old mode 100644
new mode 100755
diff --git a/npm/npm.app/Contents/PkgInfo b/npm/npm.app/Contents/PkgInfo
old mode 100644
new mode 100755
diff --git a/npm/npm.cfg b/npm/npm.cfg
old mode 100644
new mode 100755
index 22d5940..c599db3
--- a/npm/npm.cfg
+++ b/npm/npm.cfg
@@ -1,4 +1,4 @@
--$A+
+-$A8
-$B-
-$C+
-$D+
@@ -31,7 +31,8 @@
-M
-$M16384,1048576
-K$00400000
--LN"c:\program files\borland\delphi4\Lib"
+-LE"c:\program files (x86)\borland\delphi7\Projects\Bpl"
+-LN"c:\program files (x86)\borland\delphi7\Projects\Bpl"
-U"C:\pas\mricron\common;C:\pas\mricron\fpmath"
-O"C:\pas\mricron\common;C:\pas\mricron\fpmath"
-I"C:\pas\mricron\common;C:\pas\mricron\fpmath"
diff --git a/npm/npm.dof b/npm/npm.dof
old mode 100644
new mode 100755
index 269cd94..7fdd741
--- a/npm/npm.dof
+++ b/npm/npm.dof
@@ -1,5 +1,7 @@
+[FileVersion]
+Version=7.0
[Compiler]
-A=1
+A=8
B=0
C=1
D=1
@@ -28,6 +30,55 @@ Z=1
ShowHints=1
ShowWarnings=1
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+NamespacePrefix=
+SymbolDeprecated=1
+SymbolLibrary=1
+SymbolPlatform=1
+UnitLibrary=1
+UnitPlatform=1
+UnitDeprecated=1
+HResultCompat=1
+HidingMember=1
+HiddenVirtual=1
+Garbage=1
+BoundsError=1
+ZeroNilCompat=1
+StringConstTruncated=1
+ForLoopVarVarPar=1
+TypedConstVarPar=1
+AsgToTypedConst=1
+CaseLabelRange=1
+ForVariable=1
+ConstructingAbstract=1
+ComparisonFalse=1
+ComparisonTrue=1
+ComparingSignedUnsigned=1
+CombiningSignedUnsigned=1
+UnsupportedConstruct=1
+FileOpen=1
+FileOpenUnitSrc=1
+BadGlobalSymbol=1
+DuplicateConstructorDestructor=1
+InvalidDirective=1
+PackageNoLink=1
+PackageThreadVar=1
+ImplicitImport=1
+HPPEMITIgnored=1
+NoRetVal=1
+UseBeforeDef=1
+ForLoopVarUndef=1
+UnitNameMismatch=1
+NoCFGFileFound=1
+MessageDirective=1
+ImplicitVariants=1
+UnicodeToLocale=1
+LocaleToUnicode=1
+ImagebaseMultiple=1
+SuspiciousTypecast=1
+PrivatePropAccessor=1
+UnsafeType=1
+UnsafeCode=1
+UnsafeCast=1
[Linker]
MapFile=0
OutputObjs=0
@@ -51,6 +102,13 @@ UsePackages=0
[Parameters]
RunParams=
HostApplication=
+Launcher=
+UseLauncher=0
+DebugCWD=
+[Language]
+ActiveLang=
+ProjectLang=
+RootDir=
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
diff --git a/npm/npm.dpr b/npm/npm.dpr
old mode 100644
new mode 100755
diff --git a/npm/npm.dsk b/npm/npm.dsk
new file mode 100755
index 0000000..6852856
--- /dev/null
+++ b/npm/npm.dsk
@@ -0,0 +1,184 @@
+[Closed Files]
+File_0=SourceModule,'C:\pas\mricron\dcm2nii\niftiutil.pas',0,1,449,35,459,0,0
+File_1=SourceModule,'C:\pas\mricron\dcm2nii\dicomcompat.pas',0,1,5212,5,5221,0,0
+File_2=SourceModule,'C:\pas\mricron\dcm2nii\gui.pas',0,1,1,27,11,1,0
+File_3=SourceModule,'C:\pas\delphi\niftiview7\draw_interpolate_slices.pas',0,1,128,17,132,0,0
+File_4=SourceModule,'C:\pas\d7\rx275d7\Units\RXSpin.pas',0,1,1058,43,1066,0,0
+File_5=SourceModule,'C:\pas\delphi\niftiview7\pref_ini.pas',0,1,234,47,268,0,0
+File_6=SourceModule,'C:\pas\delphi\niftiview7\nifti_img_view.pas',0,1,3630,14,3645,1,0
+File_7=SourceModule,'C:\pas\delphi\niftiview7\ROIfilt.pas',0,1,24,1,34,0,0
+File_8=SourceModule,'C:\pas\delphi\niftiview7\nifti_img.pas',0,1,1547,23,1563,0,0
+
+[Modules]
+Module0=C:\pas\mricron\npm\npmform.pas
+Count=1
+EditWindowCount=1
+
+[C:\pas\mricron\npm\npmform.pas]
+ModuleType=SourceModule
+FormState=1
+FormOnTop=1
+
+[C:\Program Files (x86)\Borland\Delphi7\Bin\ProjectGroup1.bpg]
+FormState=0
+FormOnTop=0
+
+[C:\pas\mricron\npm\npm.dpr]
+FormState=0
+FormOnTop=0
+
+[EditWindow0]
+ViewCount=1
+CurrentView=0
+View0=0
+CodeExplorer=CodeExplorer at EditWindow0
+MessageView=MessageView at EditWindow0
+Create=1
+Visible=1
+State=0
+Left=905
+Top=100
+Width=1302
+Height=682
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1294
+ClientHeight=655
+LeftPanelSize=140
+LeftPanelClients=CodeExplorer at EditWindow0
+LeftPanelData=000004000000000000000000000000000000000000000000000100000000000000000C000000436F64654578706C6F726572FFFFFFFF
+RightPanelSize=0
+BottomPanelSize=0
+BottomPanelClients=MessageView at EditWindow0
+BottomPanelData=00000400010000000B0000004D657373616765566965770000000000000000000000000000000000FFFFFFFF
+
+[View0]
+Module=C:\pas\mricron\npm\npmform.pas
+CursorX=1
+CursorY=1
+TopLine=1
+LeftCol=1
+
+[Watches]
+Count=0
+
+[Breakpoints]
+Count=0
+
+[AddressBreakpoints]
+Count=0
+
+[Main Window]
+Create=1
+Visible=1
+State=0
+Left=0
+Top=0
+Width=1920
+Height=79
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=1912
+ClientHeight=52
+
+[ProjectManager]
+Create=1
+Visible=0
+State=0
+Left=369
+Top=372
+Width=438
+Height=303
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=430
+ClientHeight=279
+TBDockHeight=303
+LRDockWidth=438
+Dockable=1
+
+[AlignmentPalette]
+Create=1
+Visible=0
+State=0
+Left=200
+Top=81
+Width=156
+Height=82
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=150
+ClientHeight=60
+
+[PropertyInspector]
+Create=1
+Visible=1
+State=0
+Left=0
+Top=469
+Width=190
+Height=589
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=182
+ClientHeight=565
+TBDockHeight=589
+LRDockWidth=190
+Dockable=1
+SplitPos=85
+ArrangeBy=Name
+SelectedItem=Caption
+ExpandedItems=
+HiddenCategories=
+
+[ObjectTree]
+Create=1
+Visible=1
+State=0
+Left=0
+Top=79
+Width=190
+Height=388
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=182
+ClientHeight=364
+TBDockHeight=388
+LRDockWidth=190
+Dockable=1
+
+[CodeExplorer at EditWindow0]
+Create=1
+Visible=1
+State=0
+Left=0
+Top=12
+Width=140
+Height=643
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=140
+ClientHeight=643
+TBDockHeight=305
+LRDockWidth=140
+Dockable=1
+
+[MessageView at EditWindow0]
+Create=1
+Visible=0
+State=0
+Left=-711
+Top=-671
+Width=443
+Height=85
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=443
+ClientHeight=85
+TBDockHeight=85
+LRDockWidth=443
+Dockable=1
+
+[DockHosts]
+DockHostCount=0
+
diff --git a/npm/npm.ini b/npm/npm.ini
old mode 100644
new mode 100755
index e3e4fad..72a7f95
--- a/npm/npm.ini
+++ b/npm/npm.ini
@@ -5,6 +5,7 @@ countlesionpatterns=1
ROI=1
[INT]
-CacheMB=512
-nPermute=0
+CacheMB=888
+nPermute=4000
nThread=2
+TFCE=0
diff --git a/npm/npm.lpi b/npm/npm.lpi
old mode 100644
new mode 100755
index 0ba1297..fc30648
--- a/npm/npm.lpi
+++ b/npm/npm.lpi
@@ -1,19 +1,21 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
+ <Version Value="9"/>
<PathDelim Value="\"/>
- <Version Value="7"/>
<General>
<Flags>
<LRSInOutputDirectory Value="False"/>
</Flags>
<MainUnit Value="0"/>
- <TargetFileExt Value=".exe"/>
- <ActiveEditorIndexAtStart Value="2"/>
+ <ActiveWindowIndexAtStart Value="0"/>
</General>
<VersionInfo>
- <ProjectVersion Value=""/>
+ <StringTable ProductVersion=""/>
</VersionInfo>
+ <BuildModes Count="1">
+ <Item1 Name="default" Default="True"/>
+ </BuildModes>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
@@ -31,108 +33,120 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
- <Units Count="55">
+ <Units Count="67">
<Unit0>
<Filename Value="npm.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="npm"/>
- <CursorPos X="8" Y="13"/>
- <TopLine Value="1"/>
<EditorIndex Value="0"/>
- <UsageCount Value="39"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="34" Y="11"/>
+ <UsageCount Value="103"/>
<Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
</Unit0>
<Unit1>
<Filename Value="npmform.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
+ <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="npmform"/>
- <CursorPos X="47" Y="1490"/>
- <TopLine Value="1476"/>
+ <IsVisibleTab Value="True"/>
<EditorIndex Value="4"/>
- <UsageCount Value="39"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="102"/>
+ <CursorPos X="23" Y="130"/>
+ <UsageCount Value="103"/>
<Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
</Unit1>
<Unit2>
<Filename Value="nifti_hdr.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="nifti_hdr"/>
- <CursorPos X="49" Y="368"/>
<TopLine Value="358"/>
- <UsageCount Value="35"/>
+ <CursorPos X="49" Y="368"/>
+ <UsageCount Value="99"/>
</Unit2>
<Unit3>
<Filename Value="define_types.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="define_types"/>
- <CursorPos X="38" Y="959"/>
<TopLine Value="945"/>
- <UsageCount Value="35"/>
+ <CursorPos X="38" Y="959"/>
+ <UsageCount Value="99"/>
</Unit3>
<Unit4>
<Filename Value="GraphicsMathLibrary.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="GraphicsMathLibrary"/>
- <CursorPos X="1" Y="738"/>
<TopLine Value="681"/>
- <UsageCount Value="35"/>
+ <CursorPos X="1" Y="738"/>
+ <UsageCount Value="99"/>
</Unit4>
<Unit5>
<Filename Value="distr.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="distr"/>
- <CursorPos X="1" Y="107"/>
<TopLine Value="99"/>
- <UsageCount Value="35"/>
+ <CursorPos X="1" Y="107"/>
+ <UsageCount Value="99"/>
</Unit5>
<Unit6>
<Filename Value="statcr.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="statcr"/>
- <CursorPos X="34" Y="6"/>
- <TopLine Value="1"/>
- <UsageCount Value="35"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="4"/>
+ <CursorPos X="11" Y="25"/>
+ <UsageCount Value="99"/>
</Unit6>
<Unit7>
<Filename Value="stats.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="stats"/>
- <CursorPos X="41" Y="370"/>
<TopLine Value="369"/>
- <UsageCount Value="35"/>
+ <CursorPos X="41" Y="370"/>
+ <UsageCount Value="99"/>
</Unit7>
<Unit8>
<Filename Value="brunner.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="brunner"/>
- <CursorPos X="29" Y="517"/>
<TopLine Value="500"/>
- <UsageCount Value="35"/>
+ <CursorPos X="29" Y="517"/>
+ <UsageCount Value="99"/>
</Unit8>
<Unit9>
<Filename Value="StatThdsUtil.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="StatThdsUtil"/>
- <CursorPos X="69" Y="6"/>
+ <EditorIndex Value="2"/>
+ <WindowIndex Value="0"/>
<TopLine Value="1"/>
- <UsageCount Value="35"/>
+ <CursorPos X="11" Y="11"/>
+ <UsageCount Value="99"/>
+ <Loaded Value="True"/>
</Unit9>
<Unit10>
<Filename Value="StatThds.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="StatThds"/>
- <CursorPos X="59" Y="478"/>
- <TopLine Value="466"/>
- <UsageCount Value="35"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="24" Y="6"/>
+ <UsageCount Value="99"/>
</Unit10>
<Unit11>
<Filename Value="valformat.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="valformat"/>
- <CursorPos X="1" Y="91"/>
- <TopLine Value="64"/>
- <UsageCount Value="35"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="9" Y="12"/>
+ <UsageCount Value="99"/>
</Unit11>
<Unit12>
<Filename Value="design.pas"/>
@@ -141,11 +155,13 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="design"/>
- <CursorPos X="24" Y="52"/>
+ <EditorIndex Value="6"/>
+ <WindowIndex Value="0"/>
<TopLine Value="37"/>
- <EditorIndex Value="3"/>
- <UsageCount Value="34"/>
+ <CursorPos X="36" Y="58"/>
+ <UsageCount Value="98"/>
<Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
</Unit12>
<Unit13>
<Filename Value="spread.pas"/>
@@ -154,65 +170,71 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="spread"/>
- <CursorPos X="34" Y="591"/>
- <TopLine Value="587"/>
- <EditorIndex Value="2"/>
- <UsageCount Value="34"/>
+ <EditorIndex Value="5"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="557"/>
+ <CursorPos X="1" Y="584"/>
+ <UsageCount Value="98"/>
<Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
</Unit13>
<Unit14>
<Filename Value="gzio2.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="gzio2"/>
- <CursorPos X="22" Y="793"/>
<TopLine Value="774"/>
- <UsageCount Value="35"/>
+ <CursorPos X="22" Y="793"/>
+ <UsageCount Value="99"/>
</Unit14>
<Unit15>
<Filename Value="part.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="part"/>
- <CursorPos X="38" Y="108"/>
<TopLine Value="91"/>
- <UsageCount Value="35"/>
+ <CursorPos X="38" Y="108"/>
+ <UsageCount Value="99"/>
</Unit15>
<Unit16>
<Filename Value="markorder.pas"/>
<UnitName Value="markorder"/>
- <CursorPos X="44" Y="23"/>
<TopLine Value="8"/>
- <UsageCount Value="10"/>
+ <CursorPos X="44" Y="23"/>
+ <UsageCount Value="6"/>
</Unit16>
<Unit17>
<Filename Value="ztopform.pas"/>
<ComponentName Value="ZForm"/>
<UnitName Value="ztopform"/>
- <CursorPos X="18" Y="23"/>
<TopLine Value="9"/>
- <UsageCount Value="22"/>
+ <CursorPos X="18" Y="23"/>
+ <UsageCount Value="18"/>
</Unit17>
<Unit18>
<Filename Value="..\examples\opendialogcrash\unit1.pas"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
- <CursorPos X="40" Y="14"/>
<TopLine Value="19"/>
- <UsageCount Value="10"/>
+ <CursorPos X="40" Y="14"/>
+ <UsageCount Value="6"/>
</Unit18>
<Unit19>
<Filename Value="nifti_img.pas"/>
<UnitName Value="nifti_img"/>
- <CursorPos X="28" Y="54"/>
- <TopLine Value="52"/>
- <UsageCount Value="11"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="15" Y="1"/>
+ <UsageCount Value="9"/>
</Unit19>
<Unit20>
<Filename Value="lesion_pattern.pas"/>
<UnitName Value="lesion_pattern"/>
- <CursorPos X="25" Y="86"/>
- <TopLine Value="76"/>
- <UsageCount Value="10"/>
+ <EditorIndex Value="12"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="13" Y="21"/>
+ <UsageCount Value="11"/>
+ <Loaded Value="True"/>
</Unit20>
<Unit21>
<Filename Value="ReadInt.pas"/>
@@ -221,318 +243,498 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="ReadInt"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="23"/>
<CursorPos X="9" Y="50"/>
- <TopLine Value="33"/>
- <EditorIndex Value="1"/>
- <UsageCount Value="33"/>
- <Loaded Value="True"/>
+ <UsageCount Value="97"/>
</Unit21>
<Unit22>
<Filename Value="ReadInt.lrs"/>
<IsPartOfProject Value="True"/>
- <CursorPos X="1" Y="3"/>
<TopLine Value="1"/>
- <UsageCount Value="31"/>
+ <CursorPos X="1" Y="3"/>
+ <UsageCount Value="95"/>
</Unit22>
<Unit23>
<Filename Value="LesionStatThds.pas"/>
<UnitName Value="LesionStatThds"/>
- <CursorPos X="16" Y="3"/>
- <TopLine Value="1"/>
- <UsageCount Value="11"/>
+ <EditorIndex Value="14"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="173"/>
+ <CursorPos X="1" Y="193"/>
+ <UsageCount Value="33"/>
+ <Loaded Value="True"/>
</Unit23>
<Unit24>
<Filename Value="power.pas"/>
<UnitName Value="power"/>
- <CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="11"/>
+ <CursorPos X="1" Y="1"/>
+ <UsageCount Value="7"/>
</Unit24>
<Unit25>
<Filename Value="Mat.pas"/>
<UnitName Value="Mat"/>
- <CursorPos X="18" Y="239"/>
<TopLine Value="225"/>
- <UsageCount Value="11"/>
+ <CursorPos X="18" Y="239"/>
+ <UsageCount Value="7"/>
</Unit25>
<Unit26>
<Filename Value="Vector.pas"/>
<UnitName Value="Vector"/>
- <CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <CursorPos X="1" Y="1"/>
+ <UsageCount Value="6"/>
</Unit26>
<Unit27>
<Filename Value="firth.pas"/>
<UnitName Value="firth"/>
- <CursorPos X="19" Y="383"/>
- <TopLine Value="382"/>
- <UsageCount Value="10"/>
+ <EditorIndex Value="7"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="294"/>
+ <CursorPos X="38" Y="23"/>
+ <UsageCount Value="34"/>
+ <Loaded Value="True"/>
</Unit27>
<Unit28>
<Filename Value="overlap.pas"/>
<UnitName Value="overlap"/>
- <CursorPos X="1" Y="6"/>
- <TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="280"/>
+ <CursorPos X="23" Y="301"/>
+ <UsageCount Value="8"/>
</Unit28>
<Unit29>
<Filename Value="firthThds.pas"/>
<UnitName Value="firthThds"/>
- <CursorPos X="123" Y="315"/>
- <TopLine Value="312"/>
- <UsageCount Value="10"/>
+ <EditorIndex Value="8"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="605"/>
+ <CursorPos X="52" Y="36"/>
+ <UsageCount Value="29"/>
+ <Loaded Value="True"/>
</Unit29>
<Unit30>
<Filename Value="design.lfm"/>
- <CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
- <SyntaxHighlighter Value="LFM"/>
+ <CursorPos X="1" Y="1"/>
+ <UsageCount Value="6"/>
+ <DefaultSyntaxHighlighter Value="LFM"/>
</Unit30>
<Unit31>
<Filename Value="options.inc"/>
- <CursorPos X="21" Y="3"/>
<TopLine Value="1"/>
- <UsageCount Value="11"/>
+ <CursorPos X="21" Y="3"/>
+ <UsageCount Value="7"/>
</Unit31>
<Unit32>
<Filename Value="userdir.pas"/>
<UnitName Value="userdir"/>
- <CursorPos X="64" Y="45"/>
<TopLine Value="1"/>
- <UsageCount Value="11"/>
+ <CursorPos X="64" Y="45"/>
+ <UsageCount Value="7"/>
</Unit32>
<Unit33>
<Filename Value="..\..\lcl\forms.pp"/>
<UnitName Value="Forms"/>
- <CursorPos X="14" Y="661"/>
<TopLine Value="642"/>
- <UsageCount Value="11"/>
+ <CursorPos X="14" Y="661"/>
+ <UsageCount Value="7"/>
</Unit33>
<Unit34>
<Filename Value="..\gzio2.pas"/>
<UnitName Value="gzio2"/>
- <CursorPos X="22" Y="635"/>
<TopLine Value="627"/>
- <UsageCount Value="10"/>
+ <CursorPos X="22" Y="635"/>
+ <UsageCount Value="6"/>
</Unit34>
<Unit35>
<Filename Value="..\..\fpc\2.0.4\source\rtl\objpas\sysutils\finah.inc"/>
- <CursorPos X="22" Y="27"/>
<TopLine Value="17"/>
- <UsageCount Value="10"/>
+ <CursorPos X="22" Y="27"/>
+ <UsageCount Value="6"/>
</Unit35>
<Unit36>
<Filename Value="..\define_types.pas"/>
<UnitName Value="define_types"/>
- <CursorPos X="31" Y="5"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <CursorPos X="31" Y="5"/>
+ <UsageCount Value="6"/>
</Unit36>
<Unit37>
<Filename Value="..\..\fpc\2.0.4\source\rtl\win32\wininc\messages.inc"/>
- <CursorPos X="6" Y="1201"/>
<TopLine Value="1191"/>
- <UsageCount Value="10"/>
+ <CursorPos X="6" Y="1201"/>
+ <UsageCount Value="6"/>
</Unit37>
<Unit38>
<Filename Value="regression.pas"/>
<UnitName Value="regression"/>
- <CursorPos X="37" Y="16"/>
- <TopLine Value="1"/>
- <UsageCount Value="12"/>
+ <EditorIndex Value="3"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="90"/>
+ <CursorPos X="44" Y="106"/>
+ <UsageCount Value="39"/>
+ <Loaded Value="True"/>
</Unit38>
<Unit39>
<Filename Value="Regmult.pas"/>
<UnitName Value="RegMult"/>
- <CursorPos X="27" Y="43"/>
<TopLine Value="30"/>
- <UsageCount Value="10"/>
+ <CursorPos X="27" Y="43"/>
+ <UsageCount Value="6"/>
</Unit39>
<Unit40>
<Filename Value="..\fpmath\regmult.pas"/>
<UnitName Value="regmult"/>
- <CursorPos X="69" Y="45"/>
<TopLine Value="39"/>
- <UsageCount Value="10"/>
+ <CursorPos X="69" Y="45"/>
+ <UsageCount Value="6"/>
</Unit40>
<Unit41>
<Filename Value="..\common\distr.pas"/>
<UnitName Value="distr"/>
- <CursorPos X="1" Y="308"/>
<TopLine Value="296"/>
- <UsageCount Value="11"/>
+ <CursorPos X="1" Y="308"/>
+ <UsageCount Value="7"/>
</Unit41>
<Unit42>
<Filename Value="..\common\define_types.pas"/>
<UnitName Value="define_types"/>
- <CursorPos X="40" Y="16"/>
- <TopLine Value="4"/>
- <UsageCount Value="11"/>
+ <EditorIndex Value="9"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="124"/>
+ <CursorPos X="23" Y="148"/>
+ <UsageCount Value="36"/>
+ <Loaded Value="True"/>
</Unit42>
<Unit43>
<Filename Value="hdr.pas"/>
<UnitName Value="hdr"/>
- <CursorPos X="1" Y="3"/>
- <TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <EditorIndex Value="13"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="404"/>
+ <CursorPos X="22" Y="418"/>
+ <UsageCount Value="31"/>
+ <Loaded Value="True"/>
</Unit43>
<Unit44>
<Filename Value="..\common\gzio2.pas"/>
<UnitName Value="gzio2"/>
- <CursorPos X="16" Y="236"/>
<TopLine Value="223"/>
- <UsageCount Value="10"/>
+ <CursorPos X="16" Y="236"/>
+ <UsageCount Value="6"/>
</Unit44>
<Unit45>
<Filename Value="..\common\nifti_hdr.pas"/>
<UnitName Value="nifti_hdr"/>
- <CursorPos X="1" Y="121"/>
- <TopLine Value="119"/>
- <UsageCount Value="11"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="52" Y="14"/>
+ <UsageCount Value="9"/>
</Unit45>
<Unit46>
<Filename Value="..\common\GraphicsMathLibrary.pas"/>
<UnitName Value="GraphicsMathLibrary"/>
- <CursorPos X="17" Y="8"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <CursorPos X="17" Y="8"/>
+ <UsageCount Value="6"/>
</Unit46>
<Unit47>
<Filename Value="..\fpmath\utypes.pas"/>
<UnitName Value="utypes"/>
- <CursorPos X="41" Y="482"/>
<TopLine Value="470"/>
- <UsageCount Value="12"/>
+ <CursorPos X="41" Y="482"/>
+ <UsageCount Value="8"/>
</Unit47>
<Unit48>
<Filename Value="lesion.pas"/>
<UnitName Value="lesion"/>
- <CursorPos X="64" Y="313"/>
<TopLine Value="299"/>
- <UsageCount Value="10"/>
+ <CursorPos X="64" Y="313"/>
+ <UsageCount Value="6"/>
</Unit48>
<Unit49>
<Filename Value="anacom.pas"/>
<UnitName Value="anacom"/>
- <CursorPos X="32" Y="593"/>
<TopLine Value="579"/>
- <UsageCount Value="10"/>
+ <CursorPos X="32" Y="593"/>
+ <UsageCount Value="6"/>
</Unit49>
<Unit50>
<Filename Value="filename.pas"/>
<UnitName Value="filename"/>
- <CursorPos X="6" Y="4"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <CursorPos X="6" Y="4"/>
+ <UsageCount Value="6"/>
</Unit50>
<Unit51>
<Filename Value="montecarlo.pas"/>
<UnitName Value="montecarlo"/>
- <CursorPos X="6" Y="3"/>
+ <WindowIndex Value="0"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <CursorPos X="6" Y="3"/>
+ <UsageCount Value="7"/>
</Unit51>
<Unit52>
<Filename Value="roc.pas"/>
<UnitName Value="roc"/>
- <CursorPos X="33" Y="344"/>
- <TopLine Value="317"/>
- <UsageCount Value="10"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="2"/>
+ <CursorPos X="41" Y="14"/>
+ <UsageCount Value="7"/>
</Unit52>
<Unit53>
<Filename Value="..\fpmath\types.inc"/>
- <CursorPos X="15" Y="163"/>
- <TopLine Value="163"/>
- <UsageCount Value="12"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="153"/>
+ <CursorPos X="3" Y="174"/>
+ <UsageCount Value="11"/>
</Unit53>
<Unit54>
- <Filename Value="..\..\..\Developer\lazarus\lcl\interfaces\carbon\carbonprivatecommon.inc"/>
- <CursorPos X="1" Y="184"/>
+ <Filename Value="C:\Developer\lazarus\lcl\interfaces\carbon\carbonprivatecommon.inc"/>
<TopLine Value="170"/>
- <UsageCount Value="10"/>
+ <CursorPos X="1" Y="184"/>
+ <UsageCount Value="6"/>
</Unit54>
+ <Unit55>
+ <Filename Value="tfce_clustering.pas"/>
+ <UnitName Value="tfce_clustering"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="128" Y="8"/>
+ <UsageCount Value="8"/>
+ </Unit55>
+ <Unit56>
+ <Filename Value="C:\Developer\lazarus\lcl\include\menuitem.inc"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="61"/>
+ <CursorPos X="1" Y="83"/>
+ <UsageCount Value="8"/>
+ </Unit56>
+ <Unit57>
+ <Filename Value="..\common\isgui.inc"/>
+ <EditorIndex Value="15"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="10" Y="1"/>
+ <UsageCount Value="32"/>
+ <Loaded Value="True"/>
+ </Unit57>
+ <Unit58>
+ <Filename Value="..\common\dialogsx.pas"/>
+ <UnitName Value="dialogsx"/>
+ <EditorIndex Value="10"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="8"/>
+ <CursorPos X="10" Y="35"/>
+ <UsageCount Value="31"/>
+ <Loaded Value="True"/>
+ </Unit58>
+ <Unit59>
+ <Filename Value="..\common\dicomhdr.pas"/>
+ <UnitName Value="dicomhdr"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="13" Y="7"/>
+ <UsageCount Value="6"/>
+ </Unit59>
+ <Unit60>
+ <Filename Value="unpm.pas"/>
+ <UnitName Value="unpm"/>
+ <EditorIndex Value="1"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="20"/>
+ <CursorPos X="84" Y="43"/>
+ <UsageCount Value="37"/>
+ <Loaded Value="True"/>
+ </Unit60>
+ <Unit61>
+ <Filename Value="turbolesion.pas"/>
+ <UnitName Value="turbolesion"/>
+ <EditorIndex Value="11"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="94" Y="6"/>
+ <UsageCount Value="33"/>
+ <Loaded Value="True"/>
+ </Unit61>
+ <Unit62>
+ <Filename Value="prefs.pas"/>
+ <UnitName Value="prefs"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="121"/>
+ <CursorPos X="21" Y="134"/>
+ <UsageCount Value="31"/>
+ </Unit62>
+ <Unit63>
+ <Filename Value="C:\usr\local\share\fpcsrc\rtl\objpas\sysutils\sysstrh.inc"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="10" Y="107"/>
+ <UsageCount Value="7"/>
+ </Unit63>
+ <Unit64>
+ <Filename Value="..\common\cpucount.pas"/>
+ <UnitName Value="cpucount"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="10" Y="5"/>
+ <UsageCount Value="31"/>
+ </Unit64>
+ <Unit65>
+ <Filename Value="C:\Developer\lazarus\lcl\include\progressbar.inc"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="155"/>
+ <CursorPos X="1" Y="178"/>
+ <UsageCount Value="8"/>
+ </Unit65>
+ <Unit66>
+ <Filename Value="C:\Developer\lazarus\lcl\dialogs.pp"/>
+ <UnitName Value="Dialogs"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="486"/>
+ <CursorPos X="10" Y="500"/>
+ <UsageCount Value="31"/>
+ </Unit66>
</Units>
- <JumpHistory Count="17" HistoryIndex="16">
+ <JumpHistory Count="30" HistoryIndex="29">
<Position1>
- <Filename Value="npm.lpr"/>
- <Caret Line="7" Column="3" TopLine="1"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="371" Column="29" TopLine="344"/>
</Position1>
<Position2>
- <Filename Value="npm.lpr"/>
- <Caret Line="27" Column="30" TopLine="1"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="424" Column="113" TopLine="389"/>
</Position2>
<Position3>
- <Filename Value="npm.lpr"/>
- <Caret Line="26" Column="1" TopLine="1"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="506" Column="53" TopLine="471"/>
</Position3>
<Position4>
- <Filename Value="npmform.pas"/>
- <Caret Line="2147" Column="16" TopLine="2137"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="9" Column="89" TopLine="1"/>
</Position4>
<Position5>
- <Filename Value="npmform.pas"/>
- <Caret Line="39" Column="54" TopLine="31"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="424" Column="44" TopLine="397"/>
</Position5>
<Position6>
- <Filename Value="npmform.pas"/>
- <Caret Line="108" Column="22" TopLine="79"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="11" Column="44" TopLine="1"/>
</Position6>
<Position7>
- <Filename Value="npmform.pas"/>
- <Caret Line="1678" Column="32" TopLine="1649"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="18" Column="14" TopLine="1"/>
</Position7>
<Position8>
- <Filename Value="npmform.pas"/>
- <Caret Line="1729" Column="63" TopLine="1700"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="5" Column="47" TopLine="1"/>
</Position8>
<Position9>
- <Filename Value="npmform.pas"/>
- <Caret Line="56" Column="204" TopLine="52"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="18" Column="14" TopLine="1"/>
</Position9>
<Position10>
- <Filename Value="npmform.pas"/>
- <Caret Line="108" Column="28" TopLine="52"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="290" Column="62" TopLine="272"/>
</Position10>
<Position11>
- <Filename Value="npmform.pas"/>
- <Caret Line="1678" Column="1" TopLine="1675"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="30" Column="122" TopLine="20"/>
</Position11>
<Position12>
- <Filename Value="npmform.pas"/>
- <Caret Line="2089" Column="19" TopLine="2032"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="19" Column="153" TopLine="16"/>
</Position12>
<Position13>
- <Filename Value="npmform.pas"/>
- <Caret Line="2091" Column="57" TopLine="2072"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="5" Column="150" TopLine="2"/>
</Position13>
<Position14>
- <Filename Value="npm.lpr"/>
- <Caret Line="26" Column="1" TopLine="3"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="194" Column="19" TopLine="158"/>
</Position14>
<Position15>
- <Filename Value="npmform.pas"/>
- <Caret Line="1494" Column="7" TopLine="1482"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="10" Column="112" TopLine="1"/>
</Position15>
<Position16>
- <Filename Value="npmform.pas"/>
- <Caret Line="3" Column="109" TopLine="1"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="200" Column="83" TopLine="193"/>
</Position16>
<Position17>
- <Filename Value="npmform.pas"/>
- <Caret Line="111" Column="21" TopLine="103"/>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="14" Column="58" TopLine="1"/>
</Position17>
+ <Position18>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="113" Column="6" TopLine="84"/>
+ </Position18>
+ <Position19>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="127" Column="30" TopLine="98"/>
+ </Position19>
+ <Position20>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="13" Column="126" TopLine="1"/>
+ </Position20>
+ <Position21>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="22" Column="97" TopLine="5"/>
+ </Position21>
+ <Position22>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="216" Column="35" TopLine="205"/>
+ </Position22>
+ <Position23>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="220" Column="22" TopLine="204"/>
+ </Position23>
+ <Position24>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="218" Column="13" TopLine="203"/>
+ </Position24>
+ <Position25>
+ <Filename Value="turbolesion.pas"/>
+ <Caret Line="213" Column="32" TopLine="204"/>
+ </Position25>
+ <Position26>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="129" Column="66" TopLine="7"/>
+ </Position26>
+ <Position27>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="4" Column="90" TopLine="1"/>
+ </Position27>
+ <Position28>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="38" Column="5" TopLine="29"/>
+ </Position28>
+ <Position29>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="7" Column="41" TopLine="1"/>
+ </Position29>
+ <Position30>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="38" Column="13" TopLine="9"/>
+ </Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
- <Version Value="8"/>
+ <Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
- <OtherUnitFiles Value="..\fpmath\;..\common\"/>
+ <OtherUnitFiles Value="..\fpmath;..\common"/>
</SearchPaths>
+ <Parsing>
+ <SyntaxOptions>
+ <UseAnsiStrings Value="False"/>
+ </SyntaxOptions>
+ </Parsing>
<Linking>
<Debugging>
+ <GenerateDebugInfo Value="False"/>
<UseLineInfoUnit Value="False"/>
<StripSymbols Value="True"/>
</Debugging>
@@ -545,9 +747,9 @@
</Options>
</Linking>
<Other>
- <ConfigFile>
- <CustomConfigFile Value="True"/>
- </ConfigFile>
+ <CompilerMessages>
+ <UseMsgFile Value="True"/>
+ </CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
diff --git a/npm/npm.lpr b/npm/npm.lpr
old mode 100644
new mode 100755
diff --git a/npm/npm.or b/npm/npm.or
old mode 100644
new mode 100755
index 1d4bbd3..4a3628d
Binary files a/npm/npm.or and b/npm/npm.or differ
diff --git a/npm/npm.res b/npm/npm.res
old mode 100644
new mode 100755
diff --git a/npm/npmcl.lpi b/npm/npmcl.lpi
new file mode 100755
index 0000000..bbb2fa4
--- /dev/null
+++ b/npm/npmcl.lpi
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<CONFIG>
+ <ProjectOptions>
+ <Version Value="9"/>
+ <General>
+ <Flags>
+ <MainUnitHasCreateFormStatements Value="False"/>
+ </Flags>
+ <SessionStorage Value="InProjectDir"/>
+ <MainUnit Value="0"/>
+ <Title Value="NPMcl"/>
+ <UseAppBundle Value="False"/>
+ <ResourceType Value="res"/>
+ </General>
+ <i18n>
+ <EnableI18N LFM="False"/>
+ </i18n>
+ <VersionInfo>
+ <StringTable ProductVersion=""/>
+ </VersionInfo>
+ <BuildModes Count="1">
+ <Item1 Name="Default" Default="True"/>
+ </BuildModes>
+ <PublishOptions>
+ <Version Value="2"/>
+ <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+ <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ </local>
+ </RunParams>
+ <Units Count="2">
+ <Unit0>
+ <Filename Value="npmcl.lpr"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="npmcl"/>
+ </Unit0>
+ <Unit1>
+ <Filename Value="unpm.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="unpm"/>
+ </Unit1>
+ </Units>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="11"/>
+ <Target>
+ <Filename Value="npmcl"/>
+ </Target>
+ <SearchPaths>
+ <IncludeFiles Value="$(ProjOutDir)"/>
+ <OtherUnitFiles Value="../common;../fpmath"/>
+ <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
+ </SearchPaths>
+ <Other>
+ <CompilerMessages>
+ <MsgFileName Value=""/>
+ </CompilerMessages>
+ <CompilerPath Value="$(CompPath)"/>
+ </Other>
+ </CompilerOptions>
+ <Debugging>
+ <Exceptions Count="3">
+ <Item1>
+ <Name Value="EAbort"/>
+ </Item1>
+ <Item2>
+ <Name Value="ECodetoolError"/>
+ </Item2>
+ <Item3>
+ <Name Value="EFOpenError"/>
+ </Item3>
+ </Exceptions>
+ </Debugging>
+</CONFIG>
diff --git a/npm/npmcl.lpr b/npm/npmcl.lpr
new file mode 100755
index 0000000..31ed43c
--- /dev/null
+++ b/npm/npmcl.lpr
@@ -0,0 +1,187 @@
+program npmcl;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ //cthreads,
+ {$ENDIF}{$ENDIF}
+ cthreads,
+
+ Classes, SysUtils, CustApp,prefs, unpm, userdir,StatThdsUtil, cpucount, define_types, turbolesion;
+
+type
+ TNPMcl = class(TCustomApplication)
+ protected
+ procedure DoRun; override;
+ public
+ constructor Create(TheOwner: TComponent); override;
+ destructor Destroy; override;
+ function GetOptionValueInt(lCmd: string; lDefault: integer): integer;
+ //procedure WriteHelp; virtual;
+ procedure ThreadDone(Sender: TObject);
+ end;
+
+var
+ Application: TNPMcl;
+
+procedure msg(s: string);
+begin
+ { add your help code here }
+ writeln(s);
+end;
+
+
+
+
+procedure ShowOptions (lTestInt: integer; lMaskFilename,lOutFilename: string);
+begin
+ msg(' -c : CPU threads, Default : '+inttostr(gnCPUThreads));
+ msg(' -m : mask name. Default "' +lMaskFilename+'"');
+ msg(' -n : neighbors for TFCE, 0 for none. Default ' +inttostr(gNPMprefs.TFCE));
+ msg(' -o : output name. Default "' +lOutFilename+'"');
+ msg(' -p : Permutations, 0 for none. Default '+inttostr(gNPMprefs.nPermute));
+ msg(' -r : RAM for processing (Mb). Default '+inttostr(kPlankMB));
+ msg(' -t : test (0=continuous,1=binomial,2=regress,3=multiregress). Default '+inttostr(lTestInt));
+
+end;
+
+procedure WriteHelp ;
+begin
+ msg(GetKVers);
+ msg(' usage: '+ExtractFileName(FileNameNoExt(paramstr(0)))+' [options] [-t test] [valfilename]' );
+ msg('Examples:');
+ msg(' '+ ExtractFileName(FileNameNoExt(paramstr(0)))+' -t 0 test.val');
+ msg(' '+ ExtractFileName(FileNameNoExt(paramstr(0)))+' -r 1024 -p 1000 -m mymask.nii -t 0 test.val');
+ msg('Options:');
+ msg(' -h : Help displayed');
+end;
+
+procedure TNPMcl.ThreadDone(Sender: TObject);
+begin
+ Dec(gThreadsRunning);
+end;
+function TNPMcl.GetOptionValueInt(lCmd: string; lDefault: integer): integer;
+var
+ lResp : string;
+begin
+ lResp := GetOptionValue(lCmd);
+ if length(lResp) < 1 then result := lDefault;
+ try
+ result := strtoint(lResp);
+ except
+ Writeln('Error '+(lResp)+' is not a valid integer.');
+ result := lDefault;
+ end;
+
+
+end;
+
+procedure doVLSM(lBinomial: boolean; VALFilename, lMaskFilename,lOutFilename: string);
+ var
+ lPrefs: TLDMPrefs ;
+begin
+ lPrefs.NULP := gNPMPrefs.NULP;
+ if (not lBinomial) then begin //continuous
+ lPrefs.BMtest := true;
+ lPrefs.Ttest := true;
+ lPrefs.Ltest:= false;
+ end else begin //binomial
+ lPrefs.BMtest := false;
+ lPrefs.Ttest := false;
+ lPrefs.Ltest:= true;
+ end;
+ lPrefs.CritPct := -1;
+ lPrefs.nPermute := gNPMprefs.nPermute;
+ lPrefs.Run := 0;{0 except for montecarlo}
+ lPrefs.VALFilename := VALFilename;
+ lPrefs.OutName := lOutFilename;
+ lPrefs.ExplicitMaskName := lMaskFilename;
+ DoLesion (lPrefs);
+end;
+
+
+
+procedure TNPMcl.DoRun;
+label
+ 666;
+var
+ lTestInt: integer = 0;
+ lMaskFilename : string = '';
+ lValFilename : string = '';
+ lOutFilename : string = '';
+begin
+ gnCPUThreads := GetLogicalCpuCount;
+ ReadIniFile;
+ // parse parameters
+ if (HasOption('h','help')) or (ParamCount = 0) then begin
+ WriteHelp;
+ ShowOptions(lTestInt, lMaskFilename, lOutFilename);
+ goto 666;
+ end;
+ if (HasOption('c')) then gnCPUThreads := GetOptionValueInt('c', gnCPUThreads);
+ if (HasOption('m')) then begin
+ lMaskFilename := GetOptionValue('m');
+ if not (not FileExistsEX(lMaskFilename)) then begin
+ writeln('Can not fine masking image '+ lMaskFilename);
+ goto 666;
+ end;
+ end;
+ if (HasOption('n')) then gnCPUThreads := GetOptionValueInt('n', gNPMprefs.TFCE);
+ if (HasOption('o')) then begin
+ lOutFilename := GetOptionValue('o');
+ end;
+ if (HasOption('p')) then gNPMprefs.nPermute := GetOptionValueInt('p', gNPMprefs.nPermute);
+ if (HasOption('r')) then begin
+ kPlankMB := GetOptionValueInt('r', kPlankMB);
+ ComputePlankSize(kPlankMB);
+ end;
+ if (HasOption('t')) then lTestInt := GetOptionValueInt('t', lTestInt);
+
+
+ lValFilename := (paramstr(ParamCount));
+ if (UpCaseExt(lValFilename) <> '.VAL') or (not FileExistsEX(lValFilename)) then begin
+ Writeln('Error: final option should be an existing file with the .val extension');
+ goto 666;
+ end;
+
+ if (lOutFilename = '') then begin
+ lOutFilename := ChangeFileExtX( lValFilename,'');
+ end;
+ //show settings
+ ShowOptions(lTestInt,lMaskFilename,lOutFilename);
+ Writeln('VAL File: '+lValFilename);
+ //run test
+ case lTestInt of
+ 0: doVLSM(false, lVALFilename, lMaskFilename,lOutFilename);//continuous : t-test
+ 1: doVLSM(true, lVALFilename, lMaskFilename,lOutFilename);//binomial: Liebermeister
+ 2: NPMSingleRegress ( lVALFilename, lMaskFilename,lOutFilename);
+ 3: NPMMultipleRegressClick( lVALFilename, lMaskFilename,lOutFilename);
+ end;
+
+
+ WriteIniFile;
+ // stop program loop
+ 666:
+ Terminate;
+end;
+
+constructor TNPMcl.Create(TheOwner: TComponent);
+begin
+ inherited Create(TheOwner);
+ StopOnException:=True;
+end;
+
+destructor TNPMcl.Destroy;
+begin
+ inherited Destroy;
+end;
+
+
+begin
+ Application:=TNPMcl.Create(nil);
+ Application.Title:='NPMcl';
+ Application.Run;
+ Application.Free;
+end.
+
diff --git a/npm/npmform.dfm b/npm/npmform.dfm
old mode 100644
new mode 100755
index 1cffcf9..ac7d3e3
Binary files a/npm/npmform.dfm and b/npm/npmform.dfm differ
diff --git a/npm/npmform.lfm b/npm/npmform.lfm
old mode 100644
new mode 100755
index e66d0cb..701cedc
--- a/npm/npmform.lfm
+++ b/npm/npmform.lfm
@@ -1,7 +1,7 @@
object MainForm: TMainForm
- Left = 714
+ Left = 468
Height = 418
- Top = 60
+ Top = 213
Width = 542
ActiveControl = Memo1
Caption = 'Non-Parametric Mapping'
@@ -12,7 +12,7 @@ object MainForm: TMainForm
OnCreate = FormCreate
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '0.9.29'
+ LCLVersion = '1.0.2.0'
object Memo1: TMemo
Left = 0
Height = 374
@@ -68,9 +68,9 @@ object MainForm: TMainForm
ShortCut = 16450
OnClick = LesionBtnClick
end
- object Binaryimagescontinuousgroupsvlsm1: TMenuItem
+ object Binaryimagescontinuousgroupsfast1: TMenuItem
Tag = 1
- Caption = 'Binary images, continuous grooups (vlsm)'
+ Caption = 'Binary images, continuous groups (vlsm)'
ShortCut = 16460
OnClick = LesionBtnClick
end
@@ -99,15 +99,15 @@ object MainForm: TMainForm
Caption = 'Paired Measures T-test'
OnClick = PairedTMenuClick
end
- object MenuItem1: TMenuItem
+ object MultipleRegress: TMenuItem
Caption = 'Multiple WLS Regression'
OnClick = MultipleRegressClick
end
- object MenuItem2: TMenuItem
+ object SingleRegress: TMenuItem
Caption = 'Single WLS Regression'
OnClick = SingleRegressClick
end
- object MenuItem3: TMenuItem
+ object DualImageCorrelation1: TMenuItem
Caption = 'Dual image correlation'
OnClick = DualImageCorrelation1Click
end
@@ -229,13 +229,13 @@ object MainForm: TMainForm
OnClick = threadChange
end
end
+ object PlankSzMenuItem1: TMenuItem
+ Caption = 'Plank Size'
+ OnClick = PlankSzMenuItem1Click
+ end
end
object Utilities1: TMenuItem
Caption = 'Utilities'
- object niiniigz1: TMenuItem
- Caption = 'nii -> .nii.gz'
- OnClick = niiniigz1Click
- end
object Variance1: TMenuItem
Caption = 'Variance image'
OnClick = Variance1Click
@@ -262,17 +262,10 @@ object MainForm: TMainForm
Caption = 'Intensity normalization B'
OnClick = Balance1Click
end
- object PhysiologicalArtifactCorrection1: TMenuItem
- Caption = 'Physiological Correction'
- OnClick = PhysiologicalArtifactCorrection1Click
- end
- object Countlesionoverlaps1: TMenuItem
- Caption = 'Count lesion overlaps'
- OnClick = Countlesionoverlaps1Click
- end
end
object Help1: TMenuItem
Caption = 'Help'
+ Visible = False
object About1: TMenuItem
Caption = 'About'
OnClick = About1Click
@@ -289,4 +282,10 @@ object MainForm: TMainForm
left = 8
top = 72
end
+ object StartTimer: TTimer
+ Enabled = False
+ OnTimer = StartTimerTimer
+ left = 141
+ top = 67
+ end
end
diff --git a/npm/npmform.lrs b/npm/npmform.lrs
old mode 100644
new mode 100755
index 66b3d37..c33e69c
--- a/npm/npmform.lrs
+++ b/npm/npmform.lrs
@@ -1,14 +1,14 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TMainForm','FORMDATA',[
- 'TPF0'#9'TMainForm'#8'MainForm'#4'Left'#3#202#2#6'Height'#3#162#1#3'Top'#2'<'
- +#5'Width'#3#30#2#13'ActiveControl'#7#5'Memo1'#7'Caption'#6#22'Non-Parametric'
- +' Mapping'#12'ClientHeight'#3#143#1#11'ClientWidth'#3#30#2#4'Menu'#7#9'MainM'
- +'enu1'#7'OnClose'#7#9'FormClose'#8'OnCreate'#7#10'FormCreate'#6'OnShow'#7#8
- +'FormShow'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#6'0.9.29'#0#5'T'
- +'Memo'#5'Memo1'#4'Left'#2#0#6'Height'#3'v'#1#3'Top'#2#0#5'Width'#3#30#2#5'Al'
- +'ign'#7#8'alClient'#10'ScrollBars'#7#10'ssAutoBoth'#8'TabOrder'#2#0#0#0#6'TP'
- +'anel'#6'Panel1'#4'Left'#2#0#6'Height'#2#25#3'Top'#3'v'#1#5'Width'#3#30#2#5
+ 'TPF0'#9'TMainForm'#8'MainForm'#4'Left'#3#212#1#6'Height'#3#162#1#3'Top'#3#213
+ +#0#5'Width'#3#30#2#13'ActiveControl'#7#5'Memo1'#7'Caption'#6#22'Non-Parametr'
+ +'ic Mapping'#12'ClientHeight'#3#143#1#11'ClientWidth'#3#30#2#4'Menu'#7#9'Mai'
+ +'nMenu1'#7'OnClose'#7#9'FormClose'#8'OnCreate'#7#10'FormCreate'#6'OnShow'#7#8
+ +'FormShow'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#7'1.0.2.0'#0#5
+ +'TMemo'#5'Memo1'#4'Left'#2#0#6'Height'#3'v'#1#3'Top'#2#0#5'Width'#3#30#2#5'A'
+ +'lign'#7#8'alClient'#10'ScrollBars'#7#10'ssAutoBoth'#8'TabOrder'#2#0#0#0#6'T'
+ +'Panel'#6'Panel1'#4'Left'#2#0#6'Height'#2#25#3'Top'#3'v'#1#5'Width'#3#30#2#5
+'Align'#7#8'alBottom'#12'ClientHeight'#2#25#11'ClientWidth'#3#30#2#8'TabOrde'
+'r'#2#1#0#12'TProgressBar'#12'ProgressBar1'#4'Left'#2#1#6'Height'#2#23#3'Top'
+#2#1#5'Width'#3#28#2#5'Align'#7#8'alClient'#8'TabOrder'#2#0#0#0#0#9'TMainMen'
@@ -20,7 +20,7 @@ LazarusResources.Add('TMainForm','FORMDATA',[
+'TMenuItem'#5'VLSM1'#7'Caption'#6#4'VLSM'#0#9'TMenuItem'#24'BinomialAnalysis'
+'lesions1'#7'Caption'#6'''Binary images, binary groups (lesions) '#8'ShortCu'
+'t'#3'B@'#7'OnClick'#7#14'LesionBtnClick'#0#0#9'TMenuItem!Binaryimagescontin'
- +'uousgroupsvlsm1'#3'Tag'#2#1#7'Caption'#6'(Binary images, continuous grooups'
+ +'uousgroupsfast1'#3'Tag'#2#1#7'Caption'#6'''Binary images, continuous groups'
+' (vlsm)'#8'ShortCut'#3'L@'#7'OnClick'#7#14'LesionBtnClick'#0#0#9'TMenuItem'
+#28'PenalizedLogisticRegerssion1'#7'Caption'#6#31'Binary images, multiple fa'
+'ctors'#7'OnClick'#7'!PenalizedLogisticRegerssion1Click'#0#0#9'TMenuItem'#12
@@ -30,56 +30,54 @@ LazarusResources.Add('TMainForm','FORMDATA',[
+#0#9'TMenuItem'#22'ContinuousanalysisVBM1'#7'Caption'#6'&Continuous images, '
+'binary groups (VBM)'#8'ShortCut'#3'V@'#7'OnClick'#7#8'NPMclick'#0#0#9'TMenu'
+'Item'#11'PairedTMenu'#7'Caption'#6#22'Paired Measures T-test'#7'OnClick'#7
- +#16'PairedTMenuClick'#0#0#9'TMenuItem'#9'MenuItem1'#7'Caption'#6#23'Multiple'
- +' WLS Regression'#7'OnClick'#7#20'MultipleRegressClick'#0#0#9'TMenuItem'#9'M'
- +'enuItem2'#7'Caption'#6#21'Single WLS Regression'#7'OnClick'#7#18'SingleRegr'
- +'essClick'#0#0#9'TMenuItem'#9'MenuItem3'#7'Caption'#6#22'Dual image correlat'
- +'ion'#7'OnClick'#7#26'DualImageCorrelation1Click'#0#0#0#9'TMenuItem'#8'Optio'
- +'ns1'#7'Caption'#6#7'Options'#0#9'TMenuItem'#13'Permutations1'#7'Caption'#6
- +#12'Permutations'#0#9'TMenuItem'#2'N0'#9'AutoCheck'#9#7'Caption'#6#4'None'#7
- +'Checked'#9#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclic'
- +'k'#0#0#9'TMenuItem'#5'N1000'#3'Tag'#3#232#3#9'AutoCheck'#9#7'Caption'#6#4'1'
- +'000'#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'#0#0
- +#9'TMenuItem'#5'N2000'#3'Tag'#3#208#7#9'AutoCheck'#9#7'Caption'#6#4'2000'#10
- +'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'#0#0#9'TMenu'
- +'Item'#5'N3000'#3'Tag'#3#184#11#9'AutoCheck'#9#7'Caption'#6#4'3000'#10'Group'
- +'Index'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'#0#0#9'TMenuItem'
- +#5'N4000'#3'Tag'#3#160#15#9'AutoCheck'#9#7'Caption'#6#4'4000'#10'GroupIndex'
- +#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'#0#0#0#9'TMenuItem'#6'Te'
- +'sts1'#7'Caption'#6#5'Tests'#0#9'TMenuItem'#9'ttestmenu'#7'Caption'#6#6't-te'
- +'st'#7'OnClick'#7#13'testmenuclick'#0#0#9'TMenuItem'#6'BMmenu'#7'Caption'#6
- +#14'Brunner Munzel'#7'Checked'#9#7'OnClick'#7#13'testmenuclick'#0#0#0#9'TMen'
- +'uItem'#8'Threads1'#7'Caption'#6#7'Threads'#0#9'TMenuItem'#2'T1'#9'AutoCheck'
- +#9#7'Caption'#6#1'1'#7'Checked'#9#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'On'
- +'Click'#7#12'threadChange'#0#0#9'TMenuItem'#2'T2'#9'AutoCheck'#9#7'Caption'#6
- +#1'2'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0
- +#9'TMenuItem'#2'T3'#9'AutoCheck'#9#7'Caption'#6#1'3'#10'GroupIndex'#3#131#0#9
- +'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'#2'T4'#9'AutoChe'
- +'ck'#9#7'Caption'#6#1'4'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7
- +#12'threadChange'#0#0#9'TMenuItem'#2'T7'#9'AutoCheck'#9#7'Caption'#6#1'7'#10
+ +#16'PairedTMenuClick'#0#0#9'TMenuItem'#15'MultipleRegress'#7'Caption'#6#23'M'
+ +'ultiple WLS Regression'#7'OnClick'#7#20'MultipleRegressClick'#0#0#9'TMenuIt'
+ +'em'#13'SingleRegress'#7'Caption'#6#21'Single WLS Regression'#7'OnClick'#7#18
+ +'SingleRegressClick'#0#0#9'TMenuItem'#21'DualImageCorrelation1'#7'Caption'#6
+ +#22'Dual image correlation'#7'OnClick'#7#26'DualImageCorrelation1Click'#0#0#0
+ +#9'TMenuItem'#8'Options1'#7'Caption'#6#7'Options'#0#9'TMenuItem'#13'Permutat'
+ +'ions1'#7'Caption'#6#12'Permutations'#0#9'TMenuItem'#2'N0'#9'AutoCheck'#9#7
+ +'Caption'#6#4'None'#7'Checked'#9#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClic'
+ +'k'#7#14'radiomenuclick'#0#0#9'TMenuItem'#5'N1000'#3'Tag'#3#232#3#9'AutoChec'
+ +'k'#9#7'Caption'#6#4'1000'#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14
+ +'radiomenuclick'#0#0#9'TMenuItem'#5'N2000'#3'Tag'#3#208#7#9'AutoCheck'#9#7'C'
+ +'aption'#6#4'2000'#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiom'
+ +'enuclick'#0#0#9'TMenuItem'#5'N3000'#3'Tag'#3#184#11#9'AutoCheck'#9#7'Captio'
+ +'n'#6#4'3000'#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenucl'
+ +'ick'#0#0#9'TMenuItem'#5'N4000'#3'Tag'#3#160#15#9'AutoCheck'#9#7'Caption'#6#4
+ +'4000'#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'#0#0
+ +#0#9'TMenuItem'#6'Tests1'#7'Caption'#6#5'Tests'#0#9'TMenuItem'#9'ttestmenu'#7
+ +'Caption'#6#6't-test'#7'OnClick'#7#13'testmenuclick'#0#0#9'TMenuItem'#6'BMme'
+ +'nu'#7'Caption'#6#14'Brunner Munzel'#7'Checked'#9#7'OnClick'#7#13'testmenucl'
+ +'ick'#0#0#0#9'TMenuItem'#8'Threads1'#7'Caption'#6#7'Threads'#0#9'TMenuItem'#2
+ +'T1'#9'AutoCheck'#9#7'Caption'#6#1'1'#7'Checked'#9#10'GroupIndex'#3#131#0#9
+ +'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'#2'T2'#9'AutoChe'
+ +'ck'#9#7'Caption'#6#1'2'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7
+ +#12'threadChange'#0#0#9'TMenuItem'#2'T3'#9'AutoCheck'#9#7'Caption'#6#1'3'#10
+'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMen'
- +'uItem'#2'T8'#9'AutoCheck'#9#7'Caption'#6#1'8'#10'GroupIndex'#3#131#0#9'Radi'
- +'oItem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'#3'T15'#9'AutoCheck'
- +#9#7'Caption'#6#2'15'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12
- +'threadChange'#0#0#9'TMenuItem'#3'T16'#9'AutoCheck'#9#7'Caption'#6#2'16'#10
- +'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#0#0#9
- +'TMenuItem'#10'Utilities1'#7'Caption'#6#9'Utilities'#0#9'TMenuItem'#9'niinii'
- +'gz1'#7'Caption'#6#14'nii -> .nii.gz'#7'OnClick'#7#14'niiniigz1Click'#0#0#9
- ,'TMenuItem'#9'Variance1'#7'Caption'#6#14'Variance image'#7'OnClick'#7#14'Var'
- +'iance1Click'#0#0#9'TMenuItem'#14'Makemeanimage2'#3'Tag'#2#1#7'Caption'#6#19
- +'Make binarized mean'#7'OnClick'#7#19'Makemeanimage1Click'#0#0#9'TMenuItem'
- +#14'Makemeanimage1'#7'Caption'#6#21'Make mean/StDev image'#7'OnClick'#7#19'M'
- +'akemeanimage1Click'#0#0#9'TMenuItem'#21'SingleSubjectZScores1'#7'Caption'#6
- +#22'Single Subject Z-Score'#7'OnClick'#7#26'SingleSubjectZScores1Click'#0#0#9
- +'TMenuItem'#24'IntensitynormalizationA1'#3'Tag'#2#1#7'Caption'#6#25'Intensit'
- +'y normalization A'#7'OnClick'#7#13'Balance1Click'#0#0#9'TMenuItem'#8'Balanc'
- +'e1'#7'Caption'#6#25'Intensity normalization B'#7'OnClick'#7#13'Balance1Clic'
- +'k'#0#0#9'TMenuItem PhysiologicalArtifactCorrection1'#7'Caption'#6#24'Physio'
- +'logical Correction'#7'OnClick'#7'%PhysiologicalArtifactCorrection1Click'#0#0
- +#9'TMenuItem'#20'Countlesionoverlaps1'#7'Caption'#6#21'Count lesion overlaps'
- +#7'OnClick'#7#25'Countlesionoverlaps1Click'#0#0#0#9'TMenuItem'#5'Help1'#7'Ca'
- +'ption'#6#4'Help'#0#9'TMenuItem'#6'About1'#7'Caption'#6#5'About'#7'OnClick'#7
+ +'uItem'#2'T4'#9'AutoCheck'#9#7'Caption'#6#1'4'#10'GroupIndex'#3#131#0#9'Radi'
+ +'oItem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'#2'T7'#9'AutoCheck'#9
+ +#7'Caption'#6#1'7'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'thr'
+ +'eadChange'#0#0#9'TMenuItem'#2'T8'#9'AutoCheck'#9#7'Caption'#6#1'8'#10'Group'
+ +'Index'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'
+ +#3'T15'#9'AutoCheck'#9#7'Caption'#6#2'15'#10'GroupIndex'#3#131#0#9'RadioItem'
+ +#9#7'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'#3'T16'#9'AutoCheck'#9#7'Ca'
+ +'ption'#6#2'16'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'thread'
+ +'Change'#0#0#0#9'TMenuItem'#16'PlankSzMenuItem1'#7'Caption'#6#10'Plank Size'
+ +#7'OnClick'#7#21'PlankSzMenuItem1Click'#0#0#0#9'TMenuItem'#10'Utilities1'#7
+ ,'Caption'#6#9'Utilities'#0#9'TMenuItem'#9'Variance1'#7'Caption'#6#14'Varianc'
+ +'e image'#7'OnClick'#7#14'Variance1Click'#0#0#9'TMenuItem'#14'Makemeanimage2'
+ +#3'Tag'#2#1#7'Caption'#6#19'Make binarized mean'#7'OnClick'#7#19'Makemeanima'
+ +'ge1Click'#0#0#9'TMenuItem'#14'Makemeanimage1'#7'Caption'#6#21'Make mean/StD'
+ +'ev image'#7'OnClick'#7#19'Makemeanimage1Click'#0#0#9'TMenuItem'#21'SingleSu'
+ +'bjectZScores1'#7'Caption'#6#22'Single Subject Z-Score'#7'OnClick'#7#26'Sing'
+ +'leSubjectZScores1Click'#0#0#9'TMenuItem'#24'IntensitynormalizationA1'#3'Tag'
+ +#2#1#7'Caption'#6#25'Intensity normalization A'#7'OnClick'#7#13'Balance1Clic'
+ +'k'#0#0#9'TMenuItem'#8'Balance1'#7'Caption'#6#25'Intensity normalization B'#7
+ +'OnClick'#7#13'Balance1Click'#0#0#0#9'TMenuItem'#5'Help1'#7'Caption'#6#4'Hel'
+ +'p'#7'Visible'#8#0#9'TMenuItem'#6'About1'#7'Caption'#6#5'About'#7'OnClick'#7
+#11'About1Click'#0#0#0#0#11'TSaveDialog'#10'SaveHdrDlg'#11'FilterIndex'#2#0#4
+'left'#2#8#3'top'#2'('#0#0#11'TOpenDialog'#10'OpenHdrDlg'#11'FilterIndex'#2#0
- +#4'left'#2#8#3'top'#2'H'#0#0#0
+ +#4'left'#2#8#3'top'#2'H'#0#0#6'TTimer'#10'StartTimer'#7'Enabled'#8#7'OnTimer'
+ +#7#15'StartTimerTimer'#4'left'#3#141#0#3'top'#2'C'#0#0#0
]);
diff --git a/npm/npmform.pas b/npm/npmform.pas
old mode 100644
new mode 100755
index 4218201..76203f8
--- a/npm/npmform.pas
+++ b/npm/npmform.pas
@@ -1,11 +1,14 @@
unit npmform;
{$IFDEF FPC} {$mode objfpc}{$H+} {$ENDIF}
+{$DEFINE SINGLETHREAD}
+//{$DEFINE FIRTHNOTHREAD}
interface
{$I options.inc}
uses
- define_types,SysUtils,
+ define_types,SysUtils,
part,StatThds,statcr,StatThdsUtil,Brunner,DISTR,nifti_img,
- Messages, Classes, Graphics, Controls, Forms, Dialogs,
+ Messages, userDir,
+ Classes, Graphics, Controls, Forms, DialogsX,Dialogs,
Menus, ComCtrls, ExtCtrls, StdCtrls,
overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr,
@@ -15,7 +18,7 @@ overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr,
{$ELSE}
LCLType,
{$ENDIF}
-upower,firthThds,firth,IniFiles,cpucount,userdir,math,
+upower,firthThds,firth,IniFiles,cpucount,math,
regmult,utypes,turbolesion
{$IFDEF compileANACOM}, anacom{$ENDIF}
@@ -27,8 +30,13 @@ type
{ TMainForm }
TMainForm = class(TForm)
+ Binaryimagescontinuousgroupsfast1: TMenuItem;
Memo1: TMemo;
+
Design1: TMenuItem;
+ //PlankSzMenuItem1: TMenuItem;
+ DualImageCorrelation1: TMenuItem;
+ MultipleRegress: TMenuItem;
SaveText1: TMenuItem;
ROIanalysis1: TMenuItem;
OpenHdrDlg: TOpenDialog;
@@ -43,7 +51,6 @@ type
BMmenu: TMenuItem;
ContinuousanalysisVBM1: TMenuItem;
Copy1: TMenuItem;
- Countlesionoverlaps1: TMenuItem;
Edit1: TMenuItem;
Exit1: TMenuItem;
File1: TMenuItem;
@@ -56,12 +63,11 @@ type
N2000: TMenuItem;
N3000: TMenuItem;
N4000: TMenuItem;
- niiniigz1: TMenuItem;
Options1: TMenuItem;
PairedTMenu: TMenuItem;
PenalizedLogisticRegerssion1: TMenuItem;
Permutations1: TMenuItem;
- PhysiologicalArtifactCorrection1: TMenuItem;
+ SingleRegress: TMenuItem;
SingleSubjectZScores1: TMenuItem;
T1: TMenuItem;
T15: TMenuItem;
@@ -73,91 +79,73 @@ type
T8: TMenuItem;
Tests1: TMenuItem;
Threads1: TMenuItem;
+ //StartTimer: TTimer;
ttestmenu: TMenuItem;
Utilities1: TMenuItem;
Variance1: TMenuItem;
VBM1: TMenuItem;
VLSM1: TMenuItem;
- ComputeIntersectionandUnion1: TMenuItem;
Intensitynormalization1: TMenuItem;
Masked1: TMenuItem;
MaskedintensitynormalizationA1: TMenuItem;
MaskedintensitynormalizationB1: TMenuItem;
- Binaryimagescontinuousgroupsfast1: TMenuItem;
Binarizeimages1: TMenuItem;
- Resliceimagetoneworientationandboundingbox1: TMenuItem;
- Setnonseroto1001: TMenuItem;
- AnaCOMmenu: TMenuItem;
- MonteCarloSimulation1: TMenuItem;
- Subtract1: TMenuItem;
- LogPtoZ1: TMenuItem;
- function GetKVers: string;
+ PlankSzMenuItem1: TMenuItem;
+ StartTimer: TTimer;
+ //Setnonseroto1001: TMenuItem;
+ //AnaCOMmenu: TMenuItem;
+ //MonteCarloSimulation1: TMenuItem;
+ //Subtract1: TMenuItem;
+ //LogPtoZ1: TMenuItem;
+ procedure PlankSzMenuItem1Click(Sender: TObject);
+ procedure NPMmsgUI( lStr: string);
+ procedure NPMmsgClearUI;
+ procedure NPMmsgSaveUI(lFilename: string);
+ procedure ProcessParamStr;
function GetValX (var lnSubj, lnFactors: integer; var lSymptomRA: singleP; var lImageNames: TStrings; var lCrit: integer; {lBinomial : boolean;} var lPredictorList: TStringList):boolean;
- function ThreshMap(lThresh: single; lVolVox: integer;lOutImg: singleP): integer;
function FirthNPMAnalyze (var lImages: TStrings; var lPredictorList: TStringList; var lMaskHdr: TMRIcroHdr; lnCond,lnCrit: integer; var lSymptomRA: SingleP; var lOutName: string): boolean;
- procedure InitPermute (lnSubj, lnPermute: integer; var lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP; var lRanOrderp: pointer; var lRanOrder: Doublep0);
- function reportPermute (lLabel:string; lnPermute: integer; var lPermuteMaxZ, lPermuteMinZ: singleP): double;
- procedure FreePermute (lnPermute: integer; var lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP;var lRanOrderp: pointer);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
function SaveHdrName (lCaption: string; var lFilename: string): boolean;
- procedure StrToMemo (lStr: string);
procedure NPMclick(Sender: TObject);
function OpenDialogExecute (lCaption: string;lAllowMultiSelect,lForceMultiSelect: boolean; lFilter: string): boolean;//; lAllowMultiSelect: boolean): boolean;
- function NPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lMaskVoxels,lnGroup1: integer): boolean;
- function NPMAnalyzePaired (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lMaskVoxels: integer): boolean;
- function NPMzscore (var lImages: TStrings; var lMnHdr,lStDevHdr: TMRIcroHdr): boolean;
+ //function NPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lMaskVoxels,lnGroup1: integer): boolean;
+ //function NPMAnalyzePaired (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lMaskVoxels: integer): boolean;
procedure FormCreate(Sender: TObject);
- function ReportDescriptives (var RA: SingleP; n: integer): boolean;
- function MakeSubtract (lPosName,lNegName: string): boolean;
- function MakeMean (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lBinarize,lVariance: boolean): boolean;
- function Balance (var lImageName,lMaskName: String; lMethod: integer{lInflection: boolean}): boolean;
+ //function MakeSubtract (lPosName,lNegName: string): boolean;
+ //function MakeMean (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lBinarize,lVariance: boolean): boolean;
+ //function Balance (var lImageName,lMaskName: String; lMethod: integer{lInflection: boolean}): boolean;
procedure LesionBtnClick(Sender: TObject);
procedure Copy1Click(Sender: TObject);
+ procedure StartTimerTimer(Sender: TObject);
procedure testmenuclick(Sender: TObject);
procedure radiomenuclick(Sender: TObject);
- procedure ReadIniFile;
- procedure WriteIniFile;
- function reportBonferroni(lLabel: string; lnTests: integer): double;
- function reportFDR (lLabel:string; lnVox, lnTests: integer; var lData: SingleP): double;
procedure Makemeanimage1Click(Sender: TObject);
procedure Exit1Click(Sender: TObject);
procedure Balance1Click(Sender: TObject);
- procedure niiniigz1Click(Sender: TObject);
+
procedure Variance1Click(Sender: TObject);
- procedure ZtoP1Click(Sender: TObject);
procedure About1Click(Sender: TObject);
procedure Design1Click(Sender: TObject);
- procedure PhysiologicalArtifactCorrection1Click(Sender: TObject);
procedure DualImageCorrelation1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure PairedTMenuClick(Sender: TObject);
procedure SingleSubjectZScores1Click(Sender: TObject);
procedure MultipleRegressClick(Sender: TObject);
function ReadPermute: integer;
- procedure NPMmsg( lStr: string);
- procedure NPMmsgClear;
- procedure MsgSave(lFilename: string);
procedure SingleRegressClick(Sender: TObject);
procedure AssociatevalfileswithNPM1Click(Sender: TObject);
procedure threadChange(Sender: TObject);
- procedure Countlesionoverlaps1Click(Sender: TObject);
+ //procedure Countlesionoverlaps1Click(Sender: TObject);
procedure PenalizedLogisticRegerssion1Click(Sender: TObject);
- procedure ComputeIntersectionandUnion1Click(Sender: TObject);
- procedure ROCbinomialdeficit1Click(Sender: TObject);
- procedure ROCcontinuousdeficit1Click(Sender: TObject);
+ //procedure ROCbinomialdeficit1Click(Sender: TObject);
+ //procedure ROCcontinuousdeficit1Click(Sender: TObject);
procedure ThreadDone(Sender: TObject);
- procedure NPMmsgAppend( lStr: string);
procedure ROIanalysis1Click(Sender: TObject);
procedure Masked1Click(Sender: TObject);
procedure Binarizeimages1Click(Sender: TObject);
- procedure Resliceimagetoneworientationandboundingbox1Click(
- Sender: TObject);
procedure Setnonseroto1001Click(Sender: TObject);
procedure Savetext1Click(Sender: TObject);
- procedure AnaCOMmenuClick(Sender: TObject);
- procedure MonteCarloSimulation1Click(Sender: TObject);
- procedure Subtract1Click(Sender: TObject);
- procedure LogPtoZ1Click(Sender: TObject);
+ //procedure Subtract1Click(Sender: TObject);
private
{ Private declarations }
public
@@ -168,218 +156,85 @@ var
MainForm: TMainForm;
implementation
-uses filename,prefs,roc,hdr,regression,valformat {$IFDEF SPREADSHEET} ,design,spread{$ENDIF}
+uses unpm, filename,prefs,hdr,roc,regression,valformat {$IFDEF SPREADSHEET} ,design,spread{$ENDIF}
{$IFNDEF UNIX},ActiveX {$ENDIF};
{$IFNDEF FPC}
{$R *.DFM}
-
{$ENDIF}
-const
- kVers : string = 'Chris Rorden''s NPM :: '+kMRIcronVers;
-var
-gNULP: boolean = true;
-gROI : boolean = false;
-function TMainForm.GetKVers: string;
-begin
- result := kVers +'; Threads used = '+inttostr(gnCPUThreads );
-end;
-
-
-procedure TMainForm.NPMmsgAppend( lStr: string);
-var
- lOutname: string;
- f: TextFile;
-begin
- MainForm.Memo1.Lines.add(lStr);
- lOutname:='c:\dx.txt';
- if fileexists(lOutname) then
- begin { open a text file }
- AssignFile(f, lOutname);
- Append(f);
- Writeln(f, lStr);
- Flush(f); { ensures that the text was actually written to file }
- { insert code here that would require a Flush before closing the file }
- CloseFile(f);
- end;
-end;
-
-procedure TMainForm.NPMmsg( lStr: string);
-begin
- MainForm.Memo1.Lines.add(lStr);
-end;
-
-procedure Msg(lStr: string);
-begin
- MainForm.NPMmsg(lStr);
-end;
-
-procedure MsgClear;
-begin
- MainForm.Memo1.Lines.Clear;
-end;
-procedure TMainForm.NPMmsgClear;
+(*function WarnIfLowNCrit(lnSubj,lnCrit: integer): boolean;
+//returns true if warning generated
begin
- MsgClear;
-end;
-
+ result := (round(lnSubj * 0.15) ) > lnCrit; //15%
+ if result then
+ Showmessage('Warning: low statistical power as tests computed for voxels damaged in at least '+inttostr(lnCrit) +' people. Solution: change Design value "Ignore voxels damaged in less than N%".');
-procedure TMainForm.MsgSave(lFilename: string);
-begin
- MainForm.Memo1.Lines.SaveToFile(lFilename);
-end;
+end; *)
-procedure TMainForm.ThreadDone(Sender: TObject);
+procedure TMainForm.NPMmsgUI( lStr: string);
begin
- Dec(gThreadsRunning);
+ Memo1.Lines.add(lStr);
end;
-procedure InitRA (lnPermute: integer; var lRA: singleP);
+procedure TMainForm.PlankSzMenuItem1Click(Sender: TObject);
var
- lInc: integer;
-begin
- getmem(lRA,lnPermute* sizeof(single));
- for lInc := 1 to lnPermute do
- lRA^[lInc] := 0;
-end;
-
-procedure TMainForm.InitPermute (lnSubj, lnPermute: integer; var lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP; var lRanOrderp: pointer; var lRanOrder: Doublep0);
-begin
- if (lnPermute < 2) then
- exit;
- InitRA(lnPermute,lPermuteMaxT);
- InitRA(lnPermute,lPermuteMinT);
- InitRA(lnPermute,lPermuteMaxBM);
- InitRA(lnPermute,lPermuteMinBM);
- createArray64(lRanOrderp,lRanOrder,lnSubj);
-end; //init permute
-
-procedure sort (lo, up: integer; var r:SingleP);
-//62ms Shell Sort http://www.dcc.uchile.cl/~rbaeza/handbook/algs/4/414.sort.p.html
-label 999;
-var d, i, j : integer;
- tempr : single;
-begin
- d := up-lo+1;
- while d>1 do begin
- if d<5 then
- d := 1
- else
- d := trunc( 0.45454*d );
- //Do linear insertion sort in steps size d
- for i:=up-d downto lo do begin
- tempr := r^[i];
- j := i+d;
- while j <= up do
- if tempr > r^[j] then begin
- r^[j-d] := r^[j];
- j := j+d
- end
- else goto 999; //break
- 999:
- r^[j-d] := tempr
- end //for
- end //while
-end; //proc Sort
-
-function IndexPct(lnPermute: integer; lPct: single; lTop: boolean): integer;
+ str : string;
+ v,max: integer;
begin
- result := round(lnPermute * lPct);
- if lTop then
- result := (lnPermute - result)+1;
- if (result < 1) then
- result := 1;
- if (result > lnPermute) then
- result := lnPermute;
-end;
-
-function TMainForm.reportBonferroni(lLabel: string; lnTests: integer): double; //returns 5% Z score
-begin
- if lnTests < 1 then exit;
- result := pNormalInv(0.05/lnTests);
- msg(inttostr(lnTests)+' test '+lLabel+' Bonferroni FWE Z '+
- '0.050='+realtostr(result,3)+
- ', 0.025='+realtostr(pNormalInv(0.025/lnTests),3)+
- ', 0.01='+realtostr(pNormalInv(0.01/lnTests),3));
-end;
+ {$IFDEF CPU32}
+ max := 1536;
+ {$ELSE}
+ max := 8000;
+ {$ENDIF}
-function TMainForm.reportFDR (lLabel:string; lnVox, lnTests: integer; var lData: SingleP): double;
-var
- lC,lN: integer;
- lPs: SingleP;
- lFDR05r, lFDR01r,lFDR05p, lFDR01p,lMin,lMax : double;
-begin
- result := 10000;
- if (lnTests < 1) or (lnVox < 1) then
+ str := inttostr(gNPMPrefs.PlankMB);
+ if not InputQuery('Specify cache size', 'Mb for computation (256..'+inttostr(max)+')', str) then exit;
+ try
+ v := StrToInt(str); // Trailing blanks are not supported
+ except
+ on Exception : EConvertError do begin
+ ShowMessage(Exception.Message);
exit;
- GetMem(lPs,lnTests*sizeof(single));
- for lC := 1 to lnTests do
- lPs^[lC] := 0;
- lN := 0;
- lMin := 0;
- lMax := 0;
- for lC := 1 to lnVox do begin
- if lData^[lC] <> 0 then begin
- inc(lN);
- if lData^[lC] > lMax then lMax := lData^[lC]
- else if lData^[lC] < lMin then lMin := lData^[lC];
- if lN <= lnTests then
- lPs^[lN] := pNormal(lData^[lC]);
- end;
- end;
- EstimateFDR2(lnTests, lPs, lFDR05p, lFDR01p,lFDR05r, lFDR01r);
- msg(lLabel+' Range '
- +realtostr(lMin,3)+
- '...'+realtostr(lMax,3));
- {Msg(lLabel+' Range '
- +realtostr(pNormalInv(lPs[lnTests]),3)+
- '...'+realtostr(pNormalInv(lPs[1]),3)+
- ' '); } //we could use this and save time computing lmin/lmax, but loss in precision
- msg(lLabel+' +FDR Z '+
- '0.050='+realtostr(pNormalInv(lFDR05p),8)+
- ', 0.01='+realtostr(pNormalInv(lFDR01p),8)+
- ' ');
- msg(lLabel+' -FDR Z '+
- '0.050='+realtostr(pNormalInv(1-lFDR05r),8)+
- ', 0.01='+realtostr(pNormalInv(1-lFDR01r),8)+
- ' ');
- result := pNormalInv(lFDR01p);
+ end;
+ end;
+ if (v < 256) then
+ v := 256;
+ if v > max then
+ v := max;
+ gNPMPrefs.PlankMB := v;
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ ComputePlankSize(gNPMPrefs.PlankMB);
end;
-function ReportThresh (lLabel: string; lnPermute: integer; var lRankedData: singleP;lTop:boolean): double;
+procedure TMainForm.NPMmsgClearUI;
begin
- result := lRankedData^[IndexPct(lnPermute,0.050,lTop)];
- msg(lLabel+': permutationFWE '+
- //'0.500='+realtostr(lRankedData[IndexPct(lnPermute,0.500,lTop)],3)+
- ', 0.050='+realtostr({lRankedData^[IndexPct(lnPermute,0.050,lTop)]} result,8)+
- ', 0.025='+realtostr(lRankedData^[IndexPct(lnPermute,0.025,lTop)],8)+
- ', 0.01='+realtostr(lRankedData^[IndexPct(lnPermute,0.010,lTop)],8)+
- ' ');
+ Memo1.Lines.Clear;
end;
-function TMainForm.reportPermute (lLabel:string; lnPermute: integer; var lPermuteMaxZ, lPermuteMinZ: singleP): double;
-begin
- result := 0;
- if (lnPermute < 2) then
- exit;
- sort (1, lnPermute,lPermuteMaxZ);
- result := ReportThresh(lLabel+'+',lnPermute,lPermuteMaxZ,true);
- sort (1, lnPermute,lPermuteMinZ);
- ReportThresh(lLabel+'-',lnPermute,lPermuteMinZ,false);
- //for lPos := 1 to lnPermute do
- // msg(inttostr(lPos)+', '+realtostr(lPermuteMinZ[lPos],4));
+procedure TMainForm.NPMMsgSaveUI(lFilename: string);
+var
+ i: integer;
+ f: textfile;
+begin
+ if (Memo1.Lines.Count < 1) then exit;
+ if fileexists(lFilename) then begin
+ AssignFile(f, lFilename);
+ {$I-}
+ append(f);
+ {$I+}
+ if IOResult= 0 then
+ for i:= 0 to Memo1.Lines.Count- 1 do
+ WriteLn(f, Memo1.Lines[i]);
+ CloseFile(f);
+ end else
+ MainForm.Memo1.Lines.SaveToFile(lFilename);
end;
-procedure TMainForm.FreePermute (lnPermute: integer; var lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP;var lRanOrderp: pointer);
+procedure TMainForm.ThreadDone(Sender: TObject);
begin
- if (lnPermute < 2) then
- exit;
- Freemem(lRanOrderp);
- Freemem(lPermuteMaxT);
- Freemem(lPermuteMinT);
- Freemem(lPermuteMaxBM);
- Freemem(lPermuteMinBM);
+ Dec(gThreadsRunning);
end;
function TMainForm.SaveHdrName (lCaption: string; var lFilename: string): boolean;
@@ -395,46 +250,9 @@ end;
procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
- //showmessage('zz');
WriteIniFile;
end;
-procedure MakeStatHdr (var lBGHdr,lStatHdr: TniftiHdr; lMinIntensity,lMaxIntensity,lIntent_p1,lIntent_p2,lIntent_p3: single; lIntent_code: smallint;lIntentName: string);
-var lIntentNameLen,lPos: integer;
- lStr: string;
-begin
- move(lBGHdr,lStatHdr,sizeof(TniftiHdr));
- with lStatHdr do begin
- magic :=kNIFTI_MAGIC_SEPARATE_HDR;
- bitpix := 32; //32-bit real data
- datatype := kDT_FLOAT;
- scl_slope:= 1;
- scl_inter:= 0;
- glmin := round(lMinIntensity);
- glmax := round(lMaxIntensity);
- intent_code := lIntent_Code;// kNIFTI_INTENT_ESTIMATE;
- intent_p1 := lIntent_p1;
- intent_p2 := lIntent_p2;
- intent_p3 := lIntent_p3;
- lIntentNameLen := length(lIntentName);
- descrip[1] := 'N';
- descrip[2] := 'P';
- descrip[3] := 'M';
- if lIntent_code=kNIFTI_INTENT_TTEST then begin
- descrip[4] := 't' ;
- lStr := inttostr(trunc(lIntent_p1));
- for lPos := 1 to length (lStr) do
- descrip[4+lPos] := lStr[lPos] ;
- end else
- descrip[4] := 'z';
- if lIntentNameLen > sizeof(intent_name) then
- lIntentNameLen := sizeof(intent_name);
- if lIntentNameLen > 0 then
- for lPos := 1 to lIntentNameLen do
- intent_name[lPos] := lIntentName[lPos];
- end;
-end;
-
procedure WriteThread( lnThread: integer);
begin
case lnThread of
@@ -463,7 +281,6 @@ begin
gnCPUThreads := result;
end;
-
procedure WritePermute( lnPermute: integer);
begin
case lnPermute of
@@ -484,349 +301,6 @@ begin
else result := 0;
end;
-(*function LoadImgX(lInName: string; lImgData: SingleP; lStart, lEnd,linvox_offset,lRApos,lDataType,lVolVox: integer): boolean;
-var
- lInc: integer;
-begin
- //LoadImgX(lImages[lPos-1], lPlankImg, lStartVox, lEndVox,round(gOffsetRA[lPos]),lPlankImgPos,gDataTypeRA[lPos],lVolVox);
- for lInc := 1 to ((lEnd{+1})-lStart) do
- lImgData^[lRApos+lInc-1] := 123;
- msg(inttostr(lRApos+1-1)+' '+inttostr(lRApos+((lEnd+1)-lStart)-1) );
-end;*)
-
-function TMainForm.NPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lMaskVoxels,lnGroup1: integer): boolean;
-
-label
- 667;
-var
- lOutName,lOutNameMod: string;
- lMaskImg,lPlankImg,lOutImgMn,lOutImgBM,lOutImgT,lDummy: SingleP;
- lTotalMemory: double; //not integer - limit for 32bit int is 2Gb
- lPlank,lVolVox,lPos,lMinMask,lMaxMask,lnPlanks,lVoxPerPlank,
- lPos2,lPos2Offset,lStartVox,lEndVox,lPlankImgPos,lnTests,lnVoxTested,lThreadStart,lThreadEnd,lThreadInc: integer;
- lT, lSum, lMn: double;
- lStatHdr: TNIfTIhdr;
- lFdata: file;
- lThread,lnPermute: integer;
- lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP;
- lRanOrderp: pointer;
- lRanOrder: Doublep0;
- lttest,lBM: boolean;
-begin
-
- result := false;
- lttest:= ttestmenu.checked;
- lBM := BMmenu.checked;
- lnPermute := ReadPermute;
- //lnPermute := 100;
- msg('Permutations = ' +IntToStr(lnPermute));
- lOutName := lMaskHdr.ImgFileName;
- if not SaveHdrName ('Statistical Map', lOutName) then exit;
- msg('Analysis began = ' +TimeToStr(Now));
- lTotalMemory := 0;
- lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
- if (lVolVox < 1) then goto 667;
- //load mask
- getmem(lMaskImg,lVolVox*sizeof(single));
- if not LoadImg(lMaskHdr.ImgFileName, lMaskImg, 1, lVolVox,round(gOffsetRA[0]),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
- msg('Unable to load mask ' +lMaskHdr.ImgFileName);
- goto 667;
- end;
- //next find start and end of mask
- lPos := 0;
- repeat
- inc(lPos);
- until (lMaskImg^[lPos] > 0) or (lPos = lVolVox);
- lMinMask := lPos;
- lPos := lVolVox+1;
- repeat
- dec(lPos);
- until (lMaskImg^[lPos] > 0) or (lPos = 1);
- lMaxMask := lPos;
- if lMaxMask = 1 then begin
- msg('Mask appears empty' +lMaskHdr.ImgFileName);
- goto 667;
- end;
- msg('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
- lVoxPerPlank := kPlankSz div lImages.Count div sizeof(single) ;
- if (lVoxPerPlank = 0) then goto 667; //no data
- lTotalMemory := ((lMaxMask+1)-lMinMask) * lImages.Count;
- if (lTotalMemory = 0) then goto 667; //no data
- lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
- msg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
- msg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
- getmem(lPlankImg,kPlankSz);
- lStartVox := lMinMask;
- lEndVox := lMinMask-1;
- for lPos := 1 to lImages.Count do
- if gScaleRA[lPos] = 0 then
- gScaleRA[lPos] := 1;
-
- getmem(lOutImgMn,lVolVox* sizeof(single));
- getmem(lOutImgBM,lVolVox* sizeof(single));
- getmem(lOutImgT,lVolVox* sizeof(single));
- InitPermute (lImages.Count, lnPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
- for lPos := 1 to lVolVox do begin
- lOutImgMn^[lPos] := 0;
- lOutImgBM^[lPos] := 0;
- lOutImgT^[lPos] := 0;
- end;
- ClearThreadData(gnCPUThreads,lnPermute);
-
- for lPlank := 1 to lnPlanks do begin
- msg('Computing plank = ' +Inttostr(lPlank));
- Refresh;
- Application.processmessages;
- lEndVox := lEndVox + lVoxPerPlank;
- if lEndVox > lMaxMask then begin
- lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
- lEndVox := lMaxMask;
- end;
- lPlankImgPos := 1;
- for lPos := 1 to lImages.Count do begin
- if not LoadImg(lImages[lPos-1], lPlankImg, lStartVox, lEndVox,round(gOffsetRA[lPos]),lPlankImgPos,gDataTypeRA[lPos],lVolVox) then
- goto 667;
- lPlankImgPos := lPlankImgPos + lVoxPerPlank;
- end;//for each image
- //showmessage('stop');
- //threading start
- lThreadStart := 1;
- lThreadInc := lVoxPerPlank div gnCPUThreads;
- lThreadEnd := lThreadInc;
- Application.processmessages;
- for lThread := 1 to gnCPUThreads do begin
- if lThread = gnCPUThreads then
- lThreadEnd := lVoxPerPlank; //avoid integer rounding error
- with TNNStat.Create (ProgressBar1,lttest,lBM,0, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,lnGroup1, lMaskImg,lPlankImg,lOutImgMn,lOutImgBM,lOutImgT,lDummy) do
- {$IFDEF FPC} OnTerminate := @ThreadDone; {$ELSE}OnTerminate := ThreadDone;{$ENDIF}
- inc(gThreadsRunning);
- lThreadStart := lThreadEnd + 1;
- lThreadEnd :=lThreadEnd + lThreadInc;
- end; //for each thread
- repeat
- Application.processmessages;
- until gThreadsRunning = 0;
- Application.processmessages;
- //threading end
- lStartVox := lEndVox + 1;
- end;
- lnVoxTested := SumThreadData(gnCPUThreads,lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM);
- //next report findings
- msg('Voxels tested = ' +Inttostr(lnVoxTested));
- reportBonferroni('Std',lnVoxTested);
- //next: save data
-(*savedata*)
- MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
-//save mean
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Mean','.hdr');
- if lnVoxTested > 1 then
-
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgMn,1);
- MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
-
-if (lttest) and (lnVoxTestED > 1 ) then begin //save Ttest
- //reportRange ('ttest', lVolVox, lnVoxTested, lOutImgT);
- //next: convert t-scores to z scores
- for lPos := 1 to lVolVox do
- lOutImgT^[lPos] := TtoZ (lOutImgT^[lPos],lImages.Count-2);
- for lPos := 1 to lnPermute do begin
- lPermuteMaxT^[lPos] := TtoZ (lPermuteMaxT^[lPos],lImages.Count-2);
- lPermuteMinT^[lPos] := TtoZ (lPermuteMinT^[lPos],lImages.Count-2);
- end;
-
- reportFDR ('ttest', lVolVox, lnVoxTested, lOutImgT);
- reportPermute('ttest',lnPermute,lPermuteMaxT, lPermuteMinT);
- lOutNameMod := ChangeFilePostfixExt(lOutName,'ttest','.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgT,1);
-end;
-if (lBM) and (lnVoxTested > 1 ) then begin //save Brunner Munzel
- reportFDR ('BM', lVolVox, lnVoxTested, lOutImgBM);
- reportPermute('BM',lnPermute,lPermuteMaxBM, lPermuteMinBM);
- lOutNameMod := ChangeFilePostfixExt(lOutName,'BM','.hdr');
-
- {reportFDR ('absT', lVolVox, lnVoxTested, lOutImgBM);
- reportPermute('absT',lnPermute,lPermuteMaxBM, lPermuteMinBM);
- lOutNameMod := ChangeFilePostfixExt(lOutName,'absT','.hdr');
- }
- //NIFTIhdr_SaveHdr(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr));
- lOutNameMod := changefileext(lOutNameMod,'.img');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgBM,1);
-end;(**)
-//next: close images
- FreePermute (lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp);
- freemem(lOutImgT);
- freemem(lOutImgBM);
- freemem(lOutImgMn);
- //freemem(lObsp);
- freemem(lMaskImg);
- freemem(lPlankImg);
- msg('Analysis finished = ' +TimeToStr(Now));
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes','.txt');
- MsgSave(lOutNameMod);
- ProgressBar1.Position := 0;
- result := true;
- exit;
-667: //you only get here if you aborted ... free memory and report error
- if lVolVox > 1 then freemem(lMaskImg);
- if lTotalMemory > 1 then freemem(lPlankImg);
- msg('Unable to complete analysis.');
- ProgressBar1.Position := 0;
-end;
-
-function TMainForm.NPMAnalyzePaired (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lMaskVoxels: integer): boolean;
-label
- 667;
-var
- lOutName,lOutNameMod: string;
- lMaskImg,lPlankImg,lOutImgMn,lOutImgT,lDummy,lDummy2: SingleP;
- lTotalMemory: double; //not integer - limit for 32bit int is 2Gb
- lPlank,lVolVox,lPos,lMinMask,lMaxMask,lnPlanks,lVoxPerPlank,
- lPos2,lPos2Offset,lStartVox,lEndVox,lPlankImgPos,lnTests,lnVoxTested,lThreadStart,lThreadEnd,lThreadInc: integer;
- lT, lSum, lMn: double;
- lStatHdr: TNIfTIhdr;
- lFdata: file;
- lThread,lnPermute: integer;
- lPermuteMaxT, lPermuteMinT: singleP;
- lRanOrderp: pointer;
- lRanOrder: Doublep0;
-begin
- //lnPermute := ReadPermute;
- lnPermute := 0;//not yet
- msg('Permutations = ' +IntToStr(lnPermute));
- lOutName := lMaskHdr.ImgFileName;
- if not SaveHdrName ('Statistical Map', lOutName) then exit;
- msg('Analysis began = ' +TimeToStr(Now));
- lTotalMemory := 0;
- lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
- if (lVolVox < 1) then goto 667;
- //load mask
- getmem(lMaskImg,lVolVox*sizeof(single));
- if not LoadImg(lMaskHdr.ImgFileName, lMaskImg, 1, lVolVox,round(gOffsetRA[0]),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
- msg('Unable to load mask ' +lMaskHdr.ImgFileName);
- goto 667;
- end;
- //next find start and end of mask
- lPos := 0;
- repeat
- inc(lPos);
- until (lMaskImg^[lPos] > 0) or (lPos = lVolVox);
- lMinMask := lPos;
- lPos := lVolVox+1;
- repeat
- dec(lPos);
- until (lMaskImg^[lPos] > 0) or (lPos = 1);
- lMaxMask := lPos;
- if lMaxMask = 1 then begin
- Msg('Mask appears empty' +lMaskHdr.ImgFileName);
- goto 667;
- end;
- Msg('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
- lVoxPerPlank := kPlankSz div lImages.Count div sizeof(single) ;
- if (lVoxPerPlank = 0) then goto 667; //no data
- lTotalMemory := ((lMaxMask+1)-lMinMask) * lImages.Count;
- if (lTotalMemory = 0) then goto 667; //no data
- lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
- Msg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
- Msg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
- getmem(lPlankImg,kPlankSz);
- lStartVox := lMinMask;
- lEndVox := lMinMask-1;
- for lPos := 1 to lImages.Count do
- if gScaleRA[lPos] = 0 then
- gScaleRA[lPos] := 1;
- getmem(lOutImgMn,lVolVox* sizeof(single));
- getmem(lOutImgT,lVolVox* sizeof(single));
- //not yet InitPermute (lImages.Count, lnPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
- for lPos := 1 to lVolVox do begin
- lOutImgMn^[lPos] := 0;
- lOutImgT^[lPos] := 0;
- end;
- ClearThreadData(gnCPUThreads,lnPermute);
- for lPlank := 1 to lnPlanks do begin
- Msg('Computing plank = ' +Inttostr(lPlank));
- Refresh;
- Application.processmessages;
- lEndVox := lEndVox + lVoxPerPlank;
- if lEndVox > lMaxMask then begin
- lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
- lEndVox := lMaxMask;
- end;
- lPlankImgPos := 1;
- for lPos := 1 to lImages.Count do begin
- if not LoadImg(lImages[lPos-1], lPlankImg, lStartVox, lEndVox,round(gOffsetRA[lPos]),lPlankImgPos,gDataTypeRA[lPos],lVolVox) then
- goto 667;
- lPlankImgPos := lPlankImgPos + lVoxPerPlank;
- end;//for each image
- //threading start
- lThreadStart := 1;
- lThreadInc := lVoxPerPlank div gnCPUThreads;
- lThreadEnd := lThreadInc;
- Application.processmessages;
- for lThread := 1 to gnCPUThreads do begin
- if lThread = gnCPUThreads then
- lThreadEnd := lVoxPerPlank; //avoid integer rounding error
- with TPairedTStat.Create (ProgressBar1,false,false,0, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,666, lMaskImg,lPlankImg,lOutImgMn,lDummy2,lOutImgT,lDummy) do
- {$IFDEF FPC} OnTerminate := @ThreadDone; {$ELSE}OnTerminate := ThreadDone;{$ENDIF}
- inc(gThreadsRunning);
- lThreadStart := lThreadEnd + 1;
- lThreadEnd :=lThreadEnd + lThreadInc;
- end; //for each thread
- repeat
- Application.processmessages;
- until gThreadsRunning = 0;
- Application.processmessages;
- //threading end
- lStartVox := lEndVox + 1;
- end;
- lnVoxTested := SumThreadDataLite(gnCPUThreads);//not yet SumThreadData(gnCPUThreads,lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM);
- //next report findings
- Msg('Voxels tested = ' +Inttostr(lnVoxTested));
- reportBonferroni('Std',lnVoxTested);
- //next: save data
-(*savedata *)
- MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
-//save mean
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Mean','.hdr');
- if lnVoxTested > 1 then
-
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgMn,1);
- MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
-
-if (lnVoxTestED > 1 ) then begin //save Ttest
- //next: convert t-scores to z scores
- for lPos := 1 to lVolVox do
- lOutImgT^[lPos] := TtoZ (lOutImgT^[lPos],(lImages.Count div 2)-1);
- for lPos := 1 to lnPermute do begin
- lPermuteMaxT^[lPos] := TtoZ (lPermuteMaxT^[lPos],lImages.Count-2);
- lPermuteMinT^[lPos] := TtoZ (lPermuteMinT^[lPos],lImages.Count-2);
- end;
-
- reportFDR ('ttest', lVolVox, lnVoxTested, lOutImgT);
- reportPermute('ttest',lnPermute,lPermuteMaxT, lPermuteMinT);
- lOutNameMod := ChangeFilePostfixExt(lOutName,'ttest','.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgT,1);
-end;
-//next: close images
- //not yet FreePermute (lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp);
- freemem(lOutImgT);
- freemem(lOutImgMn);
- //freemem(lObsp);
- freemem(lMaskImg);
- freemem(lPlankImg);
- Msg('Analysis finished = ' +TimeToStr(Now));
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes','.txt');
- MsgSave(lOutNameMod);
- ProgressBar1.Position := 0;
- exit;
-667: //you only get here if you aborted ... free memory and report error
- if lVolVox > 1 then freemem(lMaskImg);
- if lTotalMemory > 1 then freemem(lPlankImg);
- Msg('Unable to complete analysis.');
- ProgressBar1.Position := 0;
-end;
-
-
-
function TMainForm.OpenDialogExecute (lCaption: string;lAllowMultiSelect,lForceMultiSelect: boolean; lFilter: string): boolean;//; lAllowMultiSelect: boolean): boolean;
var
lNumberofFiles: integer;
@@ -843,667 +317,138 @@ begin
if lForceMultiSelect then begin
lNumberofFiles:= OpenHdrDlg.Files.Count;
if lNumberofFiles < 2 then begin
- Showmessage('Error: This function is designed to overlay MULTIPLE images. You selected less than two images.');
+ ShowMsg('Error: This function is designed to overlay MULTIPLE images. You selected less than two images.');
result := false;
end;
end;
end;
-
-
procedure TMainForm.NPMclick(Sender: TObject);
label
666;
var
lnGroup1,lMaskVoxels: integer;
lG: TStrings;
- lMaskname: string;
+ lMaskname, lOutName: string;
lMaskHdr: TMRIcroHdr;
begin
if (not ttestmenu.checked) and (not BMmenu.checked) then begin
- Showmessage('Error: you need to compute at least on test [options/test menu]');
+ ShowMsg('Error: you need to compute at least on test [options/test menu]');
exit;
end;
- MsgClear;
- Msg(GetKVers);
- Msg('Threads: '+inttostr(gnCPUThreads));
- if not OpenDialogExecute('Select brain mask ',false,false,kImgFilter) then begin
- showmessage('NPM aborted: mask selection failed.');
+
+ if not OpenDialogExecute('Select brain mask ',false,false,kImgFilter) then begin
+ ShowMsg('NPM aborted: mask selection failed.');
exit;
- end; //if not selected
- lMaskname := OpenHdrDlg.Filename;
- if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- showmessage('Error reading mask.');
+ end; //if not selected
+ lMaskname := OpenHdrDlg.Filename;
+ (*if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
+ showMsg('Error reading mask.');
exit;
- end;
+ end;
lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
- showmessage('Mask file size too small.');
+ ShowMsg('Mask file size too small.');
exit;
- end;
- Msg('Mask name = '+ lMaskname);
- Msg('Total voxels = '+inttostr(lMaskVoxels));
+ end; *)
+
//next, get 1st group
if not OpenDialogExecute('Select postive group (Z scores positive if this group is brighter)',true,true,kImgFilter) then begin
- showmessage('NPM aborted: file selection failed.');
+ ShowMsg('NPM aborted: file selection failed.');
exit;
end; //if not selected
lG:= TStringList.Create; //not sure why TStrings.Create does not work???
lG.addstrings(OpenHdrDlg.Files);
lnGroup1 :=OpenHdrDlg.Files.Count;
- Msg('Scans in Group 1 = '+inttostr(lnGroup1));
+
//next, get 2nd group
if not OpenDialogExecute('Select negative group (Z scores negative if this group is brighter)',true,true,kImgFilter) then begin
- showmessage('NPM aborted: file selection failed.');
+ ShowMsg('NPM aborted: file selection failed.');
goto 666;
end; //if not selected
lG.addstrings(OpenHdrDlg.Files);
if not CheckVoxelsGroupX(lG,lMaskHdr {lMaskVoxels}) then begin
- showmessage('File dimensions differ from mask.');
+ ShowMsg('File dimensions differ from mask.');
goto 666;
end;
- Msg('Scans in Group 2 = '+inttostr(lG.count-lnGroup1));
- NPMAnalyze(lG,lMaskHdr,lMaskVoxels,lnGroup1);
+ lOutName := lMaskHdr.ImgFileName;
+ if not SaveHdrName ('Statistical Map', lOutName) then exit;
+ NPMAnalyze(lG,lMaskName,lMaskVoxels,lnGroup1,gNPMPrefs,lOutName);
666:
lG.Free;
end;
-function TMainForm.ThreshMap(lThresh: single; lVolVox: integer;lOutImg: singleP): integer;
+function TMainForm.GetValX (var lnSubj, lnFactors: integer; var lSymptomRA: singleP; var lImageNames: TStrings; var lCrit: integer; var lPredictorList: TStringList):boolean;
+//warning: you MUST free lPredictorList
var
- lVox: integer;
+ lVALFilename: string;
+ lCritPct: integer;
begin
- result := 0;
- for lVox := 1 to lVolVox do
- if lOutImg^[lVox] >= lThresh then
- inc(result);
-
- for lVox := 1 to lVolVox do
- if lOutImg^[lVox] >= lThresh then
- lOutImg^[lVox] := 1
- else
- lOutImg^[lVox] := 0;
+ lPredictorList := TStringList.Create;
+ result := false;
+ lnSubj := 0;
+ if not MainForm.OpenDialogExecute('Select MRIcron VAL file',false,false,'MRIcron VAL (*.val)|*.val') then begin
+ ShowMsg('NPM aborted: VAL file selection failed.');
+ exit;
+ end; //if not selected
+ lVALFilename := MainForm.OpenHdrDlg.Filename;
+ result := GetValCore ( lVALFilename, lnSubj, lnFactors, lSymptomRA, lImageNames, lCrit,lCritPct{,binom},lPredictorList);
end;
-{x$DEFINE NOTmedianfx}
-(*function TMainForm.LesionNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lnCrit,lRun: integer; var lSymptomRA: SingleP;var lFactname,lOutName: string): boolean;
-label
- 123,667;
-var
- lOutNameMod: string;
- lPlankImg: byteP;
- lOutImgSum,lOutImgBM,lOutImgT,
- lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP;
- lPos,lPlank,lThread: integer;
- lVolVox,lMinMask,lMaxMask,lTotalMemory,lnPlanks,lVoxPerPlank,
- lThreadStart,lThreadEnd,lThreadInc,lnLesion,lnPermute,
- lPos2,lPos2Offset,lStartVox,lEndVox,lPlankImgPos,lnTests,lnVoxTested,lPosPct: int64;
- lT,lBMz, lSum,lThresh :double;
- lObsp: pointer;
- lObs: Doublep0;
- lStatHdr: TNIfTIhdr;
- lFdata: file;
- lRanOrderp: pointer;
- lRanOrder: Doublep0;
- lttest,lBM: boolean;
- {$IFDEF medianfx}
- lmedianFX,lmeanFX,lsummean,lsummedian: double;
- lmediancount: integer;
- {$ENDIF}
-begin
- lttest:= ttestmenu.checked;
- lBM := BMmenu.checked;
- lnPermute := ReadPermute;
- Msg('Permutations = ' +IntToStr(lnPermute));
- Msg('Analysis began = ' +TimeToStr(Now));
- lTotalMemory := 0;
- lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
- if (lVolVox < 1) then goto 667;
- lMinMask := 1;
- lMaxMask := lVolVox;
- lVoxPerPlank := kPlankSz div lImages.Count div sizeof(byte) ;
- if (lVoxPerPlank = 0) then goto 667; //no data
- lTotalMemory := ((lMaxMask+1)-lMinMask) * lImages.Count;
- if (lTotalMemory = 0) then goto 667; //no data
- lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
- Msg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
- Msg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
- if (lnPlanks = 1) then
- getmem(lPlankImg,lTotalMemory) //assumes 1bpp
- else
- getmem(lPlankImg,kPlankSz);
- lStartVox := lMinMask;
- lEndVox := lMinMask-1;
- {$IFDEF medianfx}
- lsummean := 0;
- lsummedian:= 0;
- lmediancount := 0;
- {$ENDIF}
- for lPos := 1 to lImages.Count do
- if gScaleRA[lPos] = 0 then
- gScaleRA[lPos] := 1;
- createArray64(lObsp,lObs,lImages.Count);
- getmem(lOutImgSum,lVolVox* sizeof(single));
- getmem(lOutImgBM,lVolVox* sizeof(single));
- getmem(lOutImgT,lVolVox* sizeof(single));
- InitPermute (lImages.Count, lnPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
- for lPos := 1 to lVolVox do begin
- lOutImgSum^[lPos] := 0;
- lOutImgBM^[lPos] := 0;
- lOutImgT^[lPos] := 0;
- end;
- //next create permuted BM bounds
- if lBM then begin
- Msg('Generating BM permutation thresholds');
- Refresh;
- for lPos := 1 to lImages.Count do
- lObs^[lPos-1] := lSymptomRA^[lPos];
- genBMsim (lImages.Count, lObs);
- end;
- ClearThreadData(gnCPUThreads,lnPermute) ;
- for lPlank := 1 to lnPlanks do begin
- Msg('Computing plank = ' +Inttostr(lPlank));
- Refresh;
- Application.processmessages;
- lEndVox := lEndVox + lVoxPerPlank;
- if lEndVox > lMaxMask then begin
- lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
- lEndVox := lMaxMask;
- end;
- lPlankImgPos := 1;
- for lPos := 1 to lImages.Count do begin
- if not LoadImg8(lImages[lPos-1], lPlankImg, lStartVox, lEndVox,round(gOffsetRA[lPos]),lPlankImgPos,gDataTypeRA[lPos],lVolVox) then
- goto 667;
- lPlankImgPos := lPlankImgPos + lVoxPerPlank;
- end;//for each image
- //threading start
- lThreadStart := 1;
- lThreadInc := lVoxPerPlank div gnCPUThreads;
- lThreadEnd := lThreadInc;
- Application.processmessages;
- for lThread := 1 to gnCPUThreads do begin
- if lThread = gnCPUThreads then
- lThreadEnd := lVoxPerPlank; //avoid integer rounding error
- with TLesionContinuous.Create (ProgressBar1,lttest,lBM,lnCrit, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,0,lPlankImg,lOutImgSum,lOutImgBM,lOutImgT,nil,lSymptomRA) do
- {$IFDEF FPC} OnTerminate := @ThreadDone; {$ELSE}OnTerminate := ThreadDone;{$ENDIF}
- inc(gThreadsRunning);
- lThreadStart := lThreadEnd + 1;
- lThreadEnd :=lThreadEnd + lThreadInc;
- end; //for each thread
- repeat
- Application.processmessages;
- until gThreadsRunning = 0;
- Application.processmessages;
- //threading end
- lStartVox := lEndVox + 1;
- end;
- lnVoxTested := SumThreadData(gnCPUThreads,lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM);
- //next report findings
- if lnVoxTested < 1 then begin
- Msg('**Error: no voxels tested: no regions lesioned in at least '+inttostr(lnCrit)+' patients**');
- goto 123;
- end;
-
- Msg('Voxels tested = ' +Inttostr(lnVoxTested));
- {$IFDEF medianfx}
- Msg('Average MEAN effect size = ' +realtostr((lsummean/lmediancount),3));
- Msg('Average MEDIAN effect size = ' +realtostr((lsummedian/lmediancount),3));
- {$ENDIF}
- Msg('Only tested voxels with more than '+inttostr(lnCrit)+' lesions');
- //Next: save results from permutation thresholding....
- reportBonferroni('Std',lnVoxTested);
- //next: save data
- MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
-//save sum map
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Sum'+lFactName,'.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgSum,1);
-//create new header - subsequent images will use Z-scores
- MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
- if Sum2PowerCont(lOutImgSum,lVolVox,lImages.Count) then begin
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Power'+lFactName,'.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgSum,1);
- end;
-
- //MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
-if lttest then begin //save Ttest
- //next: convert t-scores to z scores
- for lPos := 1 to lVolVox do
- lOutImgT^[lPos] := TtoZ (lOutImgT^[lPos],lImages.Count-2);
- for lPos := 1 to lnPermute do begin
- lPermuteMaxT^[lPos] := TtoZ (lPermuteMaxT^[lPos],lImages.Count-2);
- lPermuteMinT^[lPos] := TtoZ (lPermuteMinT^[lPos],lImages.Count-2);
- end;
- lThresh := reportFDR ('ttest', lVolVox, lnVoxTested, lOutImgT);
- reportPermute('ttest',lnPermute,lPermuteMaxT, lPermuteMinT);
- lOutNameMod := ChangeFilePostfixExt(lOutName,'ttest'+lFactName,'.hdr');
- if lRun > 0 then
- Msg('threshtt,'+inttostr(lRun)+','+inttostr(ThreshMap(lThresh,lVolVox,lOutImgT))+','+realtostr(lThresh,3));
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgT,1);
-
-end;
-if lBM then begin //save Mann Whitney
- lThresh := reportFDR ('BM', lVolVox, lnVoxTested, lOutImgBM);
- reportPermute('BM',lnPermute,lPermuteMaxBM, lPermuteMinBM);
- lOutNameMod := ChangeFilePostfixExt(lOutName,'BM'+lFactName,'.hdr');
- if lRun > 0 then
- Msg('threshbm,'+inttostr(lRun)+','+inttostr(ThreshMap(lThresh,lVolVox,lOutImgBM))+','+realtostr(lThresh,3));
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgBM,1);
-
-end;
-//next: free dynamic memory
-123:
- FreePermute (lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp);
- freemem(lOutImgT);
- freemem(lOutImgBM);
- freemem(lOutImgSum);
- freemem(lObsp);
- freemem(lPlankImg);
- Msg('Analysis finished = ' +TimeToStr(Now));
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes'+lFactName,'.txt');
- MsgSave(lOutNameMod);
- ProgressBar1.Position := 0;
- exit;
-667: //you only get here if you aborted ... free memory and report error
- if lTotalMemory > 1 then freemem(lPlankImg);
- Msg('Unable to complete analysis.');
- ProgressBar1.Position := 0;
-end; //LesionNPMAnalyze *)
-
-
-(*function TMainForm.LesionNPMAnalyzeBinomial (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lnCrit: integer; var lSymptomRA: SingleP; var lFactname,lOutName: string): boolean;
-label
- 123,667;
-var
- lVal: single;
- lOutNameMod: string;
- lPlankImg: byteP;
- lOutImgSum,lOutImgL,lDummyImg,
- lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP;
- lPos,lPlank,lThread,lnDeficit: integer;
- lTotalMemory,lVolVox,lMinMask,lMaxMask,lnPlanks,lVoxPerPlank,
- lThreadStart,lThreadInc,lThreadEnd, lnLesion,lnPermute,
- lPos2,lPos2Offset,lStartVox,lEndVox,lPlankImgPos,lnTests,lnVoxTested,lPosPct: int64;
- lT, lSum: double;
- lObsp: pointer;
- lObs: Doublep0;
- lStatHdr: TNIfTIhdr;
- lFdata: file;
- lRanOrderp: pointer;
- lRanOrder: Doublep0;
+procedure TMainForm.Copy1Click(Sender: TObject);
begin
- lnPermute := ReadPermute;
- Msg('Permutations = ' +IntToStr(lnPermute));
- //lOutName := lMaskHdr.ImgFileName;
- //if not SaveHdrName ('Statistical Map', lOutName) then exit;
- Msg('Analysis began = ' +TimeToStr(Now));
- lTotalMemory := 0;
- lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
- if (lVolVox < 1) then goto 667;
- lMinMask := 1;
- lMaxMask := lVolVox;
- lVoxPerPlank := kPlankSz div lImages.Count div sizeof(byte) ;
- if (lVoxPerPlank = 0) then goto 667; //no data
- lTotalMemory := ((lMaxMask+1)-lMinMask) * lImages.Count;
- if (lTotalMemory = 0) then goto 667; //no data
- lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
- Msg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
- Msg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
- if (lnPlanks = 1) then
- getmem(lPlankImg,lTotalMemory) //assumes 1bp
- else
- getmem(lPlankImg,kPlankSz);
- lStartVox := lMinMask;
- lEndVox := lMinMask-1;
- for lPos := 1 to lImages.Count do
- if gScaleRA[lPos] = 0 then
- gScaleRA[lPos] := 1;
- createArray64(lObsp,lObs,lImages.Count);
- getmem(lOutImgSum,lVolVox* sizeof(single));
- getmem(lOutImgL,lVolVox* sizeof(single));
- InitPermute (lImages.Count, lnPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
- for lPos := 1 to lVolVox do begin
- lOutImgSum^[lPos] := 0;
- lOutImgL^[lPos] := 0;
- end;
- ClearThreadDataPvals(gnCPUThreads,lnPermute) ;
- for lPlank := 1 to lnPlanks do begin
- ProgressBar1.Position := 1;
- Msg('Computing plank = ' +Inttostr(lPlank));
- Refresh;
- Application.processmessages;
- lEndVox := lEndVox + lVoxPerPlank;
- if lEndVox > lMaxMask then begin
- lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
- lEndVox := lMaxMask;
- end;
- lPlankImgPos := 1;
- for lPos := 1 to lImages.Count do begin
- if not LoadImg8(lImages[lPos-1], lPlankImg, lStartVox, lEndVox,round(gOffsetRA[lPos]),lPlankImgPos,gDataTypeRA[lPos],lVolVox) then
- goto 667;
- lPlankImgPos := lPlankImgPos + lVoxPerPlank;
- end;//for each image
- //threading start
- lThreadStart := 1;
- lThreadInc := lVoxPerPlank div gnCPUThreads;
- lThreadEnd := lThreadInc;
- Application.processmessages;
- for lThread := 1 to gnCPUThreads do begin
- if lThread = gnCPUThreads then
- lThreadEnd := lVoxPerPlank; //avoid integer rounding error
- //with TLesionBinomial.Create (ProgressBar1,false,true,lnCrit, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,666, lDummyImg,lPlankImg,lOutImgSum,lOutImgL,lDummyImg,lSymptomRA) do
- with TLesionBinom.Create (ProgressBar1,false,true,lnCrit, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,0,lPlankImg,lOutImgSum,lOutImgL,lDummyImg,nil,lSymptomRA) do
- {$IFDEF FPC} OnTerminate := @ThreadDone; {$ELSE}OnTerminate := ThreadDone;{$ENDIF}
- inc(gThreadsRunning);
- Msg('Thread ' +Inttostr(gThreadsRunning)+' = '+inttostr(lThreadStart)+'..'+inttostr(lThreadEnd));
- lThreadStart := lThreadEnd + 1;
- lThreadEnd :=lThreadEnd + lThreadInc;
- end; //for each thread
- repeat
- Application.processmessages;
- until gThreadsRunning = 0;
- Application.processmessages;
- //threading end
- lStartVox := lEndVox + 1;
- end;
- lnVoxTested := SumThreadData(gnCPUThreads,lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM);
- for lPos := 1 to lnPermute do begin
- if (lPermuteMinT^[lPos] > 1.1) or (lPermuteMinT^[lPos] < -1.1) then
- lPermuteMinT^[lPos] := 0.5;
- if (lPermuteMaxT^[lPos] > 1.1) or (lPermuteMaxT^[lPos] < -1.1) then
- lPermuteMaxT^[lPos] := 0.5;
- lVal := lPermuteMaxT^[lPos];
- lPermuteMaxT^[lPos] := lPermuteMinT^[lPos];
- lPermuteMinT^[lPos] := lVal;
- if lPermuteMaxT^[lPos] < 0 then
- lPermuteMaxT^[lPos] := -pNormalInv(abs(lPermuteMaxT^[lPos]))
- else
- lPermuteMaxT^[lPos] := pNormalInv(lPermuteMaxT^[lPos]);
- if lPermuteMinT^[lPos] < 0 then
- lPermuteMinT^[lPos] := -pNormalInv(abs(lPermuteMinT^[lPos]))
- else
- lPermuteMinT^[lPos] := pNormalInv(lPermuteMinT^[lPos]);
- end;
-
-
-
- if lnVoxTested < 1 then begin
- Msg('**Error: no voxels tested: no regions lesioned in at least '+inttostr(lnCrit)+' patients**');
- goto 123;
- end;
- //next report findings
- Msg('Voxels tested = ' +Inttostr(lnVoxTested));
- Msg('Only tested voxels with more than '+inttostr(lnCrit)+' lesions');
- //Next: save results from permutation thresholding....
- reportBonferroni('Std',lnVoxTested);
- //next: save data
-//savedata
- MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
-//save sum map
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Sum'+lFactName,'.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgSum,1);
-//future images will store Z-scores...
- MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
-//save power map
- lnDeficit := 0;
- for lPos := 1 to lImages.Count do
- if lSymptomRA^[lPos] = 0 then
- inc(lnDeficit);
- if Sum2Power(lOutImgSum,lVolVox,lImages.Count,lnDeficit) then begin
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Power'+lFactName,'.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgSum,1);
- end;
- // MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
- //save Liebermeister
-
- lOutNameMod := ChangeFilePostfixExt(lOutName,'L'+lFactName,'.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgL,1);
- //save end
- reportFDR ('L', lVolVox, lnVoxTested, lOutImgL);
- reportPermute('L',lnPermute,lPermuteMaxT, lPermuteMinT);
-
-123:
-//next: free dynamic memory
- FreePermute (lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp);
- freemem(lOutImgL);
- freemem(lOutImgSum);
- freemem(lObsp);
- freemem(lPlankImg);
- Msg('Analysis finished = ' +TimeToStr(Now));
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes'+lFactName,'.txt');
- MsgSave(lOutNameMod);
+ Memo1.SelectAll;
+ Memo1.CopyToClipboard;
- ProgressBar1.Position := 0;
- exit;
-667: //you only get here if you aborted ... free memory and report error
- if lTotalMemory > 1 then freemem(lPlankImg);
- Msg('Unable to complete analysis.');
- ProgressBar1.Position := 0;
-end; *)
-
-
-function TMainForm.GetValX (var lnSubj, lnFactors: integer; var lSymptomRA: singleP; var lImageNames: TStrings; var lCrit: integer; {lBinomial : boolean;} var lPredictorList: TStringList):boolean;
-//warning: you MUST free lPredictorList
-var
- lVALFilename {,lTemplateName}: string;
- lCritPct: integer;
-begin
- lPredictorList := TStringList.Create;
- result := false;
- lnSubj := 0;
- if not MainForm.OpenDialogExecute('Select MRIcron VAL file',false,false,'MRIcron VAL (*.val)|*.val') then begin
- showmessage('NPM aborted: VAL file selection failed.');
- exit;
- end; //if not selected
- lVALFilename := MainForm.OpenHdrDlg.Filename;
- result := GetValCore ( lVALFilename, lnSubj, lnFactors, lSymptomRA, lImageNames, lCrit,lCritPct{,binom},lPredictorList);
end;
-
-function TMainForm.ReportDescriptives (var RA: SingleP; n: integer): boolean;
-var lMn,lSD,lSE,lSkew,lZSkew: double;
+procedure TMainForm.StartTimerTimer(Sender: TObject);
begin
- SuperDescriptive (RA, n, lMn,lSD,lSE,lSkew,lZSkew);
- Msg('mean='+floattostr(lMn)+',StDev='+floattostr(lSD)+',StEr='+floattostr(lSE)+',Skew='+floattostr(lSkew)+',ZSkew='+floattostr(lZSkew));
-end;
+ if StartTimer.Tag < 2 then begin
+ StartTimer.tag := StartTimer.tag + 1;
+ exit;
-(*function noVariance (lRA: singlep; lnSubj: integer): boolean;
-var
- lI : integer;
-begin
- result := false;
- if lnSubj < 2 then exit;
- for lI := 2 to lnSubj do
- if lRA^[1] <> lRA^[lI] then
- exit;
- result := true;
-end; *)
+ end;
-(*procedure TMainForm.LesionBtnClick(Sender: TObject);
-label
- 666;
-var
- lBinomial: boolean;
- lFact,lnFactors,lSubj,lnSubj,lnSubjAll,lMaskVoxels,lnCrit: integer;
- lImageNames,lImageNamesAll: TStrings;
- lPredictorList: TStringList;
- lTemp4D,lMaskname,lOutName,lFactname: string;
- lMaskHdr: TMRIcroHdr;
- lMultiSymptomRA,lSymptomRA: singleP;
-begin
- lBinomial := not odd( (Sender as tMenuItem).tag);
- if (not lBinomial) and (not ttestmenu.checked) and (not BMmenu.checked) then begin
- Showmessage('Error: you need to compute at least on test [options/test menu]');
- exit;
- end;
- lImageNamesAll:= TStringList.Create; //not sure why TStrings.Create does not work???
- lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
- //next, get 1st group
- if not GetVal(lnSubjAll,lnFactors,lMultiSymptomRA,lImageNamesAll,lnCrit{,binom},lPredictorList) then begin
- showmessage('Error with VAL file');
- goto 666;
- end;
- lTemp4D := CreateDecompressed4D(lImageNamesAll);
- if (lnSubjAll < 1) or (lnFactors < 1) then begin
- Showmessage('Not enough subjects ('+inttostr(lnSubjAll)+') or factors ('+inttostr(lnFactors)+').');
- goto 666;
- end;
- lMaskname := lImageNamesAll[0];
- if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- showmessage('Error reading 1st mask.');
- goto 666;
- end;
- lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
- if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
- showmessage('Mask file size too small.');
- goto 666;
- end;
- if not CheckVoxelsGroup(lImageNamesAll,lMaskVoxels) then begin
- showmessage('File dimensions differ from mask.');
- goto 666;
- end;
- lOutName := ExtractFileDirWithPathDelim(lMaskName)+'results';
- SaveHdrDlg.Filename := loutname;
- lOutName := lOutName+'.nii.gz';
- if not SaveHdrName ('Base Statistical Map', lOutName) then goto 666;
- for lFact := 1 to lnFactors do begin
- MsgClear;
- Msg(GetKVers);
- lImageNames.clear;
- for lSubj := 1 to lnSubjAll do
- if (not lBinomial) or (lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)] = 0) OR (lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)] = 1) THEN begin
- {$IFNDEF FPC}if lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)] <> NaN then {$ENDIF}
- lImageNames.Add(lImageNamesAll[lSubj-1]);
- end else begin
- Msg('Data rejected: behavior must be zero or one for binomial test '+lImageNamesAll.Strings[lSubj-1]);
- end;
- lnSubj := lImageNames.Count;
- if lnSubj > 1 then begin
- getmem(lSymptomRA,lnSubj * sizeof(single));
- lnSubj := 0;
- for lSubj := 1 to lnSubjAll do
- if (not lBinomial) or (lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)] = 0) OR (lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)] = 1) THEN
- {$IFNDEF FPC}if lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)] <> NaN then begin
- {$ELSE} begin{$ENDIF}
- inc(lnSubj);
- lSymptomRA^[lnSubj] := lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)];
- end;
- Msg('Threads: '+inttostr(gnCPUThreads));
- lFactName := lPredictorList.Strings[lFact-1];
- lFactName := LegitFilename(lFactName,lFact);
- Msg('Factor = '+lFactname);
- For lSubj := 1 to lnSubj do
- Msg (lImageNames.Strings[lSubj-1] + ' = '+realtostr(lSymptomRA^[lSubj],2) );
- Msg('Total voxels = '+inttostr(lMaskVoxels));
- Msg('Only testing voxels damaged in at least '+inttostr(lnCrit)+' individual[s]');
- Msg('Number of Lesion maps = '+inttostr(lnSubj));
- if not CheckVoxelsGroup(lImageNames,lMaskVoxels) then begin
- showmessage('File dimensions differ from mask.');
- goto 666;
- end;
- if noVariance (lSymptomRA,lnSubj) then
- Msg('Error no variability in behavioral data ')
- else if lBinomial then
- LesionNPMAnalyzeBinomial2(lImageNames,lMaskHdr,lnCrit,MainForm.ReadPermute,lSymptomRA,lFactname,lOutName)
- else begin
- ReportDescriptives(lSymptomRA,lnSubj);
- LesionNPMAnalyze2(lImageNames,lMaskHdr,lnCrit,-1,MainForm.ReadPermute,lSymptomRA,lFactName,lOutname,ttestmenu.checked,BMmenu.checked);
- end;
- Freemem(lSymptomRA);
- end; //lnsubj > 1
- end; //for each factor
- if lnSubjAll > 0 then begin
- Freemem(lMultiSymptomRA);
- end;
- 666:
- lImageNames.Free;
- lImageNamesAll.Free;
- lPredictorList.Free;
- DeleteDecompressed4D(lTemp4D);
-end; *)
+ StartTimer.Enabled := false;
+ if (ParamCount > 0) then ProcessParamStr;
-procedure TMainForm.Copy1Click(Sender: TObject);
-begin
- Memo1.SelectAll;
- Memo1.CopyToClipBoard;
end;
procedure TMainForm.testmenuclick(Sender: TObject);
begin
(sender as TMenuItem).checked := not (sender as TMenuItem).checked;
+ gNPMprefs.BMtest := BMmenu.Checked;
+ gNPMprefs.ttest := TTestmenu.Checked;
end;
procedure TMainForm.radiomenuclick(Sender: TObject);
begin
(sender as tmenuitem).checked := true;
+ gNPMprefs.nPermute:= readPermute;
end;
-procedure ComputePlankSize;
-begin
- if kPlankMB < 128 then
- kPlankMB := 128;
- if kPlankMB > 2000 then
- kPlankMB := 2000; //we use signed 32-bit pointers, so we can not exceed 2Gb
- kPlankSz :=1024 {bytes/kb} * 1024 {bytes/mb} * kPlankMB;
- kVers := kVers + ' CacheMB = '+inttostr(kPlankMB);
-end;
-
-procedure TMainForm.ReadIniFile;
-var
- lFilename: string;
- lThreads: integer;
- lIniFile: TIniFile;
-begin
- lFilename := IniName;
- if not FileexistsEx(lFilename) then
- exit;
- lIniFile := TIniFile.Create(lFilename);
- ttestmenu.checked := IniBool(lIniFile,'computettest',true);
- //welchmenu.checked := IniBool(lIniFile,'computewelch',true);
- BMmenu.checked := IniBool(lIniFile,'computebm',false);
- gNULP := IniBool(lIniFile,'countlesionpatterns',false);
- gROI := IniBool(lIniFile,'ROI',false);
- kPlankMB := IniInt(lIniFile,'CacheMB',512);
-
- WritePermute(IniInt(lIniFile,'nPermute',0));
- lThreads := IniInt(lIniFile,'nThread', gnCPUThreads );
- if lThreads > gnCPUThreads then
- lThreads := gnCPUThreads;
- gnCPUThreads := lThreads;
- lIniFile.Free;
-end; //ReadIniFile
-
-procedure TMainForm.WriteIniFile;
-var
- lIniName: string;
- lIniFile: TIniFile;
-begin
-//showmessage('aaa');
- lIniName := IniName;
- if (DiskFreeEx(lIniName) < 1) then
- exit;
- lIniFile := TIniFile.Create(lIniName);
- lIniFile.WriteString('BOOL', 'computettest',Bool2Char(ttestmenu.checked));
- lIniFile.WriteString('BOOL', 'countlesionpatterns',Bool2Char(gNULP));
- lIniFile.WriteString('BOOL', 'ROI',Bool2Char(gROI));
-
- //lIniFile.WriteString('BOOL', 'computewelch',Bool2Char(welchmenu.checked));
- lIniFile.WriteString('BOOL', 'computebm',Bool2Char(BMmenu.checked));
- lIniFile.WriteString('INT', 'CacheMB',inttostr(kPlankMB));
- lIniFile.WriteString('INT', 'nPermute',inttostr(ReadPermute));
- lIniFile.WriteString('INT', 'nThread',inttostr(ReadThread));
- lIniFile.Free;
-end;
-
-
-
procedure TMainForm.FormCreate(Sender: TObject);
begin
{$IFDEF Darwin}
File1.visible := false;//for OSX, exit is in the application's menu
- Edit1.visible := false;//clipboard note yet working for OSX
+ //Edit1.visible := false;//clipboard note yet working for OSX
{$ENDIF}
{$IFDEF FPC}
Application.ShowButtonGlyphs := sbgNever;
{$ENDIF}
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+ Copy1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ BinomialAnalysislesions1.ShortCut := ShortCut(Word('B'), [ssMeta]);
+ Binaryimagescontinuousgroupsfast1.ShortCut := ShortCut(Word('L'), [ssMeta]);
+ Design1.ShortCut := ShortCut(Word('D'), [ssMeta]);
+ ContinuousanalysisVBM1.ShortCut := ShortCut(Word('V'), [ssMeta]);
+ MultipleRegress.ShortCut := ShortCut(Word('R'), [ssMeta]);
+ Makemeanimage1.ShortCut := ShortCut(Word('M'), [ssMeta]);
+ About1.ShortCut := ShortCut(Word('A'), [ssMeta]);
+ {$ENDIF}//Carbon
+ {$ENDIF}//Darwin
gnCPUThreads := GetLogicalCpuCount;
(*if (ssShift in KeyDataToShiftState(vk_Shift)) then begin
case MessageDlg('Shift key down during launch: do you want to reset the default preferences?', mtConfirmation,
@@ -1513,540 +458,83 @@ begin
end else *)
if not ResetDefaults then
ReadIniFile;
- WriteThread(gnCPUThreads);
- ComputePlankSize;
- ROIanalysis1.visible := gROI;
- {$IFDEF compileANACOM}
- AnaCOMmenu.visible := gROI;
- {$ENDIF}
-end;
-
-
-
-
-function TMainForm.MakeMean (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lBinarize,lVariance : boolean): boolean;
-label
- 667;
-var
- lOutName,lOutNameMod: string;
- lCountRA,lOutImgMn,lOutStDev,lPlankImg: SingleP;
- lTotalMemory: double;
- lPlank,lVolVox,lPos,lMinMask,lMaxMask,lnPlanks,lVoxPerPlank,
- lPos2,lPos2Offset,lStartVox,lEndVox,lPlankImgPos,lnTests,lnVoxTested,lPosPct: integer;
- lStDev: boolean;
- lT, lSum,lSumSqr,lSD, lMn,lTotalSum,lTotalN: double;
- lStatHdr: TNIfTIhdr;
- lFdata: file;
-begin
- result := false;
- if not SaveHdrName ('Output image', lOutName) then exit;
- if (not lVariance) and (not lBinarize) then
- lStDev := true
- else
- lStDev := false;
- if lStDev then
- lStDev := OKMsg('Create a standard deviation image as well as a mean image?');
- Msg('Analysis began = ' +TimeToStr(Now));
- lTotalMemory := 0;
- lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
- if (lVolVox < 1) then goto 667;
- lMinMask := 1;
- lMaxMask := lVolVox;
- lVoxPerPlank := kPlankSz div lImages.Count div sizeof(single) ;
- if (lVoxPerPlank = 0) then goto 667; //no data
- lTotalMemory := ((lMaxMask+1)-lMinMask) * lImages.Count;
- if (lTotalMemory = 0) then goto 667; //no data
- lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
- Msg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
- Msg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
- // fx(kPlankSz,8888);
- getmem(lPlankImg,kPlankSz);
- lStartVox := lMinMask;
- lEndVox := lMinMask-1;
- Msg('Number of scans = '+inttostr(lImages.count));
- Msg(' Index,Filename,Intercept,Slope');
- if lBinarize then begin
- getmem(lCountRA,lImages.Count*sizeof(single));
- for lPos := 1 to lImages.Count do begin
- gInterceptRA[lPos] := 0;
- gScaleRA[lPos] := 1;
- lCountRA^[lPos] := 0;
- end;
- end else begin
- for lPos := 1 to lImages.Count do begin
- Msg(' '+inttostr(lPos)+','+lImages[lPos-1]+','+realtostr(gInterceptRA[lPos],4)+','+realtostr(gScaleRA[lPos],4));
- if gScaleRA[lPos] = 0 then
- gScaleRA[lPos] := 1;
- end;
- end;
-
- lTotalSum := 0;
- lTotalN := 0;
- //createArray64(lObsp,lObs,lImages.Count);
- getmem(lOutImgMn,lVolVox* sizeof(single));
- if lStDev then
- getmem(lOutStDev,lVolVox* sizeof(single));
- for lPlank := 1 to lnPlanks do begin
- Msg('Computing plank = ' +Inttostr(lPlank));
- Refresh;
- lEndVox := lEndVox + lVoxPerPlank;
- if lEndVox > lMaxMask then begin
- lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
- lEndVox := lMaxMask;
- end;
- lPlankImgPos := 1;
- for lPos := 1 to lImages.Count do begin
- if not LoadImg(lImages[lPos-1], lPlankImg, lStartVox, lEndVox,round(gOffsetRA[lPos]),lPlankImgPos,gDataTypeRA[lPos],lVolVox) then
- goto 667;
- lPlankImgPos := lPlankImgPos + lVoxPerPlank;
- end;//for each image
- lPosPct := lVoxPerPlank div 100;
- for lPos2 := 1 to lVoxPerPlank do begin
- if (lPos2 mod lPosPct) = 0 then begin
- ProgressBar1.Position := round((lPos2/lVoxPerPlank)*100);
- Application.Processmessages;
- end;
- lPos2Offset := lPos2+lStartVox-1;
- lSum := 0;
- if lVariance then begin
- lSum := sqr(lPlankImg^[lPos2]-lPlankImg^[lVoxPerPlank+lPos2]);//actually variance...
- //% signal
- //if lPlankImg[lVoxPerPlank+lPos2] <> 0 then
-
- // lSum := lPlankImg[lPos2]/lPlankImg[lVoxPerPlank+lPos2]
- //else
- // lSum := 0;//pct signal...
- //end % signal
- lOutImgMn^[lPos2Offset] := lSum;
- lTotalSum := lTotalSum + lOutImgMn^[lPos2Offset];
- lTotalN := lTotalN + 1;
- end else begin //not variance
-
- if lBinarize then begin
- for lPos := 1 to lImages.Count do
- if lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2] <> 0 then begin
- lSum := lSum+1;
- lCountRA^[lPos] := lCountRA^[lPos] + 1;
- end;
- end else
- for lPos := 1 to lImages.Count do
- lSum := lSum +(gScaleRA[lPos]*lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2])+gInterceptRA[lPos];
- // fx(lPos, gScaleRA[lPos],gInterceptRA[lPos]);
- lOutImgMn^[lPos2Offset] := lSum/lImages.Count;
- if lStDev then begin
- //lSum := 0;
- //for lPos := 1 to lImages.Count do
- // lSum := lSum + (gScaleRA[lPos]*lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2])+gInterceptRA[lPos];
- lSumSqr := 0;
- for lPos := 1 to lImages.Count do
- lSumSqr := lSumSqr + Sqr((gScaleRA[lPos]*lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2])+gInterceptRA[lPos]);
- lSD := (lSumSqr - ((Sqr(lSum))/lImages.Count));
- if (lSD > 0) then
- lSD := Sqrt ( lSD/(lImages.Count-1))
- else begin
- lSD := 0;
- (*if l1stError then begin
- for lPos := 1 to lImages.Count do
- Msg(floattostr( (gScaleRA[lPos]*lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2])+gInterceptRA[lPos]));
- msg('---');
- msg(floattostr(lSum));
- msg(floattostr(lSumSqr));
-
- l1stError := false;
- end;*)
- end;
- lOutStDev^[lPos2Offset] := lSD;
- end;
- end; //not variance
- if lSum > 0 then begin
- lTotalSum := lTotalSum + lOutImgMn^[lPos2Offset];
- lTotalN := lTotalN + 1;
- end;
- end;
- lStartVox := lEndVox + 1;
- end;
- if lBinarize then begin
- for lPos := 1 to lImages.Count do begin
- Msg(' '+inttostr(lPos)+','+lImages[lPos-1]+','+inttostr(round(lCountRA^[lPos])) );
-
- lCountRA^[lPos] := 0;
- end;
- freemem(lCountRA);
- end; //if binar
- //next: save data
- MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
-//save mean
-
-
-if lVariance then
- lOutNameMod := ChangeFilePostfixExt(lOutName,'var','.hdr')
-else
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Mean','.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgMn,1);
- freemem(lOutImgMn);
- if lStDev then begin
- lOutNameMod := ChangeFilePostfixExt(lOutName,'StDev','.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutStDev,1);
- freemem(lOutStDev);
- end;
-
- //freemem(lObsp);
- freemem(lPlankImg);
- Msg('Analysis finished = ' +TimeToStr(Now));
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes','.txt');
- MsgSave(lOutNameMod);
- if (lTotalN > 0) then
- Msg('num voxels >0 = ' +inttostr(round(lTotalN))+' mean value for voxels >0: '+floattostr(lTotalSum/lTotalN));
-
- ProgressBar1.Position := 0;
- exit;
-667: //you only get here if you aborted ... free memory and report error
- if lTotalMemory > 1 then freemem(lPlankImg);
- Msg('Unable to complete analysis.');
- ProgressBar1.Position := 0;
+ ttestmenu.checked := gNPMprefs.ttest;
+ bmmenu.Checked:= gNPMprefs.BMtest;
+ WritePermute(gNPMprefs.nPermute);
+ WriteThread(gnCPUThreads);
end;
-procedure TMainForm.Makemeanimage1Click(Sender: TObject);
+(*procedure TMainForm.Makemeanimage1Click(Sender: TObject);
label
666;
var
- lMaskVoxels: integer;
lG: TStrings;
- lMaskname: string;
- lMaskHdr: TMRIcroHdr;
+ loutname: string;
begin
- MsgClear;
- Msg(GetKVers);
+
if not OpenDialogExecute('Select images to average',true,true,kImgFilter) then begin
- showmessage('NPM aborted: file selection failed.');
+ ShowMsg('NPM aborted: file selection failed.');
exit;
end; //if not selected
- lG:= TStringList.Create;
- lG.addstrings(OpenHdrDlg.Files);
- lMaskname := lG[0];
- if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- showmessage('Error reading '+lMaskName);
- goto 666;
- end;
- lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
- if not CheckVoxelsGroupX(lG,lMaskHdr {lMaskVoxels}) then begin
- showmessage('File dimensions differ from mask.');
- goto 666;
- end;
- Msg('Voxels = '+inttostr(lMaskVoxels));
- MakeMean(lG,lMaskHdr, odd((Sender as TMenuItem).tag),false);
- 666:
- lG.Free;
-end;
-
-procedure TMainForm.Exit1Click(Sender: TObject);
-begin
- Close;
-end;
-
-function MinMax (var lImg: SingleP; var lVolVox: integer; var lMin, lMax: single): boolean;
-var
- lC: integer;
-begin
- result := false;
- if lVolVox < 1 then
- exit;
- lMax := lImg^[1];
- for lC := 1 to lVolVox do
- if lImg^[lC] > lMax then
- lMax := lImg^[lC];
- //lCx := lC;
- lMin := lImg^[1];
- for lC := 1 to lVolVox do
- if lImg^[lC] < lMin then
- lMin := lImg^[lC];
- result := true;
-end;
-
-function DetectMode (var lImg: SingleP; var lVolVox: integer; var lMin, lMax, lModeLo,lModeHi: single; lInflection: boolean): boolean;
-const
- kHistoBins = 255;//numbers of bins for histogram/image balance
-var
- lSmooth,lPrevSmooth,lModeWid,lC,lMinPos,lMode,lModePos,lMaxModePos,lMode2NotInflection: integer;
- lMod,lRng: single;
- lHisto : array [0..kHistoBins] of longint;
-begin
-
- result := false;
- if (lVolVox < 1) or (lMax < lMin) then
- exit;
- //zero array
- for lC := 1 to kHistoBins do
- lHisto[lC] := 0;
- //find scaling
- lRng := abs(lMax-lMin);
- if lRng > 0 then
- lMod := (kHistoBins)/lRng
- else
- lMod := 0;
- //fill histogram
- for lC := 1 to lVolVox do
- if lImg^[lC] <> 0 then
- inc(lHisto[round((lImg^[lC]-lMin)*lMod)]);
-
- {for lC := 1 to lVolVox do
- inc(lHisto[round((lImg^[lC]-lMin)*lMod)]); }
- //smooth histogram
- lPrevSmooth := lHisto[1];
- for lC := 2 to (kHistoBins-1) do begin
- lSmooth := round( (lHisto[lC-1]+lHisto[lC]+lHisto[lC]+lHisto[lC+1])/4);
- lHisto[lC-1] := lPrevSmooth;
- lPrevSmooth := lSmooth;
- end;
- lHisto[kHistoBins-1] := lPrevSmooth;
- //find mode
- lMode := 0;
- lMinPos := 1;//indexed from zero
- //find highest peak
- for lC := lMinPos to kHistoBins do begin
- if lHisto[lC] > lMode then begin
- lModePos := lC;
- lMode := lHisto[lC];
- end;//if new mode
- end; //for each bin
- if lMode > 0 then
- lMaxModePos := lModePos
- else
- exit;
- //find 2nd highest peak
- //find 2nd highest peak
- lModeWid := 25;
- lModePos := lMinPos;
- lMode := lHisto[lMinPos];
- if (lMaxModePos - lModeWid) > lMinPos then begin
- for lC := lMinPos to (lMaxModePos - lModeWid) do begin
- if lHisto[lC] > lMode then begin
- lModePos := lC;
- lMode := lHisto[lC];
- end;//if new mode
- end; //for each bin
- end; //check below highest peak
- if (lMaxModePos + lModeWid) < kHistoBins then begin
- for lC := (lMaxModePos + lModeWid) to kHistoBins do begin
- if lHisto[lC] > lMode then begin
- lModePos := lC;
- lMode := lHisto[lC];
- end;//if new mode
- end; //for each bin
- end; //check above highest peak
- //fx(lModePos);
- //an alternative method to find mode is to look for inflection - less assumptions, more sensitive to noise
- if lInflection then begin
- lMode2NotInflection := lModePos;
- lModePos := lMinPos;
-
- lMode := 0;
- lC := lMaxModePos;
- while ((lC-1) > lMinPos) and (lHisto[lC] > lHisto[lC-1]) do
- dec(lC); //find inflection
- while ((lC-1) > lMinPos) do begin
- dec(lC);
- if lHisto[lC] > lMode then begin
- lModePos := lC;
- lMode := lHisto[lC];
- end;//if new mode
- end; //look for mode
-
- lC := lMaxModePos;
- while ((lC+1) <= kHistoBins) and (lHisto[lC] > lHisto[lC+1]) do
- inc(lC); //find inflection
- while ((lC+1) <= kHistoBins) do begin
- inc(lC);
- if lHisto[lC] > lMode then begin
- lModePos := lC;
- lMode := lHisto[lC];
- end;//if new mode
- end; //look for mode
-
- if abs(lMode2NotInflection-lModePos) > 3 then
- Showmessage('Warning: inflection and windowed algorithms find different 2nd modes. Using inflection 2nd mode. inflection ='+inttostr(lModePos)+' windowed: '+inttostr(lMode2NotInflection));
-
- end;
- //now, return scaled values...
- if lMod = 0 then exit;
- lModeLo := (lModePos/lMod)+lMin;
- lModeHi := (lMaxModePos/lMod)+lMin;
- if lModeLo > lModeHi then begin
- lMod := lModeLo;
- lModeLo := lModeHi;
- lModeHi := lMod;
- end;
- result := true;
-end;
-
-
-procedure CopyFileEXoverwrite (lInName,lOutName: string);
-var lFSize: Integer;
- lBuff: bytep0;
- lFData: file;
-begin
- lFSize := FSize(lInName);
- if (lFSize < 1) then exit;
- assignfile(lFdata,lInName);
- filemode := 0;
- reset(lFdata,lFSize{1});
- GetMem( lBuff, lFSize);
- BlockRead(lFdata, lBuff^, 1{lFSize});
- closefile(lFdata);
- assignfile(lFdata,lOutName);
- filemode := 2;
- Rewrite(lFdata,lFSize);
- BlockWrite(lFdata,lBuff^, 1 {, NumWritten});
- closefile(lFdata);
- freemem(lBuff);
-end;
-
-procedure CopyFileEX (lInName,lOutName: string);
-var lFSize: Integer;
-begin
- lFSize := FSize(lInName);
- if (lFSize < 1) or (fileexistsEX(lOutName)) then exit;
- CopyFileEXoverwrite (lInName,lOutName);
-end;
-
-
-function DetectMeanStDev (var lImg: SingleP; var lVolVox: integer; var lMean,lStDev: double): boolean;
-var
- lIncVox,lVox: integer;
- lSum,lSumSqr,lSE: double;
-begin
- lMean := 0;
- lStDev := 0;
- result := false;
- if (lVolVox < 1) then
- exit;
- lSum := 0;
- lSumSqr := 0;
- lIncVox := 0; //voxels included - e.g. not masked
- for lVox := 1 to lVolVox do begin
- if lImg^[lVox] <> 0 then begin //not in mask
- inc(lIncVox);
- lSum := lSum + lImg^[lVox];
- lSumSqr := lSumSqr + sqr(lImg^[lVox]);
- end;
- end;
- if lincVox < 3 then
- exit;
- Descriptive (lincVox, lSumSqr, lSum,lMean,lStDev,lSE);
- result := true;
-end; //DetectMeanStDev
- //zero array
-
-
-
-function TMainForm.Balance (var lImageName,lMaskName: String; {lInflection: boolean}lMethod: integer): boolean;
-//0 = masked peak
-//1 = inflection
-//2 = mean =1, stdev=1
-var
- lImg,lMaskImg: SingleP;
- lHdr,lMaskHdr: TMRIcroHdr;
- lVolVox,lVox,lMasked: integer;
- lMaskedInten,lMean,lStDev: double;
- lMin,lMax: single;
- lModeLo,lModeHi,lIntercept,lSlope: single;
- lOutNameMod: string;
-begin
- //lOutName := lMaskHdr.ImgFileName;
- result := false;
- //if not SaveHdrName ('Statistical Map', lOutName) then exit;
- if not NIFTIhdr_LoadHdr(lImageName,lHdr) then begin
- showmessage('Error reading '+lImageName);
- exit;
- end;
- lVolVox := lHdr.NIFTIhdr.dim[1]*lHdr.NIFTIhdr.dim[2]* lHdr.NIFTIhdr.dim[3];
- if (lVolVox < 1) then exit;
- getmem(lImg,lVolVox*sizeof(single));
- if not LoadImg(lHdr.ImgFileName, lImg, 1, lVolVox,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lVolVox) then begin
- Msg('Unable to load ' +lHdr.ImgFileName);
- exit;
- end;
- if lMaskName <> '' then begin
- if not NIFTIhdr_LoadHdr(lMaskName,lMaskHdr) then begin
- showmessage('Error reading '+lMaskName);
- exit;
- end;
- if lVolVox <> (lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3]) then begin
- showmessage('Mask and header must have identical dimensions '+lMaskName+ ' ' + lImageName);
- exit;
+ if not SaveHdrName ('Output image', lOutName) then exit;
+ lG:= TStringList.Create;
+ lG.addstrings(OpenHdrDlg.Files);
- end;
- getmem(lMaskImg,lVolVox*sizeof(single));
- if not LoadImg(lMaskHdr.ImgFileName, lMaskImg, 1, lVolVox,round(lMaskHdr.NIFTIhdr.vox_offset),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
- Msg('Unable to load mask ' +lMaskHdr.ImgFileName);
- exit;
- end;
- lMasked := 0;
- lMaskedInten := 0;
- for lVox := 1 to lVolVox do
- if lMaskImg^[lVox] = 0 then begin
- lMaskedInten := lMaskedInten + lImg^[lVox];
- lImg^[lVox] := 0;
- inc(lMasked);
- end;
- if lMasked < 1 then
- Msg('Warning: no voxels masked with image '+lMaskName)
- else
- Msg('Mask='+ lMaskName+' Number of voxels masked= '+inttostr(lMasked)+' Mean unscaled intensity of masked voxels= '+floattostr(lMaskedInten/lMasked));
- freemem(lMaskImg);
- end;//mask
-
- if not MinMax(lImg,lVolVox,lMin,lMax) then exit;
- Msg(lImageName+' -> '+lHdr.ImgFileName);
- Msg('min..max ' +floattostr(lMin)+'..'+floattostr(lMax));
- if (lMethod = 0) or (lMethod = 1) then begin
- if not DetectMode(lImg,lVolVox,lMin,lMax,lModeLo,lModeHi, odd(lMethod)) then exit;
- if odd(lMethod) then
- Msg('method for finding second mode: inflection')
- else
- Msg('method for finding second mode: masked peak');
- Msg('modes Lo Hi ' +floattostr(lModeLo)+'..'+floattostr(lModeHi));
- if lModeLo >= lModeHi then exit;
- lSlope := 1/abs(lModeHi-lModeLo);
- lIntercept := (abs(lModeHi-lModeLo)-(lModeLo))*lSlope ; //make mode lo = 1;
- end else begin
- DetectMeanStDev (lImg, lVolVox, lMean,lStDev);
- if lStDev <>0 then
- lSlope := 1/lStDev
- else begin
- Msg('Warning: StDev = 0!!!!');
- lSlope := 1;
- end;
- lIntercept := (-lMean*lSlope)+2; //mean voxel has intensity of zero
- Msg('method for intensity normalization: Mean = 2, StDev = 1');
- Msg('raw_Mean = '+floattostr(lMean)+' '+' raw_StDev = '+floattostr(lStDev));
+ MakeMean(lG,odd((Sender as TMenuItem).tag),false,loutname);
+ 666:
+ lG.Free;
+end; *)
+procedure TMainForm.Makemeanimage1Click(Sender: TObject);
+var
+ loutname: string;
+begin
+
+ if not OpenDialogExecute('Select images to average666',true,true,kImgFilter) then begin
+ ShowMsg('NPM aborted: file selection failed.');
+ exit;
+ end; //if not selected
+ if not SaveHdrName ('Output image', lOutName) then exit;
+ MakeMean(OpenHdrDlg.Files,odd((Sender as TMenuItem).tag),false,loutname);
+end;
- end;
- Msg('Slope/Intercept ' +floattostr(lSlope)+'..'+floattostr(lIntercept));
- lHdr.NIFTIhdr.scl_slope := lSlope;
- lHdr.NIFTIhdr.scl_inter := lIntercept;
- //CopyFileEX(lHdr.HdrFilename,changefileext( lHdr.HdrFilename,'.hdx'));
- RenameFile(lHdr.HdrFilename,changefileext( lHdr.HdrFilename,'.hdx'));
- //optional - save input
- lOutNameMod := ChangeFilePrefixExt(lImageName,'i','.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lHdr.NIFTIhdr,true,not IsNifTiMagic(lHdr.NIFTIhdr),true,lImg,1);
- //end optional
- NIFTIhdr_SaveHdr(lHdr.HdrFilename,lHdr.NIFTIhdr,true,not IsNifTiMagic(lHdr.NIFTIhdr));
- freemem(lImg);
+procedure TMainForm.Exit1Click(Sender: TObject);
+begin
+ Close;
end;
+(*procedure CopyFileEXoverwrite (lInName,lOutName: string);
+var lFSize: Integer;
+ lBuff: bytep0;
+ lFData: file;
+begin
+ lFSize := FSize(lInName);
+ if (lFSize < 1) then exit;
+ assignfile(lFdata,lInName);
+ filemode := 0;
+ reset(lFdata,lFSize{1});
+ GetMem( lBuff, lFSize);
+ BlockRead(lFdata, lBuff^, 1{lFSize});
+ closefile(lFdata);
+ assignfile(lFdata,lOutName);
+ filemode := 2;
+ Rewrite(lFdata,lFSize);
+ BlockWrite(lFdata,lBuff^, 1 {, NumWritten});
+ closefile(lFdata);
+ freemem(lBuff);
+end;*)
+
procedure TMainForm.Balance1Click(Sender: TObject);
var
lFilename,lMaskName: string;
lPos: Integer;
begin
- MsgClear;
- Msg(GetKVers);
+ NPMMsgClear;
+ NPMMsg(GetKVers);
if not OpenDialogExecute('Select images for intensity normalization',true,false,kImgFilter) then begin
- showmessage('NPM aborted: file selection failed.');
+ ShowMsg('NPM aborted: file selection failed.');
exit;
end; //if not selected
if OpenHdrDlg.Files.Count < 1 then
@@ -2058,29 +546,6 @@ begin
end;
end;
-procedure TMainForm.niiniigz1Click(Sender: TObject);
-var
- lFilename,lOutname,lPath,lName,lExt: string;
- lPos: Integer;
-begin
- MsgClear;
- Msg(GetKVers);
- if not OpenDialogExecute('Select images',true,false,kNIIFilter) then begin
- showmessage('NPM aborted: file selection failed.');
- exit;
- end; //if not selected
- if OpenHdrDlg.Files.Count < 1 then
- exit;
-
- for lPos := 1 to OpenHdrDlg.Files.Count do begin
- lFilename := OpenHdrDlg.Files[lPos-1];
- FilenameParts(lFilename,lPath,lName,lExt);
- lOutname := lPath+lName+'.nii.gz';
- msg('Compressing '+ lFilename+' -> '+lOutname);
- GZipFile(lFilename, lOutname,false);
- end;
- msg('Compression completed');
-end;
procedure TMainForm.Variance1Click(Sender: TObject);
label
@@ -2088,311 +553,35 @@ label
var
lMaskVoxels: integer;
lG: TStrings;
- lMaskname: string;
+ lMaskname,loutname: string;
lMaskHdr: TMRIcroHdr;
begin
- MsgClear;
- Msg(GetKVers);
+ NPMMsgClear;
+ NPMMsg(GetKVers);
if not OpenDialogExecute('Select 2 images)',true,true,kImgFilter) then begin
- showmessage('NPM aborted: file selection failed.');
+ ShowMsg('NPM aborted: file selection failed.');
exit;
end; //if not selected
lG:= TStringList.Create;
lG.addstrings(OpenHdrDlg.Files);
if lG.count <> 2 then begin
- showmessage('You must select exactly two image.');
+ ShowMsg('You must select exactly two image.');
goto 666;
end;
- lMaskname := lG[0];
- if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- showmessage('Error reading mask.');
- goto 666;
- end;
- lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
- if not CheckVoxelsGroupX(lG,lMaskHdr{lMaskVoxels}) then begin
- showmessage('File dimensions differ from mask.');
- goto 666;
- end;
- Msg('Voxels = '+inttostr(lMaskVoxels));
- MakeMean(lG,lMaskHdr, odd((Sender as TMenuItem).tag),true);
+ if not SaveHdrName ('Output image', lOutName) then exit;
+ MakeMean(lG, odd((Sender as TMenuItem).tag),true,loutname);
666:
lG.Free;
end;
-procedure BMX;
-const
- kN = 53;
- knNoLesion = 48;
- kSymptomRA: array[1..kn] of single =
-(4,4.5,2.5,5,4,3.25,0.75,4.5,4.5,0.5,1.625,0,3.5,3,4,2,4.5,5,1.5,5,2.5,5,4,0,2,
-1.5,1.75,2.5,5,0,3.25,4.375,0,3.75,0.25,0,2,5,0,0.5,0,2.25,0,2.25,2,0,0.25,0,0,0,0,0,0);
-var
- lObs: doublep0;
- lI: integer;
- lBMz,lBMzs,lDF: double;
-
-begin
- getmem(lObs,kN * sizeof(double));
- for lI := 1 to kN do
- lObs^[lI-1] := kSymptomRA[lI];
-
- tBM (kN, knNoLesion, lObs,lBMz,lDF);
- //simulate
- MainForm.NPMmsg('Generating BM permutation thresholds');
- MainForm.Refresh;
- genBMsim (kN, lObs);
-
- lBMzs := BMzVal (kN, knNoLesion,lBMz,lDF);
- //end simulate
- MainForm.NPMmsg('BMsim= '+floattostr(lBMzs)+' '+'BM= '+floattostr(lBMz)+' '+floattostr(lDF) );
- freemem(lObs);
-end;
-
-(*procedure SX;
-var
- lVALFilename {,lTemplateName}: string;
- lCritPct,lnSubj, lnFactors: integer;
- var lSymptomRA: singleP;
- var lImageNames: TStrings;
- var lCrit: integer; {lBinomial : boolean;}
- var lPredictorList: TStringList;
-
-begin
- lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
- lVALFilename := 'c:\RT_norm.val';//MainForm.OpenHdrDlg.Filename;
- lPredictorList := TStringList.Create;
- GetValCore ( lVALFilename, lnSubj, lnFactors, lSymptomRA, lImageNames, lCrit,lCritPct{,binom},lPredictorList);
- lImageNames.Free;
- lPredictorList.Free;
-end;*)
-
-(*procedure ComputeR;
-var
- lStr: string;
- lT,lDF: double;
-begin
- inputquery('Enter value','Enter T score',lStr);
- lT := strtofloat(lStr);
- inputquery('Enter value','Enter DF',lStr);
- lDF := strtofloat(lStr);
- showmessage('The coresponding correlation Z score for t('+floattostr(lDF)+')='+floattostr(lT) +' is '+floattostr(TtoZ(lT,lDF) ) );
- //showmessage('The coresponding correlation R score for t('+floattostr(lDF)+')='+floattostr(lT) +' is '+floattostr(TtoR(lT,lDF) ) );
-end;
-
-function Log10x (lLogP: double): double;
-begin
- result := -Log10(lLogP);
- fx(result);
-end;
-
-
-procedure LogPtoZ (lLogP: double);
-var
- lD,lZ: double;
-begin
- ///lD := Log10(lLogp);
- lD := Power(10,-lLogP);
- lZ := pNormalInv(lD);
- fx(lD,lZ);
-end; *)
-
procedure TMainForm.About1Click(Sender: TObject);
begin
-//Masked1Click(nil); exit;
-//LogPtoZ (Log10x(0.02));
- //LogPtoZ(1.699);
- //ComputeR;
- showmessage(GetkVers );
+ ShowMsg(GetkVers );
end;
procedure TMainForm.Design1Click(Sender: TObject);
begin
-{$IFDEF SPREADSHEET} SpreadForm.Show; {$ELSE} Showmessage('Spreadsheet not yet supported on the Operating System');{$ENDIF}
-end;
-
-procedure TMainForm.StrToMemo(lStr: String);
-var
- lLen,lPos: integer;
- lOutStr: string;
-begin
- lLen := length(lStr);
- if lLen < 1 then exit;
- lOutStr := '';
- for lPos := 1 to lLen do begin
- if lStr[lPos] = kCR then begin
- Msg(lOutStr);
- lOutStr := '';
- end else
- lOutStr := lOutStr + lStr[lPos];
- end;
- if lOutStr <> '' then
- Msg(lOutStr);
-end;
-
-
-procedure TMainForm.PhysiologicalArtifactCorrection1Click(Sender: TObject);
-var
- lInImgName,lPulsFile,lRespFile,lOutImgName,lStr: string;
- l4Ddata: singlep;
- lHdr: TMRIcroHdr;
- lDim,lImgVox: integer;
- lOutHdr: TniftiHdr;
-begin
- if not OpenDialogExecute('Select file with pulse onsets',false,false,'Siemens physio |*.puls|3-column text |*.txt') then
- exit;
- lPulsFile := OpenHdrDlg.Filename;
- if UpCaseExt(lPulsFile) = '.PULS' then
- lRespFile := changefileext(lPulsFile,'.resp')
- else begin //text input
- if not OpenDialogExecute('Select file with respiration onsets',false,false,'3-column text |*.txt') then
- lRespFile := ''
- else
- lRespFile := OpenHdrDlg.Filename;
- end;
- if not OpenDialogExecute('Select 4D motion corrected data ',false,false,kImgFilter) then
- exit;
- lInImgName := OpenHdrDlg.Filename;
- if not NIFTIhdr_LoadHdr(lInImgName,lHdr) then begin
- showmessage('Error reading image header.');
- exit;
- end;
- for lDim := 1 to 4 do
- if lHdr.NIFTIhdr.Dim[lDim] < 4 then begin
- Showmessage('You need to select a 4D image with at least 4 voxels/images in each dimension.');
- exit;
- end;
- lImgVox := lHdr.NIFTIhdr.Dim[1]*lHdr.NIFTIhdr.Dim[2]*lHdr.NIFTIhdr.Dim[3];
- lDim := lImgVox*lHdr.NIFTIhdr.Dim[4];
- MsgClear;
- Msg(kVers);
- Msg('Physiological Artifact Removal Tool started = ' +TimeToStr(Now));
- Msg('Assuming continuous fMRI ascending acquisition with TR = '+realtostr(lHdr.NIFTIhdr.PixDim[4],4)+'sec');
- MainForm.refresh;
- getmem(l4Ddata,lDim*sizeof(single));
- if not LoadImg(lHdr.ImgFileName, l4Ddata, 1, lDim,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lImgVox) then begin
- Showmessage('Unable to load data');
- freemem(l4Ddata);
- exit;
- end;
- lStr := ApplyPART( lPulsFile,l4Ddata,40, lImgVox,lHdr.NIFTIhdr.Dim[3], lHdr.NIFTIhdr.Dim[4], lHdr.NIFTIhdr.PixDim[4]);
- if lStr = '' then begin
- Showmessage('Unable to apply physio file. Physiological correction is being aborted.');
- exit;
- end;
- StrToMemo (lStr);
- if (lRespFile <> '') and (fileexists(lRespFile)) then begin
- lStr := ApplyPART( lRespFile,l4Ddata,20, lImgVox,lHdr.NIFTIhdr.Dim[3], lHdr.NIFTIhdr.Dim[4], lHdr.NIFTIhdr.PixDim[4]);
- StrToMemo (lStr);
- if lStr = '' then begin
- Showmessage('Unable to read Respiration file. Hysiological correction is being aborted.');
- exit;
- end;
-
- end;
-
- MakeHdr (lHdr.NIFTIhdr,lOutHdr);
- Msg('Input = ' +lInImgName);
- lOutImgName := ChangeFilePrefixExt(lInImgName,'i','.hdr');
- NIFTIhdr_SaveHdrImg(lOutImgName,lOutHdr,true,not IsNifTiMagic(lHdr.NIFTIhdr),true,l4Ddata,lHdr.NIFTIhdr.Dim[4]);
- Msg('Output = ' +lOutImgName);
- Msg('Physiological Artifact Removal Tool finished = ' +TimeToStr(Now));
- lOutImgName := ChangeFilePostfixExt(lOutImgName,'Notes','.txt');
- MsgSave(lOutImgName);
- freemem(l4Ddata);
-end;
-
-function ChangeName (lInName: string): string;
-var
- lPath,lName,lExt: string;
-begin
- //lInName:= 'c:\vbm\ds\123';
- FilenameParts (lInName, lPath,lName,lExt);
- //showmessage(lPath+'*'+lName+'*'+lExt);
- if length(lName) > 0 then
- lName[1] := 'e'
- else
- lName := 'Unable to convert '+lInName;
- result := lPath+lName+lExt;
-end;
-
-function Add2ndScans(var lImageNames: TStrings): boolean;
-var
- lnSubj,lSubj: integer;
- lFilename: string;
-begin
- result := false;
- lnSubj :=lImageNames.Count;
- if lnSubj < 1 then
- exit;
- for lSubj := 1 to lnSubj do begin
- lFilename := ChangeName(lImageNames[lSubj-1]);
- if not (fileexists4D(lFilename)) then begin
- showmessage('Unable to find a file named '+ lFilename);
- exit;
- end;
- lImageNames.add(lFilename);
- end;
- result := true;
-end;
-
-function ReadPairedFilenames(var lImageNames: TStrings): boolean;
-var
- lLen,lPos: integer;
- lFilenames,lF1,lF2: string;
- lImageNames2: TStrings;
- lF: TextFile;
-begin
- result := false;
- Showmessage('Please select a text file with the image names. '+kCR+
- 'Each line of the file should specify the control and experimental filenames, separated by an *'+kCR+
- 'C:\vbmdata\c1.nii.gz*C:\vbmdata\e1.nii.gz'+kCR +
- 'C:\vbmdata\c2.nii.gz*C:\vbmdata\e2.nii.gz'+kCR+
- 'C:\vbmdata\c3.nii.gz*C:\vbmdata\e3.nii.gz'+kCR+
- '...' );
- if not MainForm.OpenDialogExecute('Select asterix separated filenames ',false,false,kTxtFilter) then
- exit;
- lImageNames2:= TStringList.Create; //not sure why TStrings.Create does not work???
- //xxx
- assignfile(lF,MainForm.OpenHdrDlg.FileName );
- FileMode := 0; //read only
- reset(lF);
- while not EOF(lF) do begin
- readln(lF,lFilenames);
- lLen := length(lFilenames);
-
- if lLen > 0 then begin
- lF1:= '';
- lF2 := '';
- lPos := 1;
- while (lPos <= lLen) and (lFilenames[lPos] <> '*') do begin
- lF1 := lF1 + lFilenames[lPos];
- inc(lPos);
- end;
- inc(lPos);
- while (lPos <= lLen) do begin
- lF2 := lF2 + lFilenames[lPos];
- inc(lPos);
- end;
- if (length(lF1) > 0) and (length(lF2)>0) then begin
- if Fileexists4D(lF1) then begin
- if Fileexists4D(lF2) then begin
- lImageNames.add(lF1);
- lImageNames2.add(lF2);
- end else //F2exists
- showmessage('Can not find image '+lF2);
- end else //F1 exists
- showmessage('Can not find image '+lF1);
- end;
- end;//len>0
- end; //while not EOF
- closefile(lF);
- FileMode := 2; //read/write
- if (lImageNames.count > 0) and (lImageNames2.count = lImageNames.count) then begin
- lImageNames.AddStrings(lImageNames2);
-
- result := true;
- end;
- lImageNames2.Free;
+{$IFDEF SPREADSHEET} SpreadForm.Show; {$ELSE} ShowMsg('Spreadsheet not yet supported on the Operating System');{$ENDIF}
end;
function AddNumStr(var X : PMatrix; var lNumStr: string; lRow,lCol: integer):boolean;
@@ -2406,7 +595,7 @@ begin
lTempFloat := strtofloat(lNumStr);
except
on EConvertError do begin
- showmessage('Empty cells? Error reading TXT file row:'+inttostr(lRow)+' col:'+inttostr(lCol)+' - Unable to convert the string '+lNumStr+' to a number');
+ ShowMsg('Empty cells? Error reading TXT file row:'+inttostr(lRow)+' col:'+inttostr(lCol)+' - Unable to convert the string '+lNumStr+' to a number');
exit;
end;
end;
@@ -2416,7 +605,6 @@ begin
result := true;
end;
-{$DEFINE notRTEST}
function ReadPairedFilenamesReg(var lImageNames: TStrings; var X : PMatrix; var lnAdditionalFactors: integer): boolean;
var
lLen,lPos,lSep,lMaxSep,lLine: integer;
@@ -2425,10 +613,8 @@ var
lF: TextFile;
begin
result := false;
- {$IFDEF RTEST}
- MainForm.OpenHdrDlg.FileName := 'c:\twins\dataplus.txt';
- {$ELSE}
- Showmessage('Please select a text file with the image names. '+kCR+
+
+ ShowMsg('Please select a text file with the image names. '+kCR+
'Each line of the file should specify the control and experimental filenames, separated by an *'+kCR+
'C:\vbmdata\c1.nii.gz*C:\vbmdata\e1.nii.gz'+kCR +
'C:\vbmdata\c2.nii.gz*C:\vbmdata\e2.nii.gz'+kCR+
@@ -2436,8 +622,6 @@ begin
'...' );
if not MainForm.OpenDialogExecute('Select asterix separated filenames ',false,false,kTxtFilter) then
exit;
- {$ENDIF}
-
lImageNames2:= TStringList.Create; //not sure why TStrings.Create does not work???
//xxx
assignfile(lF,MainForm.OpenHdrDlg.FileName );
@@ -2466,9 +650,9 @@ begin
lImageNames.add(lF1);
lImageNames2.add(lF2);
end else //F2exists
- showmessage('Can not find image '+lF2);
+ ShowMsg('Can not find image '+lF2);
end else //F1 exists
- showmessage('Can not find image '+lF1);
+ ShowMsg('Can not find image '+lF1);
end;
end;//len>0
end; //while not EOF
@@ -2512,7 +696,7 @@ begin
inc(lSep);
end else if (lSep >= 2) and (not (lFilenames[lPos] in [#10,#13,#9]) ) then begin
lNumStr := lNumStr+lFilenames[lPos];
- //showmessage(lNumStr);
+ //ShowMsg(lNumStr);
end;
inc(lPos);
end; //while not EOLN
@@ -2521,8 +705,6 @@ begin
end; //while not EOF
//next - read final line of unterminated string...
end;//maxsepa > 1
-
-
//2nd pass vals
closefile(lF);
FileMode := 2; //read/write
@@ -2546,27 +728,23 @@ var
lMaskHdr: TMRIcroHdr;
begin
lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
- MsgClear;
- Msg(kVers);
- {$IFDEF RTEST}
- OpenHdrDlg.FileName := 'c:\twins\aameanMean.hdr';
- {$ELSE}
- Msg('Dual-image Linear Regression [Weighted Least Squares]');
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+
+ NPMMsg('Dual-image Linear Regression [Weighted Least Squares]');
if not OpenDialogExecute('Select brain mask ',false,false,kImgFilter) then begin
- showmessage('NPM aborted: mask selection failed.');
+ ShowMsg('NPM aborted: mask selection failed.');
goto 666;
end; //if not selected
- {$ENDIF}
-
lMaskname := OpenHdrDlg.Filename;
if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- showmessage('Error reading Mask image.');
+ ShowMsg('Error reading Mask image.');
goto 666;
end;
lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
- showmessage('Mask file size too small.');
+ ShowMsg('Mask file size too small.');
goto 666;
end;
if not ReadPairedFilenamesReg(lImageNames,X,lnAdditionalFactors) then exit;
@@ -2575,7 +753,7 @@ begin
//fx(lnAdditionalFactors);
//show matrix
//MsgStrings (lImageNames);
- Msg ('n Subjects = '+inttostr(lnSubj));
+ NPMMsg ('n Subjects = '+inttostr(lnSubj));
for lSubj := 0 to (lnSubj-1) do begin
lStr := lImageNames[lSubj]+' <-> '+lImageNames[lSubj+lnSubj];
if lnAdditionalFactors > 0 then
@@ -2583,30 +761,26 @@ begin
lStr := lStr+','+floattostr(X^[lI]^[lSubj+1]);
- Msg(lStr);
+ NPMMsg(lStr);
end;
if not CheckVoxelsGroupX(lImageNames,lMaskHdr{lMaskVoxels}) then begin
- showmessage('File dimensions differ from mask.');
+ ShowMsg('File dimensions differ from mask.');
goto 666;
end;
- Msg('Mask = '+lMaskname);
- Msg('Total voxels = '+inttostr(lMaskVoxels));
- Msg('Number of observations = '+inttostr(lnSubj));
- (*if not CheckVoxelsGroupX(lImageNames,lMaskHdr{lMaskVoxels}) then begin
- showmessage('File dimensions differ from mask.');
- goto 666;
- end;*)
+ NPMMsg('Mask = '+lMaskname);
+ NPMMsg('Total voxels = '+inttostr(lMaskVoxels));
+ NPMMsg('Number of observations = '+inttostr(lnSubj));
if lnSubj < 5 then begin
- showmessage('Paired regression error: Requires at least 5 images per group.');
+ ShowMsg('Paired regression error: Requires at least 5 images per group.');
goto 666;
end;
lOutName := lMaskName;
if not SaveHdrName ('Base Statistical Map', lOutName) then exit;
- //showmessage('Unimplemented Regress');//
- Regress2NPMAnalyze (lImageNames, lMaskHdr, lOutname,X,lnAdditionalFactors);
+ //ShowMsg('Unimplemented Regress');//
+ Regress2NPMAnalyze (lImageNames, lMaskHdr, lOutname,X,lnAdditionalFactors,gNPMprefs.nPermute);
if lnAdditionalFactors > 1 then
DelMatrix(X, lnAdditionalFactors, lnSubj);
666:
@@ -2619,7 +793,7 @@ procedure TMainForm.LesionBtnClick(Sender: TObject);
var
lPrefs: TLDMPrefs ;
begin
- lPrefs.NULP := gNULP;
+ lPrefs.NULP := gNPMPrefs.NULP;
if (1= (Sender as tMenuItem).tag) then begin //continuous
lPrefs.BMtest := BMmenu.checked;
lPrefs.Ttest := ttestmenu.checked;
@@ -2635,11 +809,11 @@ begin
lPrefs.nPermute := ReadPermute;
lPrefs.Run := 0;{0 except for montecarlo}
{if (not lPrefs.Ltest) and (not lPrefs.Ttest) and (not lPrefs.BMtest) then begin
- Showmessage('Error: you need to compute at least on test [options/test menu]');
+ ShowMsg('Error: you need to compute at least on test [options/test menu]');
exit;
end; code above defaults to t-test}
if not MainForm.OpenDialogExecute('Select MRIcron VAL file',false,false,'MRIcron VAL (*.val)|*.val') then begin
- showmessage('NPM aborted: VAL file selection failed.');
+ ShowMsg('NPM aborted: VAL file selection failed.');
exit;
end; //if not selected
lPrefs.VALFilename := MainForm.OpenHdrDlg.Filename;
@@ -2653,38 +827,199 @@ begin
else
lPrefs.ExplicitMaskName := OpenHdrDlg.FileName;
- DoLesion (lPrefs); //Prefs.pas
+ DoLesion (lPrefs); //Prefs.pas
+end;
+
+function HasOption(const S: string):Boolean;
+var
+ i: integer;
+begin
+ result := false;
+ if (ParamCount < 1) then exit;
+ for i := 1 to ParamCount do
+ if ParamStr(i) = ('-'+S) then result := true;
+end;
+
+procedure msg (s: string);
+begin
+ writeln(s);
+end;
+
+procedure ShowOptions (lTestInt: integer; lMaskFilename,lOutFilename: string);
+begin
+ msg(' -c : CPU threads, Default : '+inttostr(gnCPUThreads));
+ msg(' -m : mask name. Default "' +lMaskFilename+'"');
+ msg(' -n : neighbors for TFCE, 0 for none. Default ' +inttostr(gNPMprefs.TFCE));
+ msg(' -o : output name. Default "' +lOutFilename+'"');
+ msg(' -p : Permutations, 0 for none. Default '+inttostr(gNPMprefs.nPermute));
+ msg(' -r : RAM for processing (Mb). Default '+inttostr(gNPMPrefs.PlankMB));
+ msg(' -t : test (0=continuous,1=binomial,2=regress,3=multiregress). Default '+inttostr(lTestInt));
+
+end;
+
+procedure WriteHelp ;
+begin
+ msg(GetKVers);
+ msg(' usage: '+ExtractFileName(ParseFileName(paramstr(0)))+' [options] [-t test] [valfilename]' );
+ msg('Examples:');
+ msg(' '+ ExtractFileName(ParseFileName(paramstr(0)))+' -t 0 test.val');
+ msg(' '+ ExtractFileName(ParseFileName(paramstr(0)))+' -r 1024 -p 1000 -m mymask.nii -t 0 test.val');
+ msg('Options:');
+ msg(' -h : Help displayed');
+end;
+
+function GetOptionValue(const S: string):string;
+var
+ i: integer;
+begin
+ result := '';
+ if (ParamCount < 2) then exit;
+ for i := 1 to (ParamCount-1) do
+ if ParamStr(i) = ('-'+S) then begin
+ result := ParamStr(i+1);
+ exit;
+
+ end;
+end;
+
+function GetOptionValueInt(lCmd: string; lDefault: integer): integer;
+var
+ lResp : string;
+begin
+ lResp := GetOptionValue(lCmd);
+ if length(lResp) < 1 then result := lDefault;
+ try
+ result := strtoint(lResp);
+ except
+ Writeln('Error '+(lResp)+' is not a valid integer.');
+ result := lDefault;
+ end;
+end;
+
+procedure doVLSM(lBinomial: boolean; VALFilename, lMaskFilename,lOutFilename: string);
+ var
+ lPrefs: TLDMPrefs ;
+begin
+ lPrefs.NULP := gNPMPrefs.NULP;
+ if (not lBinomial) then begin //continuous
+ lPrefs.BMtest := true;
+ lPrefs.Ttest := true;
+ lPrefs.Ltest:= false;
+ end else begin //binomial
+ lPrefs.BMtest := false;
+ lPrefs.Ttest := false;
+ lPrefs.Ltest:= true;
+ end;
+ lPrefs.CritPct := -1;
+ lPrefs.nPermute := gNPMprefs.nPermute;
+ lPrefs.Run := 0;{0 except for montecarlo}
+ lPrefs.VALFilename := VALFilename;
+ lPrefs.OutName := lOutFilename;
+ lPrefs.ExplicitMaskName := lMaskFilename;
+ DoLesion (lPrefs);
+end;
+
+procedure TMainForm.ProcessParamStr;
+label
+ 666;
+var
+ lTestInt: integer;
+ lMaskFilename : string;
+ lValFilename : string;
+ lOutFilename : string;
+begin
+ lTestInt := 0;
+ lMaskFilename := '';
+ lValFilename := '';
+ lOutFilename := '';
+ gnCPUThreads := GetLogicalCpuCount;
+ ReadIniFile;
+ // parse parameters
+ if (HasOption('h')) or (ParamCount = 0) then begin
+ WriteHelp;
+ ShowOptions(lTestInt, lMaskFilename, lOutFilename);
+ goto 666;
+ end;
+ if (HasOption('c')) then gnCPUThreads := GetOptionValueInt('c', gnCPUThreads);
+ if (HasOption('m')) then begin
+ lMaskFilename := GetOptionValue('m');
+ if (not FileExistsEX(lMaskFilename)) then begin
+ WriteHelp ;
+ writeln('Can not find masking image '+ lMaskFilename);
+
+ ShowOptions(lTestInt,lMaskFilename,lOutFilename);
+ goto 666;
+ end;
+ end;
+ if (HasOption('n')) then gnCPUThreads := GetOptionValueInt('n', gNPMprefs.TFCE);
+ if (HasOption('o')) then begin
+ lOutFilename := GetOptionValue('o');
+ end;
+ if (HasOption('p')) then gNPMprefs.nPermute := GetOptionValueInt('p', gNPMprefs.nPermute);
+ if (HasOption('r')) then begin
+ gNPMPrefs.PlankMB := GetOptionValueInt('r', gNPMPrefs.PlankMB);
+ ComputePlankSize(gNPMPrefs.PlankMB);
+ end;
+ if (HasOption('t')) then lTestInt := GetOptionValueInt('t', lTestInt);
+
+
+ lValFilename := (paramstr(ParamCount));
+ if (UpCaseExt(lValFilename) <> '.VAL') or (not FileExistsEX(lValFilename)) then begin
+ Writeln('Error: final option should be an existing file with the .val extension');
+ WriteHelp ;
+ ShowOptions(lTestInt,lMaskFilename,lOutFilename);
+ goto 666;
+ end;
+
+ if (lOutFilename = '') then begin
+ lOutFilename := ChangeFileExtX( lValFilename,'res.nii');
+ end;
+ //show settings
+ ShowOptions(lTestInt,lMaskFilename,lOutFilename);
+ Writeln('VAL File: '+lValFilename);
+ if (lTestInt > 1) and (lMaskFilename = '') then begin
+ Writeln('Error: this test require you to specify a mask image');
+ goto 666;
+ end;
+ //run test
+ Application.ProcessMessages;
+ case lTestInt of
+ 0: doVLSM(false, lVALFilename, lMaskFilename,lOutFilename);//continuous : t-test
+ 1: doVLSM(true, lVALFilename, lMaskFilename,lOutFilename);//binomial: Liebermeister
+ 2: NPMSingleRegress ( lVALFilename, lMaskFilename,lOutFilename);
+ 3: NPMMultipleRegressClick( lVALFilename, lMaskFilename,lOutFilename);
+
+ end;
+ (*repeat
+ Sleep(1000);
+ Writeln('waiting');
+ until gThreadsRunning = 0; *)
+ Writeln('Goodbye');
+ Application.ProcessMessages;
+
+
+ //WriteIniFile;
+ // stop program loop
+ 666:
+ Close;
end;
+
procedure TMainForm.FormShow(Sender: TObject);
begin
- MsgClear;
- Msg(GetkVers);
+ NPMMsgClear;
+ NPMMsg(GetkVers);
{$IFNDEF UNIX} {GUILaunch;}{$ENDIF}
LongTimeFormat := 'YYYY-MMM-DD hh:nn:ss'; //delphi TimeToStr
ShortTimeFormat := 'YYYY-MMM-DD hh:nn:ss'; //freepascal TimeToStr
- //stax;
- //MakeGZ;
- //{x$IFNDEF UNIX} Threads1.visible := false;{x$ENDIF}//Windows can read actual CPU count
- //TestMultReg;
- //SingleRegressClick(nil);
- //DualImageCorrelation1Click(nil);
- //AnaCOM1Click(nil);
- //msg(floattostr(pNormalInv(1/20000)));
- //msg(floattostr(pNormalInv(0.01667)));
- //msg(floattostr(pNormalInv(0.05/51700)));
- //msg(floattostr(0.05/pNormal(4.76 )));
- {$IFNDEF UNIX} ReadParamStr; {$ENDIF}
- //FX(rocA(0.2,0.4),AUC(0.7,0.4),rocA(0.4,0.7),AUC(0.4,0.7) );
- //LesionX;
+ {$IFDEF FPC}{$IFNDEF UNIX} ReadParamStr; {$ENDIF} {$ENDIF}
{$IFDEF benchmark}
MonteCarloSimulation1.visible := true;
- // LesionMonteCarlo (false,true,true);
{$ENDIF}
+ StartTimer.enabled := true;
end;
-
procedure TMainForm.PairedTMenuClick(Sender: TObject);
label
666;
@@ -2695,133 +1030,60 @@ var
lMaskHdr: TMRIcroHdr;
begin
lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
- MsgClear;
- Msg(kVers);
- Msg('Paired T-test [Repeated Measures]');
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ NPMMsg('Paired T-test [Repeated Measures]');
if not OpenDialogExecute('Select brain mask ',false,false,kImgFilter) then begin
- showmessage('NPM aborted: mask selection failed.');
+ ShowMsg('NPM aborted: mask selection failed.');
goto 666;
end; //if not selected
//OpenHdrDlg.FileName := 'c:\vbmdata\mask50.nii.gz';
lMaskname := OpenHdrDlg.Filename;
if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- showmessage('Error reading Mask image.');
+ ShowMsg('Error reading Mask image.');
goto 666;
end;
lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
- showmessage('Mask file size too small.');
+ ShowMsg('Mask file size too small.');
goto 666;
end;
if not ReadPairedFilenames(lImageNames) then exit;
lnSubj :=lImageNames.Count div 2;
if not CheckVoxelsGroupX(lImageNames,lMaskHdr{lMaskVoxels}) then begin
- showmessage('File dimensions differ from mask.');
+ ShowMsg('File dimensions differ from mask.');
goto 666;
end;
-
-
- Msg('Mask = '+lMaskname);
- Msg('Total voxels = '+inttostr(lMaskVoxels));
- Msg('Number of observations = '+inttostr(lnSubj));
- Msg('Degrees of Freedom = '+inttostr(lnSubj-1));
+ NPMMsg('Mask = '+lMaskname);
+ NPMMsg('Total voxels = '+inttostr(lMaskVoxels));
+ NPMMsg('Number of observations = '+inttostr(lnSubj));
+ NPMMsg('Degrees of Freedom = '+inttostr(lnSubj-1));
if not CheckVoxelsGroupX(lImageNames,lMaskHdr{lMaskVoxels}) then begin
- showmessage('File dimensions differ from mask.');
+ ShowMsg('File dimensions differ from mask.');
goto 666;
end;
//show matrix
//MsgStrings (lImageNames);
- Msg ('n Subjects = '+inttostr(lnSubj));
+ NPMMsg ('n Subjects = '+inttostr(lnSubj));
lStr := 'Image,';
for lSubj := 0 to (lnSubj-1) do
- Msg(lImageNames[lSubj]+' <-> '+lImageNames[lSubj+lnSubj]);
+ NPMMsg(lImageNames[lSubj]+' <-> '+lImageNames[lSubj+lnSubj]);
if lnSubj < 4 then begin
- showmessage('Paired t-test error: Requires at least 4 images per group.');
+ ShowMsg('Paired t-test error: Requires at least 4 images per group.');
goto 666;
end;
lOutName := lMaskName;
+ if not SaveHdrName ('Statistical Map', lOutName) then exit;
//if not SaveHdrName ('Base Statistical Map', lOutName) then exit;
- NPMAnalyzePaired (lImageNames, lMaskHdr, lMaskVoxels);
+ NPMAnalyzePaired (lImageNames, lMaskHdr, lMaskVoxels,lOutName);
//Regress2NPMAnalyze (lImageNames, lMaskHdr, lOutname);
666:
lImageNames.Free;
end;
-function TMainForm.NPMzscore (var lImages: TStrings; var lMnHdr,lStDevHdr: TMRIcroHdr): boolean;
-label
- 667;
-var
- lOutNameMod: string;
- lMnImg,lStDevImg,lSubjImg,lOutImg: SingleP;
- lVal: single;
- lSubj,lPos,lVolVox: integer;
- lStatHdr: TNIfTIhdr;
-begin
- result := false;
- //lOutName := lMnHdr.ImgFileName;
- //if not SaveHdrName ('Statistical Map', lOutName) then exit;
- Msg('Analysis began = ' +TimeToStr(Now));
- lVolVox := lMnHdr.NIFTIhdr.dim[1]*lMnHdr.NIFTIhdr.dim[2]* lMnHdr.NIFTIhdr.dim[3];
- if (lVolVox < 1) then goto 667;
- //load mask
- for lPos := 0 to lImages.Count do
- if gScaleRA[lPos] = 0 then
- gScaleRA[lPos] := 1;
- if gScaleRA[kMaxImages] = 0 then
- gScaleRA[kMaxImages] := 1;
-
- getmem(lMnImg,lVolVox*sizeof(single));
- if not LoadImg(lMnHdr.ImgFileName, lMnImg, 1, lVolVox,round(gOffsetRA[0]),1,lMnHdr.NIFTIhdr.datatype,lVolVox) then begin
- Msg('Unable to load mean ' +lMnHdr.ImgFileName);
- goto 667;
- end;
- //load StDev
- getmem(lStDevImg,lVolVox*sizeof(single));
- if not LoadImg(lStDevHdr.ImgFileName, lStDevImg, 1, lVolVox,round(gOffsetRA[kMaxImages]),1,lStDevHdr.NIFTIhdr.datatype,lVolVox) then begin
- Msg('Unable to load StDev ' +lStDevHdr.ImgFileName);
- goto 667;
- end;
- getmem(lOutImg,lVolVox* sizeof(single));
- for lPos := 1 to lVolVox do begin
- lMnImg^[lPos] := (gScaleRA[0]*lMnImg^[lPos])+gInterceptRA[0];
- lStDevImg^[lPos] := (gScaleRA[kMaxImages]*lStDevImg^[lPos])+gInterceptRA[kMaxImages];
- if lStDevImg^[lPos] = 0 then
- lOutImg^[lPos] := 0;
- end;
- getmem(lSubjImg,lVolVox* sizeof(single));
- for lSubj := 1 to lImages.Count do begin
- ProgressBar1.Position := round((lSubj/lImages.Count)*100);
- Msg( lImages.Strings[lSubj-1]);
- showmessage(inttostr(round(gOffsetRA[lSubj])));
- LoadImg(lImages.Strings[lSubj-1], lSubjImg, 1, lVolVox,round(gOffsetRA[lSubj]),1,gDataTypeRA[lSubj],lVolVox);
- for lPos := 1 to lVolVox do begin
- if lStDevImg^[lPos] <> 0 then begin
- lVal := (gScaleRA[lSubj]*lSubjImg^[lPos])+gInterceptRA[lSubj];
- lOutImg^[lPos] := (lVal-lMnImg^[lPos])/lStDevImg^[lPos];
- end; //for each voxel with variance
- end; //for each voxel
- lOutNameMod := ChangeFilePostfixExt(lImages.Strings[lSubj-1],'Z','.hdr');
- MakeStatHdr (lMnHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lVolVox,kNIFTI_INTENT_ZSCORE,inttostr(lVolVox) );
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMnHdr.NIFTIhdr),true,lOutImg,1);
- end; //for each subj
- freemem(lSubjImg);
- freemem(lOutImg);
- freemem(lMnImg);
- freemem(lStDevImg);
- Msg('Analysis finished = ' +TimeToStr(Now));
- ProgressBar1.Position := 0;
- result := true;
- exit;
-667: //you only get here if you aborted ... free memory and report error
- if lVolVox > 1 then freemem(lMnImg);
- Msg('Unable to complete analysis.');
- ProgressBar1.Position := 0;
-end;
-
-
procedure TMainForm.SingleSubjectZScores1Click(Sender: TObject);
label
666;
@@ -2832,29 +1094,29 @@ var
lMnHdr,lStDevHdr: TMRIcroHdr;
begin
if (not ttestmenu.checked) and (not BMmenu.checked) then begin
- Showmessage('Error: you need to compute at least on test [options/test menu]');
+ ShowMsg('Error: you need to compute at least on test [options/test menu]');
exit;
end;
- MsgClear;
- Msg(kVers);
- Msg('Threads: '+inttostr(gnCPUThreads));
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ NPMMsg('Threads: '+inttostr(gnCPUThreads));
if not OpenDialogExecute('Select mean image ',false,false,kImgFilter) then begin
- showmessage('NPM aborted: mean selection failed.');
+ ShowMsg('NPM aborted: mean selection failed.');
exit;
end; //if not selected
lMn := OpenHdrDlg.Filename;
if not NIFTIhdr_LoadHdr(lMn,lMnHdr) then begin
- showmessage('Error reading mask.');
+ ShowMsg('Error reading mask.');
exit;
end;
lMnVoxels := ComputeImageDataBytes8bpp(lMnHdr);
if (lMnVoxels < 2) or (not CheckVoxels(lMn,lMnVoxels,0)){make sure there is uncompressed .img file} then begin
- showmessage('Mean file size too small.');
+ ShowMsg('Mean file size too small.');
exit;
end;
if not OpenDialogExecute('Select StDev image ',false,false,kImgFilter) then begin
- showmessage('NPM aborted: StDev selection failed.');
+ ShowMsg('NPM aborted: StDev selection failed.');
exit;
end; //if not selected
lStDev := OpenHdrDlg.Filename;
@@ -2866,8 +1128,8 @@ begin
showmessage('Error Mean and StDev must have same size.');
exit;
end;
- Msg('Mean name = '+ lMn);
- Msg('Total voxels = '+inttostr(lMnVoxels));
+ NPMMsg('Mean name = '+ lMn);
+ NPMMsg('Total voxels = '+inttostr(lMnVoxels));
//next, get 1st group
if not OpenDialogExecute('Select postive group (Z scores positive if this group is brighter)',true,false,kImgFilter) then begin
showmessage('NPM aborted: file selection failed.');
@@ -2876,186 +1138,53 @@ begin
lG:= TStringList.Create; //not sure why TStrings.Create does not work???
lG.addstrings(OpenHdrDlg.Files);
lnSubj :=OpenHdrDlg.Files.Count;
- Msg('Subjects= '+inttostr(lnSubj));
+ NPMMsg('Subjects= '+inttostr(lnSubj));
if not CheckVoxelsGroupX(lG,lMnHdr {lMnVoxels}) then begin
showmessage('File dimensions differ from mask.');
goto 666;
end;
NPMzscore (lG, lMnHdr,lStDevHdr);
- //NPMAnalyze(lG,lMnHdr,lMnVoxels,lnSubj);
666:
lG.Free;
end;
procedure TMainForm.MultipleRegressClick(Sender: TObject);
-label
- 666;
-var
- lnFactors,lnSubj,lMaskVoxels,lRow,lCol: integer;
- lImageNames: TStrings;
- lPredictorList: TStringList;
- lTemp4D,lMaskname,lStr,lOutName: string;
- lMaskHdr: TMRIcroHdr;
- X : PMatrix;
+var lVALFilename, lMaskname,lOutname: string;
begin
- {$IFDEF FPC}
- showmessage('Regression routines not extensively tested: you may want to use the Windows compilation.');
- {$ENDIF}
- lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
- lPredictorList := TStringList.Create;
- Memo1.Lines.Clear;
- Memo1.Lines.Add(kVers);
- Memo1.Lines.Add('Multiple Linear Regression [Weighted Least Squares]');
- if not GetValReg(lnSubj,lnFactors,X,lImageNames,lPredictorList) then
- goto 666;
- lTemp4D := CreateDecompressed4D(lImageNames);
+ if not MainForm.OpenDialogExecute('Select MRIcron VAL file',false,false,'MRIcron VAL (*.val)|*.val') then begin
+ ShowMsg('NPM aborted: VAL file selection failed.');
+ exit;
+ end; //if not selected
+ lVALFilename := MainForm.OpenHdrDlg.Filename;
if not OpenDialogExecute('Select brain mask ',false,false,kImgFilter) then begin
- showmessage('NPM aborted: mask selection failed.');
- goto 666;
+ showmessage('NPM aborted: mask selection failed.');
+ exit;
end; //if not selected
lMaskname := OpenHdrDlg.Filename;
- //lMaskname := lImageNames[0];
- if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- showmessage('Error reading 1st image.');
- goto 666;
- end;
- lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
- if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
- showmessage('Mask file size too small.');
- goto 666;
- end;
- Memo1.Lines.Add('Mask = '+lMaskname);
- Memo1.Lines.Add('Total voxels = '+inttostr(lMaskVoxels));
- Memo1.Lines.Add('Number of observations = '+inttostr(lnSubj));
- if not CheckVoxelsGroupX(lImageNames,lMaskHdr {lMaskVoxels}) then begin
- showmessage('File dimensions differ from mask.');
- goto 666;
- end;
- //show matrix
- lStr := 'Image,';
- for lCol := 1 to lnFactors do
- lStr := lStr + lPredictorList.Strings[lCol-1]+', ';
- MainForm.Memo1.Lines.Add(lStr);
- for lRow := 1 to lnSubj do begin
- lStr := lImageNames[lRow-1]+',';
- for lCol := 1 to lnFactors do
- lStr := lStr + floattostr(X^[lCol]^[lRow])+', ';
- MainForm.Memo1.Lines.Add(lStr);
- end;
lOutName := lMaskName;
if not SaveHdrName ('Base Statistical Map', lOutName) then exit;
- ARegressNPMAnalyze(lImageNames,lMaskHdr,X,lnFactors,lPredictorList,lOutName);
- DelMatrix(X, lnFactors, lnSubj);
- 666:
- lImageNames.Free;
- lPredictorList.Free;
- DeleteDecompressed4D(lTemp4D);
+ NPMMultipleRegressClick(lVALFilename, lMaskname,lOutname);
end;
-{$DEFINE notRegTest}
procedure TMainForm.SingleRegressClick(Sender: TObject);
-label
- 666;
-var
- lnSubj1,lnFactors,lnSubj,lMaskVoxels,lRow,lCol: integer;
-
- lImageNames,lImageNames1: TStrings;
- lPredictorList,lPredictorList1: TStringList;
- lTemp4D,lMaskname,lOutName: string;
- lMaskHdr: TMRIcroHdr;
- X,X1 : PMatrix;
+var lVALFilename, lMaskname,lOutname: string;
begin
- {$IFDEF FPC}
- showmessage('Regression routines not extensively tested: you may want to use the Windows compilation.');
- {$ENDIF}
- lTemp4D := '';
- lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
- lPredictorList := TStringList.Create;
- lPredictorList1 := TStringList.Create;
- if not GetValReg(lnSubj,lnFactors,X,lImageNames,lPredictorList) then
- goto 666;
- {$IFDEF regtest}
- lMaskname := 'C:\Documents and Settings\Chris Rorden\Desktop\npmdata\npmdata\amask50.nii.gz';
- {$ELSE}
- if not OpenDialogExecute('Select brain mask ',false,false,kImgFilter) then begin
- showmessage('NPM aborted: mask selection failed.');
- goto 666;
- end; //if not selected
+ if not MainForm.OpenDialogExecute('Select MRIcron VAL file',false,false,'MRIcron VAL (*.val)|*.val') then exit;
+ lVALFilename := MainForm.OpenHdrDlg.Filename;
+ if not OpenDialogExecute('Select brain mask ',false,false,kImgFilter) then exit;
lMaskname := OpenHdrDlg.Filename;
- {$ENDIF}
- if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- showmessage('Error reading 1st image.');
- goto 666;
- end;
- lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
- if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
- showmessage('Mask file size too small.');
- goto 666;
- end;
- if not CheckVoxelsGroupX(lImageNames,lMaskHdr{lMaskVoxels}) then begin
- showmessage('File dimensions differ from mask.');
- goto 666;
- end;
- lOutName := lMaskName;
- {$IFNDEF regtest}
-
- if not SaveHdrName ('Base Statistical Map', lOutName) then goto 666;
- {$ENDIF}
- lTemp4D := CreateDecompressed4D(lImageNames);
-
-
- lImageNames1:= TStringList.Create;
- for lCol := 1 to lnFactors do begin
- lPredictorList1.Clear;
- lPredictorList1.Add(lPredictorList[lCol-1]);
- lImageNames1.clear;
- for lRow := 1 to lnSubj do
- if X^[lCol]^[lRow] <> kNaN then
- lImageNames1.Add(lImageNames[lRow-1]);
- DimMatrix(X1, 1, lImageNames1.Count);
- lnSubj1 := 0;
-
- for lRow := 1 to lnSubj do
- if X^[lCol]^[lRow] <> kNaN then begin
- inc(lnSubj1);
- X1^[1]^[lnSubj1] := X^[lCol]^[lRow];
- end;
- if lnSubj1 <> lImageNames1.Count then //should be impossible
- showmessage('serious error');
- Memo1.Lines.Clear;
- Memo1.Lines.Add(kVers);
- Memo1.Lines.Add('Single Linear Regression [Weighted Least Squares]');
- Memo1.Lines.Add('Mask = '+lMaskname);
- Memo1.Lines.Add('Total voxels = '+inttostr(lMaskVoxels));
- Memo1.Lines.Add('Number of observations = '+inttostr(lnSubj1));
-
- MainForm.Memo1.Lines.Add('Image,'+ lPredictorList1.Strings[0]);
- for lRow := 1 to lnSubj1 do
- MainForm.Memo1.Lines.Add(lImageNames1[lRow-1]+','+floattostr(X1^[1]^[lRow]) ) ;
- ARegressNPMAnalyze(lImageNames1,lMaskHdr,X1,1,lPredictorList1,lOutName);
- DelMatrix(X1, 1, lnSubj1);
- end;
- lImageNames1.Free;
- DelMatrix(X, lnFactors, lnSubj);
- 666:
-DeleteDecompressed4D(lTemp4D);
- lImageNames.Free;
- lPredictorList.Free;
- lPredictorList1.Free;
+ NPMSingleRegress (lVALFilename, lMaskname,lOutname);
end;
procedure TMainForm.AssociatevalfileswithNPM1Click(Sender: TObject);
begin
-{$IFDEF FPC}
- //unsupported by FreePascal
-{$ELSE}
+{$IFNDEF FPC}//unsupported by FreePascal
case MessageDlg('NPM installation:'+kCR+'Do you want .val fiels to automatically open NPM when you double click on their icons?', mtConfirmation,
[mbYes, mbNo], 0) of { produce the message dialog box }
id_No: exit;
end;
registerfiletype(kVALNativeExt,'NPM'{key},'NPM',Application.ExeName+',1');
{$ENDIF}
-
end;
procedure TMainForm.threadChange(Sender: TObject);
@@ -3064,7 +1193,7 @@ begin
ReadThread;
end;
-procedure TMainForm.Countlesionoverlaps1Click(Sender: TObject);
+(*procedure TMainForm.Countlesionoverlaps1Click(Sender: TObject);
label
666;
var
@@ -3073,8 +1202,8 @@ var
lMaskname: string;
lMaskHdr: TMRIcroHdr;
begin
- MsgClear;
- Msg(kVers);
+ NPMMsgClear;
+ NPMMsg(GetKVers);
if not OpenDialogExecute('Select images to overlap',true,false,kImgFilter) then begin
showmessage('NPM aborted: file selection failed.');
exit;
@@ -3117,17 +1246,16 @@ begin
lReps := ReadIntForm.GetInt('Enter number of times each increment is tested ', 1,10,100);
lPct := ReadIntForm.GetInt('Only include voxels damaged in N% of patients ', 0,5,100);
- Msg('Voxels = '+inttostr(lMaskVoxels));
- Msg('Scans to permute = '+inttostr(lG.count));
+ NPMMsg('Voxels = '+inttostr(lMaskVoxels));
+ NPMMsg('Scans to permute = '+inttostr(lG.count));
EvaluatePower (lG,lInc,lMax,lReps,lPct);
//MakeMean(lG,lMaskHdr, odd((Sender as TMenuItem).tag),false);
666:
lG.Free;
-end;
+end; *)
+
-{$DEFINE SINGLETHREAD}
-{$DEFINE NOTHREAD}
function TMainForm.FirthNPMAnalyze (var lImages: TStrings; var lPredictorList: TStringList; var lMaskHdr: TMRIcroHdr; lnCond,lnCrit: integer; var lSymptomRA: SingleP; var lOutName: string): boolean;
label
@@ -3154,17 +1282,17 @@ begin
exit;
lnPermute := ReadPermute;
if lnPermute > 1 then begin
- Msg('NPM does not (yet) support permutation thresholding with Logisitic Regression.');
+ NPMMsg('NPM does not (yet) support permutation thresholding with Logisitic Regression.');
lnPermute := 0;
end;
{$IFDEF SINGLETHREAD}
lnCPUThreads := gnCPUThreads;
if gnCPUThreads > 1 then
- Msg('July 2007 logistic regression will only use 1 thread. You may want to check for a software update');
+ NPMMsg('July 2007 logistic regression will only use 1 thread. You may want to check for a software update');
gnCPUThreads := 1;
{$ENDIF}
- Msg('Permutations = ' +IntToStr(lnPermute));
- Msg('Logisitic Regression began = ' +TimeToStr(Now));
+ NPMMsg('Permutations = ' +IntToStr(lnPermute));
+ NPMMsg('Logisitic Regression began = ' +TimeToStr(Now));
lTotalMemory := 0;
lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
if (lVolVox < 1) then goto 667;
@@ -3175,8 +1303,8 @@ begin
lTotalMemory := ((lMaxMask+1)-lMinMask) * lImages.Count;
if (lTotalMemory = 0) then goto 667; //no data
lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
- Msg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
- Msg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
+ NPMMsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
+ NPMMsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
if (lnPlanks = 1) then
getmem(lPlankImg,lTotalMemory)
else
@@ -3201,7 +1329,7 @@ begin
ClearThreadData(gnCPUThreads,lnPermute) ;
for lPlank := 1 to lnPlanks do begin
ProgressBar1.Position := 1;
- Msg('Computing plank = ' +Inttostr(lPlank));
+ NPMMsg('Computing plank = ' +Inttostr(lPlank));
Refresh;
Application.processmessages;
lEndVox := lEndVox + lVoxPerPlank;
@@ -3220,17 +1348,16 @@ begin
lThreadInc := lVoxPerPlank div gnCPUThreads;
lThreadEnd := lThreadInc;
Application.processmessages;
- {$IFDEF NOTHREAD}
+ {$IFDEF FIRTHNOTHREAD}
FirthAnalyzeNoThread (lnCond, lnCrit,lnPermute,1,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,lPlankImg,lOutImgSum,lSymptomRA,lOutImg);
- //FirthAnalyzeNoThread (lnCond,lnCrit, lnPermute,1,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,lPlankImg,lOutImgSum,lSymptomRA,lOutImg);
{$ELSE}
for lThread := 1 to gnCPUThreads do begin
if lThread = gnCPUThreads then
lThreadEnd := lVoxPerPlank; //avoid integer rounding error
- with TFirthThreadStat.Create (ProgressBar1,lnCond,lnCrit, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,lPlankImg,lOutImgSum,lSymptomRA,lOutImg) do
+ with TFirthThreadStat.Create ((lThread = ((gnCPUThreads+1) div 2)),MainForm, ProgressBar1,lnCond,lnCrit, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,lPlankImg,lOutImgSum,lSymptomRA,lOutImg) do
{$IFDEF FPC} OnTerminate := @ThreadDone; {$ELSE}OnTerminate := ThreadDone;{$ENDIF}
inc(gThreadsRunning);
- Msg('Thread ' +Inttostr(gThreadsRunning)+' = '+inttostr(lThreadStart)+'..'+inttostr(lThreadEnd));
+ NPMMsg('Thread ' +Inttostr(gThreadsRunning)+' = '+inttostr(lThreadStart)+'..'+inttostr(lThreadEnd));
lThreadStart := lThreadEnd + 1;
lThreadEnd :=lThreadEnd + lThreadInc;
end; //for each thread
@@ -3246,12 +1373,12 @@ begin
end;
lnVoxTested := SumThreadDataLite(gnCPUThreads); //not yet lnVoxTested := SumThreadData(gnCPUThreads,lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM);
if lnVoxTested < 1 then begin
- Msg('**Error: no voxels tested: no regions lesioned in at least '+inttostr(lnCrit)+' patients**');
+ NPMMsg('**Error: no voxels tested: no regions lesioned in at least '+inttostr(lnCrit)+' patients**');
goto 123;
end;
//next report findings
- Msg('Voxels tested = ' +Inttostr(lnVoxTested));
- Msg('Only tested voxels with more than '+inttostr(lnCrit)+' lesions');
+ NPMMsg('Voxels tested = ' +Inttostr(lnVoxTested));
+ NPMMsg('Only tested voxels with more than '+inttostr(lnCrit)+' lesions');
//Next: save results from permutation thresholding....
reportBonferroni('Std',lnVoxTested);
//next: save data
@@ -3278,9 +1405,9 @@ begin
freemem(lOutImgSum);
freemem(lObsp);
freemem(lPlankImg);
- Msg('Analysis finished = ' +TimeToStr(Now));
+ NPMMsg('Analysis finished = ' +TimeToStr(Now));
lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes','.txt');
- MsgSave(lOutNameMod);
+ NPMMsgSave(lOutNameMod);
ProgressBar1.Position := 0;
{$IFDEF SINGLETHREAD}
@@ -3289,37 +1416,13 @@ begin
exit;
667: //you only get here if you aborted ... free memory and report error
if lTotalMemory > 1 then freemem(lPlankImg);
- Msg('Unable to complete analysis.');
+ NPMMsg('Unable to complete analysis.');
ProgressBar1.Position := 0;
{$IFDEF SINGLETHREAD}
gnCPUThreads := lnCPUThreads;
{$ENDIF}
end;
-
-function ComputeLesionVolume (lImgName: string): integer;
-var
- lHdr: TMRIcroHdr;
- lImg: byteP;
- lVolVox,lVox:integer;
-begin
- result := -1; //error
- NIFTIhdr_LoadHdr(lImgName,lHdr);
- lVolVox := lHdr.NIFTIhdr.dim[1]*lHdr.NIFTIhdr.dim[2]* lHdr.NIFTIhdr.dim[3];
- getmem(lImg,lVolVox*sizeof(byte));
- if not LoadImg8(lImgName, lImg, 1, lVolVox,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lVolVox) then begin
- Msg('Unable to load ' +lHdr.ImgFileName);
- freemem(lImg);
- exit;
- end;
- result := 0;
- for lVox := 1 to lVolVox do
- if (lImg^[lVox] <> 0) then
- inc(result);
- freemem(lImg);
-end;
-
-
procedure TMainForm.PenalizedLogisticRegerssion1Click(Sender: TObject);
label
666;
@@ -3337,11 +1440,12 @@ begin
//next, get 1st group
if not GetValX(lnSubj,lnFactors,lMultiSymptomRA,lImageNames,lnCrit{,binom},lPredictorList) then
goto 666;
- lTemp4D := CreateDecompressed4D(lImageNames);
if (lnSubj < 2) or (lnFactors < 1) then begin
showmessage('This analysis requires at least 2 participants and one factor');
goto 666;
end;
+ WarnIfLowNCrit(lnSubj,lnCrit);
+ lTemp4D := CreateDecompressed4D(lImageNames);
lMaskname := lImageNames[0];
if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
showmessage('Error reading 1st image: '+lMaskname);
@@ -3356,7 +1460,7 @@ begin
[mbYes, mbNo], 0) of { produce the message dialog box }
mrYes: begin
//add a new condition called lesionvolume - create a new larger array for data
- Msg('Computing lesion volumes...');
+ NPMMsg('Computing lesion volumes...');
lPredictorList.Add('LesionVolume');
GetMem(lTempRA,lnSubj*lnFactors*sizeof(single));
for lI := 1 to (lnSubj*lnFactors) do
@@ -3397,27 +1501,27 @@ begin
end;
lOutName := ExtractFileDirWithPathDelim(lMaskName)+'results';
SaveHdrDlg.Filename := loutname;
- MsgClear;
- Msg(kVers);
- Msg('Firth Penalized regression is still beta software...');
- Msg('Number of participants: '+inttostr(lnSubj));
- Msg('Number of factors: '+inttostr(lnFactors));
- Msg('Threads: '+inttostr(gnCPUThreads));
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ NPMMsg('Firth Penalized regression is still beta software...');
+ NPMMsg('Number of participants: '+inttostr(lnSubj));
+ NPMMsg('Number of factors: '+inttostr(lnFactors));
+ NPMMsg('Threads: '+inttostr(gnCPUThreads));
//next - header shows factor names
lStr :='imagename';
for lFact := 1 to lnFactors do
lStr := lStr+','+lPredictorList[lFact-1];
- Msg(lStr);
+ NPMMsg(lStr);
For lSubj := 1 to lnSubj do begin
lStr :='';
for lFact := 1 to lnFactors do begin
lStr := lStr+','+realtostr(lMultiSymptomRA^[lSubj+ ((lFact-1)*lnSubj)],2);
end;
- Msg (lImageNames.Strings[lSubj-1] + ' = '+lStr );
+ NPMMsg (lImageNames.Strings[lSubj-1] + ' = '+lStr );
end;
- Msg('Total voxels = '+inttostr(lMaskVoxels));
- Msg('Only testing voxels damaged in at least '+inttostr(lnCrit)+' individual[s]');
- Msg('Number of Lesion maps = '+inttostr(lnSubj));
+ NPMMsg('Total voxels = '+inttostr(lMaskVoxels));
+ NPMMsg('Only testing voxels damaged in at least '+inttostr(lnCrit)+' individual[s]');
+ NPMMsg('Number of Lesion maps = '+inttostr(lnSubj));
lOutName := lOutName+'.nii.gz';
if not SaveHdrName ('Base Statistical Map', lOutName) then goto 666;
@@ -3432,7 +1536,7 @@ begin
DeleteDecompressed4D(lTemp4D);
end;
-function ComputeIntersection ( lAname,lBname: string; var lUnion,lIntersection,lAnotB,lBnotA: integer): boolean;
+(*function ComputeIntersection ( lAname,lBname: string; var lUnion,lIntersection,lAnotB,lBnotA: integer): boolean;
label 667;
var
lOutName,lOutNameMod: string;
@@ -3456,7 +1560,7 @@ begin
if (lVolVox < 1) then goto 667;
getmem(lImgA,lVolVox*sizeof(single));
if not LoadImg(lAname, lImgA, 1, lVolVox,round(lMaskHdr.NIFTIhdr.vox_offset),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
- msg('Unable to load mask ' +lMaskHdr.ImgFileName);
+ NPMMsg('Unable to load mask ' +lMaskHdr.ImgFileName);
goto 667;
end;
lVolVoxA := lVolVox;
@@ -3465,12 +1569,11 @@ begin
showmessage('Error reading image B - '+lBname);
exit;
end;
- //fx(666,round(gOffsetRA[0]));
lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
if (lVolVoxA <> lVolVox) or (lVolVox < 1) then goto 667;
getmem(lImgB,lVolVox*sizeof(single));
if not LoadImg(lBname, lImgB, 1, lVolVox,round(lMaskHdr.NIFTIhdr.vox_offset),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
- msg('Unable to load mask ' +lMaskHdr.ImgFileName);
+ NPMMsg('Unable to load mask ' +lMaskHdr.ImgFileName);
goto 667;
end;
for lVox := 1 to lVolVox do begin
@@ -3502,13 +1605,13 @@ begin
lAName := 'C:\mri\roc\p2.nii.gz';
lBName := 'C:\mri\roc\RBD35.voi';
if not ComputeIntersection ( lAName,lBName,lUnion,lIntersection,lAnotB,lBnotA) then
- Msg('Error');
- Msg( lAName+' '+lBName+' I'+inttostr(lIntersection)+' U'+inttostr(lUnion)+' AnotB'+inttostr(lAnotB)+' BnotA'+inttostr(lBnotA));
+ NPMMsg('Error');
+ NPMMsg( lAName+' '+lBName+' I'+inttostr(lIntersection)+' U'+inttostr(lUnion)+' AnotB'+inttostr(lAnotB)+' BnotA'+inttostr(lBnotA));
-end;
+end; *)
-procedure TMainForm.ComputeIntersectionandUnion1Click(Sender: TObject);
+(*procedure TMainForm.ComputeIntersectionandUnion1Click(Sender: TObject);
label
666;
var
@@ -3521,9 +1624,9 @@ var
X: PMatrix;
begin
lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
- MsgClear;
- Msg(kVers);
- Msg('Compute intersection [A and B] and union [A or B] for a series of images');
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ NPMMsg('Compute intersection [A and B] and union [A or B] for a series of images');
if not ReadPairedFilenamesReg(lImageNames,X,lnAdditionalFactors) then exit;
@@ -3548,7 +1651,7 @@ begin
end;
- Msg ('n Subjects = '+inttostr(lnSubj));
+ NPMMsg ('n Subjects = '+inttostr(lnSubj));
for lSubj := 0 to (lnSubj-1) do begin
lStr := 'A=,'+lImageNames[lSubj]+',B=,'+lImageNames[lSubj+lnSubj];
ComputeIntersection ( lImageNames[lSubj],lImageNames[lSubj+lnSubj],lUnion,lIntersection,lAnotB,lBnotA);
@@ -3556,22 +1659,18 @@ begin
lStr := lStr + ',A or B=,'+inttostr(lUnion);
lStr := lStr + ',A not B=,'+inttostr(lAnotB);
lStr := lStr + ',B not A=,'+inttostr(lBnotA);
-
-
-
-
- Msg(lStr);
+ NPMMsg(lStr);
end;
//Msg('Mask = '+lMaskname);
//Msg('Total voxels = '+inttostr(lMaskVoxels));
- Msg('Number of observations = '+inttostr(lnSubj));
+ NPMMsg('Number of observations = '+inttostr(lnSubj));
666:
lImageNames.Free;
end; //compute intersection and union
+ *)
-
-procedure TMainForm.ROCbinomialdeficit1Click(Sender: TObject);
+(*procedure TMainForm.ROCbinomialdeficit1Click(Sender: TObject);
begin
testROC;
end;
@@ -3579,7 +1678,7 @@ end;
procedure TMainForm.ROCcontinuousdeficit1Click(Sender: TObject);
begin
testROC2;
-end;
+end; *)
function isBinom ( lRA: singleP; lnObs: integer): boolean;
var
@@ -3615,7 +1714,6 @@ begin
lMeans1 := lMeans1 / (lnObs-ln0);
npmform.MainForm.memo1.lines.add('mean volume for '+inttostr(ln0)+' people who scored 0 is = '+floattostr(lmeans0));
npmform.MainForm.memo1.lines.add('mean volume for '+inttostr(lnObs-ln0)+' people who scored 1 is = '+floattostr(lmeans1));
-
end;
function AUCbinomcontT (lBinomdataRA,lContdataRA: singlep; lnSubj :integer; var lT: double): double;
@@ -3663,95 +1761,88 @@ begin
end;
//xxx
end;
-
-function ComputeOverlap ( lROIname: string; var lLesionNames: TStrings; var lROIvol: double; lFracROIinjured: singlep): boolean;
-label 667;
+ (*
+procedure ROIanalysis(var lROInames,lImageNames: TStrings; var lVALFilename: string);
+label
+ 666;
var
- lName: string;
- lSum: double;
- lLesion,lnLesions,lVolVox,lVolVoxA,lVox: integer;
- lROIImg,lImgB: SingleP;
- lMaskHdr: TMRIcroHdr;
+ lROI,lnROI,lVol,lMin,lMax,lI,lFact,lnFactors,lSubj,lnSubj,lMaskVoxels,lnCrit: integer;
+ //lROInames,lImageNames: TStrings;
+ lPredictorList: TStringList;
+ lVolStr,lTemp4D,lOutName,lStr: string;
+ lBehav: single;
+ lROIvolRA: doubleP;
+ lMultiSymptomRA,lLesionVolRA,lBehavRA: singleP;
+ lError: boolean;
begin
- lROIvol := 0;
- result := false;
- lnLesions := lLesionNames.count;
- if lnLesions < 1 then begin
- showmessage('Error: no lesion names');
- exit;
- end;
- for lLesion := 1 to lnLesions do
- lFracROIinjured^[lLesion] := 0;
- //read A
- if not NIFTIhdr_LoadHdr(lROIname,lMaskHdr) then begin
- showmessage('Error reading ROI - '+lROIname);
- exit;
- end;
- lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
- if (lVolVox < 1) then begin
- showmessage('Error with Mask voxels ' + inttostr(lVolVox));
- exit;
- end;
- if not CheckVoxelsGroupX(lLesionNames, lMaskHdr) then begin
- showmessage('Error image dimensions vary.');
- exit;
- end;
- getmem(lROIImg,lVolVox*sizeof(single));
- getmem(lImgB,lVolVox*sizeof(single));
- if not LoadImg(lROIname, lROIImg, 1, lVolVox,round(lMaskHdr.NIFTIhdr.vox_offset),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
- MainForm.NPMmsg('Unable to load lesion ' +lMaskHdr.ImgFileName);
- goto 667;
+ lnROI := lROINames.Count;
+ if lnROI < 1 then begin
+ showmessage('You need to select at least one ROI.');
+ goto 666;
+ end;
+ //lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
+ if not GetValCore ( lVALFilename,lnSubj,lnFactors,lMultiSymptomRA,lImageNames,lnCrit,lPredictorList) then
+ goto 666;
+ lTemp4D := CreateDecompressed4D(lImageNames);
+ if (lnSubj < 1) or (lnFactors < 1) then begin
+ showmessage('This analysis requires at least 1 participant and one factor');
+ goto 666;
+ end;
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ NPMmsg('Analysis began = ' +TimeToStr(Now));
+ NPMMsg('VAL file name: '+MainForm.OpenHdrDlg.Filename);
+ NPMMsg('Number of participants: '+inttostr(lnSubj));
+ NPMMsg('Number of factors: '+inttostr(lnFactors));
+ NPMMsg('Number of Lesion maps = '+inttostr(lnSubj));
+ //next - header shows factor names
+ lStr :='imagename';
+ for lFact := 1 to lnFactors do
+ lStr := lStr+','+lPredictorList[lFact-1];
+ for lROI := 1 to lnROI do
+ lStr := lStr+','+lROInames[lROI-1];
+ NPMMsg(lStr+',LesionVolume');
+ lError := false;
+ Getmem(lROIVolRA, lnSubj*lnROI*sizeof(double));
+ Getmem(lLesionVolRA, lnSubj*lnROI*sizeof(single));
+ Getmem(lBehavRA, lnSubj*lnFactors*sizeof(single));
+ for lROI := 1 to lnROI do begin
+ //if not ComputeIntersection ( lImageNames.Strings[lSubj-1],lROInames[lROI-1],lUnion,lIntersection,lAnotB,lBnotA) then
+ if not ComputeOverlap (lROInames[lROI-1],lImageNames, lROIvolRA^[lROI], singlep(@lLesionVolRA^[((lROI-1)*lnSubj)+1])) then begin
+ NPMmsg('Error computing overlap');
+ goto 666;
+ end;
end;
- lVolVoxA := lVolVox;
- for lVox := 1 to lVolVox do
- if (lROIImg^[lVox] > 0) then
- lROIvol := lROIvol +lROIImg^[lVox];
- //read Lesion
- if lROIvol < 1 then begin
- MainForm.NPMmsg('ROI volume < 1');
- goto 667;
+ For lSubj := 1 to lnSubj do begin
+ lStr :='';
+ for lFact := 1 to lnFactors do begin
+ lBehav := lMultiSymptomRA^[lSubj+ ((lFact-1)*lnSubj)];
+ lStr := lStr+','+realtostr(lBehav,2);
+ lBehavRA^[((lFact-1)*lnSubj) +lSubj] := lBehav;
+ end;
+ for lROI := 1 to lnROI do
+ lStr := lStr+','+floattostr(lLesionVolRA^[((lROI-1)*lnSubj) +lSubj]);
+ lVolStr := floattostr(ComputeLesionVolume(lImageNames.Strings[lSubj-1]));
+ NPMMsg (lImageNames.Strings[lSubj-1] + ' = '+lStr +','+lVolStr );
end;
- //for each lesion
- //MainForm.NPMmsg('Compute overlap started '+inttostr(lnLesions)+' '+floattostr(lROIvol)+' '+inttostr(lVolVoxA));
- MainForm.ProgressBar1.Position := 0;
- for lLesion := 1 to lnLesions do begin
- MainForm.ProgressBar1.Position := round((lLesion/lnLesions)*100) ;
- lSum := 0;
- lName := lLesionNames.Strings[lLesion-1];
- if not NIFTIhdr_LoadHdr(lName,lMaskHdr) then begin
- showmessage('Error reading lesion - '+lName);
- exit;
- end;
- lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
- if (lVolVoxA <> lVolVox) or (lVolVox < 1) then begin
- MainForm.NPMmsg('Volume does not have expected number of voxels ' +lMaskHdr.ImgFileName +'<>'+lROIname+ ' found ' +inttostr(lVolVox)+' expected '+inttostr(lVolVoxA));
- goto 667;
- end;
- if not LoadImg(lName, lImgB, 1, lVolVox,round(lMaskHdr.NIFTIhdr.vox_offset),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
- MainForm.NPMmsg('Unable to load mask ' +lMaskHdr.ImgFileName);
- goto 667;
- end;
- for lVox := 1 to lVolVox do begin
- //if {(lImgB^[lVox] <> 0) and} (lROIImg^[lVox] <> 0) then fx(lROIImg^[lVox]);
-
- if (lROIImg^[lVox] > 0) and (lImgB^[lVox] <> 0) then
- lSum := lSum + lROIImg^[lVox];
- end;
- lFracROIinjured^[lLesion] := lSum/lROIvol;
- end;//for each lesion
- result := true;
- MainForm.ProgressBar1.Position := 0;
-
- (*for lLesion := 1 to lnLesions do begin
- if lFracROIinjured^[lLesion] > 0 then
- fx( lFracROIinjured^[lLesion], lLesion);
- end; *)
-
- 667:
-
- freemem(lImgB);
- freemem(lROIImg);
-end;
+ for lROI := 1 to lnROI do begin
+ for lFact := 1 to lnFactors do begin
+ Contrast(lPredictorList[lFact-1],lROInames[lROI-1],singlep(@lBehavRA^[((lFact-1)*lnSubj)+1]),singlep(@lLesionVolRA^[((lROI-1)*lnSubj)+1]),lnSubj);//,((lFact-1)*lnSubj),((lROI-1)*lnSubj));
+ end; //for each factor
+ end; //for each ROI
+ for lROI := 1 to lnROI do begin
+ NPMMsg( lROInames[lROI-1] +' volume = '+floattostr(lROIvolRA^[lROI]) )
+ end; //for each ROI
+ Freemem(lLesionVolRA);
+ Freemem(lBehavRA);
+ Freemem(lROIvolRA);
+666:
+ lROInames.free;
+ lImageNames.Free;
+ lPredictorList.Free;
+ DeleteDecompressed4D(lTemp4D);
+ NPMmsg('Analysis finished = ' +TimeToStr(Now));
+end; *)
procedure TMainForm.ROIanalysis1Click(Sender: TObject);
@@ -3786,20 +1877,20 @@ begin
showmessage('This analysis requires at least 1 participant and one factor');
goto 666;
end;
- MsgClear;
- Msg(kVers);
- MainForm.NPMmsg('Analysis began = ' +TimeToStr(Now));
- Msg('VAL file name: '+MainForm.OpenHdrDlg.Filename);
- Msg('Number of participants: '+inttostr(lnSubj));
- Msg('Number of factors: '+inttostr(lnFactors));
- Msg('Number of Lesion maps = '+inttostr(lnSubj));
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ NPMmsg('Analysis began = ' +TimeToStr(Now));
+ NPMMsg('VAL file name: '+MainForm.OpenHdrDlg.Filename);
+ NPMMsg('Number of participants: '+inttostr(lnSubj));
+ NPMMsg('Number of factors: '+inttostr(lnFactors));
+ NPMMsg('Number of Lesion maps = '+inttostr(lnSubj));
//next - header shows factor names
lStr :='imagename';
for lFact := 1 to lnFactors do
lStr := lStr+','+lPredictorList[lFact-1];
for lROI := 1 to lnROI do
lStr := lStr+','+lROInames[lROI-1];
- Msg(lStr+',LesionVolume');
+ NPMMsg(lStr+',LesionVolume');
lError := false;
Getmem(lROIVolRA, lnSubj*lnROI*sizeof(double));
Getmem(lLesionVolRA, lnSubj*lnROI*sizeof(single));
@@ -3807,7 +1898,7 @@ begin
for lROI := 1 to lnROI do begin
//if not ComputeIntersection ( lImageNames.Strings[lSubj-1],lROInames[lROI-1],lUnion,lIntersection,lAnotB,lBnotA) then
if not ComputeOverlap (lROInames[lROI-1],lImageNames, lROIvolRA^[lROI], singlep(@lLesionVolRA^[((lROI-1)*lnSubj)+1])) then begin
- MainForm.NPMmsg('Error computing overlap');
+ NPMmsg('Error computing overlap');
goto 666;
end;
end;
@@ -3821,46 +1912,25 @@ begin
for lROI := 1 to lnROI do
lStr := lStr+','+floattostr(lLesionVolRA^[((lROI-1)*lnSubj) +lSubj]);
lVolStr := floattostr(ComputeLesionVolume(lImageNames.Strings[lSubj-1]));
- Msg (lImageNames.Strings[lSubj-1] + ' = '+lStr +','+lVolStr );
+ NPMMsg (lImageNames.Strings[lSubj-1] + ' = '+lStr +','+lVolStr );
end;
- (* For lSubj := 1 to lnSubj do begin
- lStr :='';
- for lFact := 1 to lnFactors do begin
- lBehav := lMultiSymptomRA^[lSubj+ ((lFact-1)*lnSubj)];
- lStr := lStr+','+realtostr(lBehav,2);
- lBehavRA^[((lFact-1)*lnSubj) +lSubj] := lBehav;
- end;
- for lROI := 1 to lnROI do begin
- if ComputeIntersection ( lImageNames.Strings[lSubj-1],lROInames[lROI-1],lUnion,lIntersection,lAnotB,lBnotA) then begin
- lStr := lStr+','+inttostr(lIntersection);
- lLesionVolRA^[((lROI-1)*lnSubj) +lSubj] := lIntersection;
- end else begin
- lError:= true;
- lStr := lStr+',error';
- end;
- //Msg( lImageNames.Strings[lSubj-1]+' '+lROInames[lROI-1]+' I'+inttostr(lIntersection)+' U'+inttostr(lUnion)+' AnotB'+inttostr(lAnotB)+' BnotA'+inttostr(lBnotA));
-
- end;
- Msg (lImageNames.Strings[lSubj-1] + ' = '+lStr );
- end;*)
for lROI := 1 to lnROI do begin
for lFact := 1 to lnFactors do begin
Contrast(lPredictorList[lFact-1],lROInames[lROI-1],singlep(@lBehavRA^[((lFact-1)*lnSubj)+1]),singlep(@lLesionVolRA^[((lROI-1)*lnSubj)+1]),lnSubj);//,((lFact-1)*lnSubj),((lROI-1)*lnSubj));
end; //for each factor
end; //for each ROI
for lROI := 1 to lnROI do begin
- Msg( lROInames[lROI-1] +' volume = '+floattostr(lROIvolRA^[lROI]) )
+ NPMMsg( lROInames[lROI-1] +' volume = '+floattostr(lROIvolRA^[lROI]) )
end; //for each ROI
Freemem(lLesionVolRA);
Freemem(lBehavRA);
Freemem(lROIvolRA);
-
666:
lROInames.free;
lImageNames.Free;
lPredictorList.Free;
DeleteDecompressed4D(lTemp4D);
- MainForm.NPMmsg('Analysis finished = ' +TimeToStr(Now));
+ NPMmsg('Analysis finished = ' +TimeToStr(Now));
end;
@@ -3869,8 +1939,8 @@ var
lFilename,lMaskname: string;
lPos: Integer;
begin
- MsgClear;
- Msg(GetKVers);
+ NPMMsgClear;
+ NPMMsg(GetKVers);
if not OpenDialogExecute('Select brain mask ',false,false,kImgFilter) then begin
showmessage('NPM aborted: mask selection failed.');
exit;
@@ -3882,7 +1952,6 @@ begin
end; //if not selected
if OpenHdrDlg.Files.Count < 1 then
exit;
-
for lPos := 1 to OpenHdrDlg.Files.Count do begin
lFilename := OpenHdrDlg.Files[lPos-1];
balance(lFilename,lMaskname,(Sender as TMenuItem).tag);
@@ -3911,7 +1980,7 @@ begin
getmem(lImg,lVolVox*sizeof(single));
getmem(lImg8,lVolVox*sizeof(byte));
if not LoadImg(lHdr.ImgFileName, lImg, 1, lVolVox,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lVolVox) then begin
- Msg('Unable to load ' +lHdr.ImgFileName);
+ NPMMsg('Unable to load ' +lHdr.ImgFileName);
exit;
end;
lHdr.NIFTIhdr.scl_slope := 1;
@@ -3938,11 +2007,10 @@ end;
for lVox := 1 to lVolVox do
if lImg^[lVox] > lMax then
lImg8^[lVox] := lNonZeroVal;
- Msg('Creating ' +lOutNameMod+' Threshold = '+floattostr(lMax));
+ NPMMsg('Creating ' +lOutNameMod+' Threshold = '+floattostr(lMax));
NIFTIhdr_SaveHdrImg8(lOutNameMod,lHdr.NIFTIhdr,true,not IsNifTiMagic(lHdr.NIFTIhdr),true,lImg8,1);
freemem(lIMg8);
freemem(lImg);
-
end;
@@ -3951,8 +2019,8 @@ var
lFilename: string;
lPos: Integer;
begin
- MsgClear;
- Msg(GetKVers);
+ NPMMsgClear;
+ NPMMsg(GetKVers);
if not OpenDialogExecute('Select images for intensity normalization',true,false,kImgFilter) then begin
showmessage('NPM aborted: file selection failed.');
exit;
@@ -3964,41 +2032,9 @@ begin
Binarize(lFilename,1,false);
//Binarize (var lImageName:String; lNonZeroVal: integer; lZeroThresh: boolean): boolean;
end;
- Msg('Done');
+ NPMMsg('Done');
end;
-procedure TMainForm.Resliceimagetoneworientationandboundingbox1Click(
- Sender: TObject);
-begin
-(* var
- lSourcename,lTargetName: string;
- lPos: integer;
-begin
- MsgClear;
- Msg(GetKVers);
- Msg('This function will transform a source image to match a target image.');
- Msg(' The resliced image will have the voxel size, orientation and bounding box of the target.');
- Msg('You will be prompted to select a target image as well as source images.');
- Msg(' The resliced image will have the prefix ''r'', e.g. c:\source.nii -> c:\rsource.nii.');
- if not OpenDialogExecute('Select target image (source images will be resliced to match target)',false,false,kImgFilter) then begin
- showmessage('reslice aborted: target selection failed.');
- exit;
- end; //if not selected
- lTargetName := OpenHdrDlg.Filename;
- if not OpenDialogExecute('Select source images for reslicing',true,false,kImgFilter) then begin
- showmessage('reslice aborted: source selection failed.');
- exit;
- end; //if not selected
- if OpenHdrDlg.Files.Count < 1 then
- exit;
- for lPos := 1 to OpenHdrDlg.Files.Count do begin
- lSourcename := OpenHdrDlg.Files[lPos-1];
-
- xxBinarize(lFilename);
- end;
- Msg('Done');
- *)
-end;
procedure TMainForm.Setnonseroto1001Click(Sender: TObject);
@@ -4006,8 +2042,8 @@ var
lFilename: string;
lPos: Integer;
begin
- MsgClear;
- Msg(GetKVers);
+ NPMMsgClear;
+ NPMMsg(GetKVers);
if not OpenDialogExecute('Select images for intensity normalization',true,false,kImgFilter) then begin
showmessage('NPM aborted: file selection failed.');
exit;
@@ -4030,20 +2066,7 @@ begin
Memo1.Lines.SaveToFile(SaveHdrDlg.Filename);
end;
-procedure TMainForm.AnaCOMmenuClick(Sender: TObject);
-begin
-{$IFDEF compileANACOM}
- DoAnaCOM;
-{$ENDIF}
-end;
-
-procedure TMainForm.MonteCarloSimulation1Click(Sender: TObject);
-begin
-{$IFDEF benchmark}
- LesionMonteCarlo (false,true,true);
-{$ENDIF}
-end;
-
+(*
function TMainForm.MakeSubtract (lPosName,lNegName: string): boolean;
var
lNegImg,lImg,lOutImg: SingleP;
@@ -4053,14 +2076,14 @@ var
begin
result := false;
if not NIFTIhdr_LoadHdr(lPosName,lHdr) then begin
- showmessage('Error reading '+lPosName);
+ ShowMsg('Error reading '+lPosName);
exit;
end;
lVolVox := lHdr.NIFTIhdr.dim[1]*lHdr.NIFTIhdr.dim[2]* lHdr.NIFTIhdr.dim[3];
if (lVolVox < 1) then exit;
getmem(lImg,lVolVox*sizeof(single));
if not LoadImg(lHdr.ImgFileName, lImg, 1, lVolVox,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lVolVox) then begin
- Msg('Unable to load ' +lHdr.ImgFileName);
+ NPMMsg('Unable to load ' +lHdr.ImgFileName);
exit;
end;
@@ -4069,18 +2092,18 @@ begin
exit;
end;
if lVolVox <> (lNegHdr.NIFTIhdr.dim[1]*lNegHdr.NIFTIhdr.dim[2]* lNegHdr.NIFTIhdr.dim[3]) then begin
- showmessage('Volumes differ');
+ ShowMsg('Volumes differ');
exit;
end;
getmem(lImg,lVolVox*sizeof(single));
if not LoadImg(lHdr.ImgFileName, lImg, 1, lVolVox,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lVolVox) then begin
- Msg('Unable to load ' +lHdr.ImgFileName);
+ NPMMsg('Unable to load ' +lHdr.ImgFileName);
exit;
end;
getmem(lNegImg,lVolVox*sizeof(single));
if not LoadImg(lNegHdr.ImgFileName, lNegImg, 1, lVolVox,round(lNegHdr.NIFTIhdr.vox_offset),1,lNegHdr.NIFTIhdr.datatype,lVolVox) then begin
- Msg('Unable to load ' +lNegHdr.ImgFileName);
+ NPMMsg('Unable to load ' +lNegHdr.ImgFileName);
exit;
end;
getmem(lOutImg,lVolVox*sizeof(single));
@@ -4091,17 +2114,17 @@ begin
lHdr.NIFTIhdr.scl_slope := 1;
lHdr.NIFTIhdr.scl_inter := 0;
lOutNameMod := ChangeFilePrefixExt(lPosName,'subtract_','.hdr');
- Msg(lPosName+' - ' + lNegName+ ' = '+lOutNameMod);
+ NPMMsg(lPosName+' - ' + lNegName+ ' = '+lOutNameMod);
NIFTIhdr_SaveHdrImg(lOutNameMod,lHdr.NIFTIhdr,true,not IsNifTiMagic(lHdr.NIFTIhdr),true,lOutImg,1);
- //end optional
- //NIFTIhdr_SaveHdr(lHdr.HdrFilename,lHdr.NIFTIhdr,true,not IsNifTiMagic(lHdr.NIFTIhdr));
+
freemem(lImg);
freemem(lOutImg);
freemem(lNegImg);
end;//makesubtract
+*)
-procedure TMainForm.Subtract1Click(Sender: TObject);
+(*procedure TMainForm.Subtract1Click(Sender: TObject);
var
lPosName,lNegName: string;
begin
@@ -4113,35 +2136,15 @@ begin
lNegName := OpenHdrDlg.FileName;
MakeSubtract (lPosName,lNegName);
-end;
-
+end; *)
-procedure TMainForm.LogPtoZ1Click(Sender: TObject);
-var
- lFilename: string;
- lPos: Integer;
-begin
- MsgClear;
- Msg(GetKVers);
- if not OpenDialogExecute('Select images for intensity normalization',true,false,kImgFilter) then begin
- showmessage('NPM aborted: file selection failed.');
- exit;
- end; //if not selected
- if OpenHdrDlg.Files.Count < 1 then
- exit;
- for lPos := 1 to OpenHdrDlg.Files.Count do begin
- lFilename := OpenHdrDlg.Files[lPos-1];
- //LogPToZ(lFilename,1,false);
+ {$IFDEF UNIX}
- end;
- Msg('Done');
-end;
- {$IFDEF UNIX}
initialization
{$I npmform.lrs}
{$ELSE} //not unix: windows
diff --git a/npm/old/anacom.pas b/npm/old/anacom.pas
old mode 100644
new mode 100755
diff --git a/npm/old/lesion.pas b/npm/old/lesion.pas
old mode 100644
new mode 100755
diff --git a/npm/old/montecarlo.pas b/npm/old/montecarlo.pas
old mode 100644
new mode 100755
diff --git a/npm/options.inc b/npm/options.inc
old mode 100644
new mode 100755
diff --git a/npm/overlap.pas b/npm/overlap.pas
old mode 100644
new mode 100755
index 3f65a32..6744ebc
--- a/npm/overlap.pas
+++ b/npm/overlap.pas
@@ -1,27 +1,24 @@
unit overlap;
{$H+}
-
+{$Include ..\common\isgui.inc}
interface
uses
-nifti_hdr,define_types,SysUtils,
-StatThdsUtil,Brunner,nifti_img,
- Classes, Graphics, Controls, Forms, Dialogs,
-StdCtrls, ComCtrls,ExtCtrls,lesion_pattern;
+// Graphics, Controls, Forms, StdCtrls, ComCtrls,ExtCtrls,
+Classes,nifti_hdr,define_types,SysUtils,dialogsx,
+StatThdsUtil,Brunner,nifti_img,lesion_pattern, unpm;
Type
OverlapRA = array [1..1] of TLesionPattern;//Toverlap;
Overlapp = ^OverlapRA;
-//function CountOverlap2(var lImages: TStrings; lMinDeficits: integer; lPlankImg: bytep): integer;
function CountOverlap (var lImages: TStrings; lMinDeficits,lnVoxTested: integer): integer;
procedure EvaluatePower(var lFilenames: TStrings; lOverlapInc,lOverlapMax,lReps,lPct: integer);
function CountOverlap2(var lImages: TStrings; lMinDeficits, lnVoxTested: integer; lPlankImg: bytep): integer;
-//procedure EvaluatePower;
implementation
-uses npmform;
+
function SelectFiles (var lIn,lOut: TStrings; lN: integer): boolean;
//select (without replacement) lN filenames from the population lIn
@@ -58,20 +55,20 @@ var
lSize,lRep: integer;
begin
if (lReps < 1) or (lOverlapMax < 1) or (lOverlapInc < 1) or (lOverlapMax > lFilenames.count) or (lOverlapInc > lOverlapMax) then begin
- showmessage('Error with EvaluatePower inputs...');
+ ShowMsg('Error with EvaluatePower inputs...');
exit;
end;
- MainForm.NPMMsgClear;
+ NPMMsgClear;
//MainForm.NPMmsg(kVers);
randomize;
- MainForm.NPMmsg('Power Analysis began = ' +TimeToStr(Now));
+ NPMmsg('Power Analysis began = ' +TimeToStr(Now));
lSize := lOverlapInc;
while lSize <= lOverlapMax do begin
for lRep := 1 to lReps do begin
lG:= TStringList.Create;
if not SelectFiles(lFilenames,lG,lSize) then begin
- showmessage('Error selecting '+inttostr(lSize)+'files!');
+ ShowMsg('Error selecting '+inttostr(lSize)+'files!');
goto 666;
end;
CountOverlap(lG, round((lPct/100)*lSize),-1 );
@@ -79,7 +76,7 @@ begin
end; //for lLoop
lSize := lSize + lOverlapInc;
end; //for lRep
- MainForm.NPMmsg('Analysis finished = ' +TimeToStr(Now));
+ NPMmsg('Analysis finished = ' +TimeToStr(Now));
exit;
666: //there has been a critical failure!
lG.Free;
@@ -142,11 +139,11 @@ begin
lN := lRep * 10;
lG:= TStringList.Create;
if not SelectFiles(lN,lG) then begin
- showmessage('Error selecting '+inttostr(lN)+'files!');
+ ShowMsg('Error selecting '+inttostr(lN)+'files!');
goto 666;
end;
{if not OpenDialogExecute('Select images to average',true,true,kImgFilter) then begin
- showmessage('NPM aborted: file selection failed.');
+ ShowMsg('NPM aborted: file selection failed.');
exit;
end; //if not selected
lG:= TStringList.Create;
@@ -156,12 +153,12 @@ begin
//this next bit allows different types of scans to be read, but it is slow....
lMaskname := lG[0];
if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- showmessage('Error reading mask.');
+ ShowMsg('Error reading mask.');
goto 666;
end;
lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
if not MainForm.CheckVoxelsGroup(lG,lMaskVoxels) then begin
- showmessage('File dimensions differ from mask.');
+ ShowMsg('File dimensions differ from mask.');
goto 666;
end;
{$ENDIF}
@@ -218,17 +215,17 @@ begin
if lImagesCount < 1 then
goto 667;
if lImages.Count > (kMaxObs) then begin
- MainForm.NPMmsg('Only able to compute tests for <= '+inttostr(kMaxObs)+' overlays.');
+ NPMmsg('Only able to compute tests for <= '+inttostr(kMaxObs)+' overlays.');
goto 667;
end;
if not NIFTIhdr_LoadHdr(lMaskName,lMaskHdr) then begin
- MainForm.NPMmsg('Error reading 1st image.');
+ NPMmsg('Error reading 1st image.');
goto 667;
end;
lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
lDataType := lMaskHdr.NIFTIhdr.datatype;
lOffset := round(lMaskHdr.NIFTIhdr.vox_offset);
- //showmessage(inttostr(lVolVox));
+ //ShowMsg(inttostr(lVolVox));
if (lVolVox < 1) then goto 667;
lVoxPerPlank := kPlankSz div lImages.Count {div sizeof(single)} ;
if (lVoxPerPlank = 0) then goto 667; //no data
@@ -244,9 +241,8 @@ begin
else
getmem(lOverlapRA,lnVoxTested* sizeof(TLesionPattern));
for lPlank := 1 to lnPlanks do begin
- MainForm.ProgressBar1.Position := 1;
- MainForm.Refresh;
- Application.processmessages;
+ NPMProgressBar(1);
+
lEndVox := lEndVox + lVoxPerPlank;
if lEndVox > lVolVox then begin
lVoxPerPlank := lVoxPerPlank - (lEndVox-lVolVox);
@@ -266,9 +262,8 @@ begin
lPrevOrder := EmptyOrder;//impossible: forces first voxel of each order to be checked
for lVox := 1 to lVoxPerPlank do begin
if (lVox mod lVoxPerPlankDiv10) = 0 then begin
- MainForm.ProgressBar1.Position := (lVox div lVoxPerPlankDiv10)*10;
- MainForm.Refresh;
- Application.processmessages;
+ NPMProgressBar((lVox div lVoxPerPlankDiv10)*10);
+
end;
lOrder := EmptyOrder;
lPlankImgPos := 0;
@@ -289,13 +284,12 @@ begin
end;
lStartVox := lEndVox + 1;
end;
- MainForm.NPMmsg('n=,'+inttostr( lImages.Count)+',minN=,'+inttostr(lMinDeficits) +',unique overlap patterns,' +Inttostr(lUniqueOrders) +',voxels tested,' +Inttostr(lnVoxels));
+ NPMmsg('n=,'+inttostr( lImages.Count)+',minN=,'+inttostr(lMinDeficits) +',unique overlap patterns,' +Inttostr(lUniqueOrders) +',voxels tested,' +Inttostr(lnVoxels));
123:
//next: free dynamic memory
freemem(lOverlapRA);
- //MainForm.NPMmsg('Analysis finished = ' +TimeToStr(Now));
- MainForm.ProgressBar1.Position := 0;
+ NPMProgressBar(0);
result := lUniqueOrders;
exit;
667: //you only get here if you aborted ... free memory and report error
@@ -303,8 +297,8 @@ begin
freemem(lPlankImg);
freemem(lOverlapRA);
end;
- MainForm.NPMmsg('Unable to complete analysis.');
- MainForm.ProgressBar1.Position := 0;
+ NPMmsg('Unable to complete analysis.');
+ NPMProgressBar( 0);
end;
function CountOverlap(var lImages: TStrings; lMinDeficits,lnVoxTested: integer): integer;
@@ -346,7 +340,7 @@ begin
end;
begin
result := -1;
- //MainForm.NPMmsg('Analysis began = ' +TimeToStr(Now));
+ //NPMmsg('Analysis began = ' +TimeToStr(Now));
//lMinDeficits := 0;
lUniqueOrders := 0;
lTotalMemory := 0;
@@ -355,26 +349,26 @@ begin
if lImages.Count < 1 then
goto 667;
if lImages.Count > (kMaxObs) then begin
- MainForm.NPMmsg('Only able to compute tests for <= '+inttostr(kMaxObs)+' overlays.');
+ NPMmsg('Only able to compute tests for <= '+inttostr(kMaxObs)+' overlays.');
goto 667;
end;
if not NIFTIhdr_LoadHdr(lMaskName,lMaskHdr) then begin
- MainForm.NPMmsg('Error reading 1st image.');
+ NPMmsg('Error reading 1st image.');
goto 667;
end;
lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
lDataType := lMaskHdr.NIFTIhdr.datatype;
lOffset := round(lMaskHdr.NIFTIhdr.vox_offset);
- //showmessage(inttostr(lVolVox));
+ //ShowMsg(inttostr(lVolVox));
if (lVolVox < 1) then goto 667;
lVoxPerPlank := kPlankSz div lImages.Count ;
if (lVoxPerPlank = 0) then goto 667; //no data
lTotalMemory := lVolVox * lImages.Count;
if (lTotalMemory = 0) then goto 667; //no data
- //showmessage('xx');
+ //ShowMsg('xx');
lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
- //MainForm.NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
- //MainForm.NPMmsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
+ //NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
+ //NPMmsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
//if lTotalMemory > kPLankSz then
// getmem(lPlankImg,kPlankSz);
@@ -430,12 +424,12 @@ begin
end;
lStartVox := lEndVox + 1;
end;
- MainForm.NPMmsg('n=,'+inttostr( lImagesCount)+',minN=,'+inttostr(lMinDeficits) +',unique overlap patterns,' +Inttostr(lUniqueOrders) +',voxels tested,' +Inttostr(lnVoxels));
+ NPMmsg('n=,'+inttostr( lImagesCount)+',minN=,'+inttostr(lMinDeficits) +',unique overlap patterns,' +Inttostr(lUniqueOrders) +',voxels tested,' +Inttostr(lnVoxels));
123:
//next: free dynamic memory
//freemem(lPlankImg);
freemem(lOverlapRA);
- //MainForm.NPMmsg('Analysis finished = ' +TimeToStr(Now));
+ //NPMmsg('Analysis finished = ' +TimeToStr(Now));
MainForm.ProgressBar1.Position := 0;
result := lUniqueOrders;
exit;
@@ -444,9 +438,9 @@ begin
freemem(lPlankImg);
freemem(lOverlapRA);
end;
- MainForm.NPMmsg('Unable to complete analysis.');
+ NPMmsg('Unable to complete analysis.');
MainForm.ProgressBar1.Position := 0;
end; *)
-end.
+end.
\ No newline at end of file
diff --git a/npm/part.pas b/npm/part.pas
old mode 100644
new mode 100755
index 85ff180..1c2a991
--- a/npm/part.pas
+++ b/npm/part.pas
@@ -3,7 +3,7 @@ unit part;
{$H+}
interface
uses
- define_types,dialogs,SysUtils;
+ define_types,dialogsx,SysUtils;
function ApplyPart( lFilename: string;lImgData: singleP; lBins,lVolVox,lSlices, lImgVol : integer; lTRsec: single): string;
@@ -91,16 +91,16 @@ var
begin
result := '';
if (lPhysio.Triggers < 4) or (lnVolVox < 4) or (lImgVol < 4) then begin
- showmessage('PART requires at least 4 triggers and at least 4 volumes each with at least 4 voxels');
+ ShowMsg('PART requires at least 4 triggers and at least 4 volumes each with at least 4 voxels');
exit;
end;
if (lBinIn < 4) then begin
- showmessage('PART requires at least 4 data bins');
+ ShowMsg('PART requires at least 4 data bins');
exit;
end;
lnSliceVox := lnVolVox div lnSlices;
if (lnVolVox mod lnSlices) <> 0 then begin
- showmessage('PART requires volvox to be evenly divisible by number of slices.');
+ ShowMsg('PART requires volvox to be evenly divisible by number of slices.');
exit;
end;
lSamplesWithVariance := 0;
@@ -226,7 +226,7 @@ begin
result := strtoint(lNumStr);
except
on EConvertError do begin
- showmessage('StrVal Error - Unable to convert the string '+lNumStr+' to a number');
+ ShowMsg('StrVal Error - Unable to convert the string '+lNumStr+' to a number');
result := MaxInt;
end;
end;
@@ -244,7 +244,7 @@ begin
if lnTotal < 5 then exit;
if lVal > 4096 then begin
if lVal <> 5000 then begin
- showmessage('Potentially serious error: unknown trigger type : '+inttostr(lVal));
+ ShowMsg('Potentially serious error: unknown trigger type : '+inttostr(lVal));
end;
inc(lnTrigger);
if (lPhysio.Triggers <> 0) then
@@ -440,7 +440,7 @@ var
begin
result := false;
if (lPhysioIn.Triggers < 4) then begin
- showmessage('InterpolateGaps requires at least 4 triggers.');
+ ShowMsg('InterpolateGaps requires at least 4 triggers.');
exit;
end;
l2Min := 2*lPhysioIn.TriggerMedian-(abs(lPhysioIn.TriggerQ1-lPhysioIn.TriggerQ3)*1.5);
@@ -499,11 +499,11 @@ var
begin
result := false;
if (lPhysio.Triggers < 4) then begin
- showmessage('ScalePhysioToTR requires at least 4 triggers.');
+ ShowMsg('ScalePhysioToTR requires at least 4 triggers.');
exit;
end;
if (lSamplesPerUnit <= 0) then begin
- showmessage('ScalePhysioToTime requires TR(sec) and samples/sec >0.');
+ ShowMsg('ScalePhysioToTime requires TR(sec) and samples/sec >0.');
exit;
end;
lScale := 1/(lSamplesPerUnit); //use reciprocal: mults faster than divides
@@ -521,7 +521,7 @@ begin
if lPhysio.Triggers < 2 then exit;
for lPos := 2 to lPhysio.Triggers do begin
if lPhysio.TriggerRA^[lPos] < lPhysio.TriggerRA^[lPos-1] then begin
- showmessage('Warning: input times are not in ascending order - data will be sorted.');
+ ShowMsg('Warning: input times are not in ascending order - data will be sorted.');
qsort(1,lPhysio.Triggers,lPhysio.TriggerRA); //ensure trigger timings are in order...
exit;
end;
@@ -552,4 +552,4 @@ begin
ClosePhysio(lPhysio);
end;
-end.
+end.
\ No newline at end of file
diff --git a/npm/prefs.pas b/npm/prefs.pas
old mode 100644
new mode 100755
index 60e5e17..83c83c6
--- a/npm/prefs.pas
+++ b/npm/prefs.pas
@@ -3,29 +3,19 @@ unit prefs;
{$H+}
interface
uses
- inifiles, define_types,SysUtils,classes,turbolesion;
+ inifiles, define_types,SysUtils,classes,turbolesion,dialogsx;
function DoLesion (var lPrefs: TLDMPrefs): boolean;
procedure SetDefaultPrefs (var lPrefs: TLDMPrefs);
-procedure ReadParamStr;
+function WarnIfLowNCrit(lnSubj,lnCrit: integer): boolean;
+//procedure ReadParamStr;
implementation
-uses nifti_img, hdr,nifti_hdr, valformat,StatThdsUtil,filename,npmform;
-
-procedure MsgX(lStr: string);
-begin
- MainForm.NPMmsg(lStr);
-end;
-
-procedure ClearMsgX;
-begin
- MainForm.NPMmsgClear
-end;
+uses nifti_img, hdr,nifti_hdr, valformat,StatThdsUtil,filename, unpm;
procedure SetDefaultPrefs (var lPrefs: TLDMPrefs);
begin
- //lPrefs.unusedbool := true;
lPrefs.tTest := true;
lPrefs.BMtest := false;
lPrefs.Ltest := false;
@@ -36,12 +26,6 @@ begin
lPrefs.Outname := '';
end;
-(*function CheckBool (lPref, lFlag: integer): boolean;
-//check if Flag is in lPref. For example, if Flag is 1 then returns true for all odd lPrefs
-begin
- result := (lPref and lFlag) = lFlag;
-end; *)
-
function noVariance (lRA: singlep; lnSubj: integer): boolean;
var
lI : integer;
@@ -54,6 +38,15 @@ begin
result := true;
end;
+function WarnIfLowNCrit(lnSubj,lnCrit: integer): boolean;
+//returns true if warning generated
+begin
+ result := (round(lnSubj * 0.15) ) > lnCrit; //15%
+ if result then
+ Showmsg('Warning: low statistical power as tests computed for voxels damaged in at least '+inttostr(lnCrit) +' people. Solution: change Design value "Ignore voxels damaged in less than N%".');
+
+end;
+
function DoLesion (var lPrefs: TLDMPrefs): boolean;
label
666;
@@ -66,46 +59,47 @@ var
lMultiSymptomRA,lSymptomRA: singleP;
begin
if (not lPrefs.BMtest) and (not lPrefs.ttest) and (not lPrefs.LTest) then begin
- MsgX('Error: you need to compute at least on test [options/test menu]');
+ NPMmsg('Error: you need to compute at least on test [options/test menu]');
exit;
end;
lImageNamesAll:= TStringList.Create; //not sure why TStrings.Create does not work???
lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
if not GetValCore(lPrefs.ValFilename, lnSubjAll,lnFactors,lMultiSymptomRA,lImageNamesAll,lnCritV,lCritPctV,lPredictorList) then begin
- MsgX('Error with VAL file');
+ NPMmsg('Error with VAL file');
goto 666;
end;
if lPrefs.critPct < 0 then //-1 denotes using the values specified in the VAL file
lPrefs.critPct := lCritPctV;
lTemp4D := CreateDecompressed4D(lImageNamesAll);
if (lnSubjAll < 1) or (lnFactors < 1) then begin
- MsgX('Not enough subjects ('+inttostr(lnSubjAll)+') or factors ('+inttostr(lnFactors)+').');
+ NPMmsg('Not enough subjects ('+inttostr(lnSubjAll)+') or factors ('+inttostr(lnFactors)+').');
goto 666;
end;
+ WarnIfLowNCrit(lnSubjAll, round( (lnSubjAll*lPrefs.CritPct)/100));
lMaskname := lImageNamesAll[0];
if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
- MsgX('Error reading 1st mask.');
+ NPMmsg('Error reading 1st mask.');
goto 666;
end;
lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
- MsgX('Mask file size too small.');
+ NPMmsg('Mask file size too small.');
goto 666;
end;
if (lPrefs.OutName = '') or (not DirExists(extractfiledir(lPrefs.Outname))) then begin
lPrefs.Outname := extractfiledir(lPrefs.ValFilename)+pathdelim+'results.nii.gz';
- MsgX('Output stored as '+lPrefs.Outname);
+ NPMmsg('Output stored as '+lPrefs.Outname);
end;
for lFact := 1 to lnFactors do begin
- ClearMsgX;
- MsgX(MainForm.GetKVers);
+ NPMMsgClear;
+ NPMMsg(GetKVers);
lImageNames.clear;
for lSubj := 1 to lnSubjAll do
if (not lPrefs.LTest) or (lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)] = 0) OR (lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)] = 1) THEN begin
{$IFNDEF FPC}if lMultiSymptomRA^[lSubj+((lFact-1)*lnSubjAll)] <> NaN then {$ENDIF}
lImageNames.Add(lImageNamesAll[lSubj-1]);
end else begin
- MsgX('Data rejected: behavior must be zero or one for binomial test '+lImageNamesAll.Strings[lSubj-1]);
+ NPMMsg('Data rejected: behavior must be zero or one for binomial test '+lImageNamesAll.Strings[lSubj-1]);
end;
lnSubj := lImageNames.Count;
if lnSubj > 2 then begin
@@ -120,27 +114,27 @@ begin
end; //valid value
end; //not binomial, or 1/0
end; //for each subject
- MsgX('Threads: '+inttostr(gnCPUThreads));
+ NPMMsg('Threads: '+inttostr(gnCPUThreads));
lFactName := lPredictorList.Strings[lFact-1];
lFactName := LegitFilename(lFactName,lFact);
- MsgX('Factor = '+lFactname);
+ NPMMsg('Factor = '+lFactname);
For lSubj := 1 to lnSubj do
- MsgX (lImageNames.Strings[lSubj-1] + ' = '+realtostr(lSymptomRA^[lSubj],2) );
- MsgX('Total voxels = '+inttostr(lMaskVoxels));
+ NPMMsg (lImageNames.Strings[lSubj-1] + ' = '+realtostr(lSymptomRA^[lSubj],2) );
+ NPMMsg('Total voxels = '+inttostr(lMaskVoxels));
lPrefs.nCrit := round( (lnSubj*lPrefs.CritPct)/100);
- MsgX('Only testing voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individual[s]');
- MsgX('Number of Lesion maps = '+inttostr(lnSubj));
+ NPMMsg('Only testing voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individual[s]');
+ NPMMsg('Number of Lesion maps = '+inttostr(lnSubj));
if not CheckVoxelsGroupX(lImageNames,lMaskHdr {lMaskVoxels}) then begin
- MsgX('Error: File dimensions differ from mask.');
+ NPMMsg('Error: File dimensions differ from mask.');
goto 666;
end;
if noVariance (lSymptomRA,lnSubj) then
- MsgX('Error no variability in behavioral data ')
+ NPMMsg('Error no variability in behavioral data ')
else
TurboLDM (lImageNames, lMaskHdr, lPrefs, lSymptomRA, lFactname,lPrefs.OutName);
Freemem(lSymptomRA);
end else begin
- MsgX('At least 2 individuals required to compute statistics for '+lPredictorList.Strings[lFact-1]);
+ NPMMsg('At least 2 individuals required to compute statistics for '+lPredictorList.Strings[lFact-1]);
end; //lnsubj > 2
end; //for each factor
if lnSubjAll > 0 then begin
@@ -153,17 +147,17 @@ begin
DeleteDecompressed4D(lTemp4D);
end;
-procedure ShowHelp;
+(*procedure ShowHelp;
begin
- MsgX('usage ''npm [options] -o resultsfilname valfilename'' ');
- MsgX(' Options ');
- MsgX(' -c: critical percent 0..100 ');
- MsgX(' -p: permutations 0..4000 ');
- MsgX(' -t: Test [1=Liebermeister, 2=TTest, 4=BMtest, 6=t&BMtests');
- MsgX(' -o: Output filename');
- MsgX('examples:');
- MsgX(' npm -c 25 -p 1000 -o c:\results.nii.gz c:\mri\data.val');
- MsgX(' npm -c 25 -o "c:\program files\results.hdr" c:\mri\data.val');
+ NPMMsg('usage ''npm [options] -o resultsfilname valfilename'' ');
+ NPMMsg(' Options ');
+ NPMMsg(' -c: critical percent 0..100 ');
+ NPMMsg(' -p: permutations 0..4000 ');
+ NPMMsg(' -t: Test [1=Liebermeister, 2=TTest, 4=BMtest, 6=t&BMtests');
+ NPMMsg(' -o: Output filename');
+ NPMMsg('examples:');
+ NPMMsg(' npm -c 25 -p 1000 -o c:\results.nii.gz c:\mri\data.val');
+ NPMMsg(' npm -c 25 -o "c:\program files\results.hdr" c:\mri\data.val');
end;
procedure ReadParamStr;
@@ -233,13 +227,13 @@ begin
lPrefs.ValFilename := lStr;
//if lPrefs.OutName = '' then
// lPrefs.Outname := extractfiledir(paramstr(0))+pathdelim+'results.nii.gz';
- MsgX ('output ' + lPrefs.Outname);
- MsgX ('val file: '+lPrefs.ValFilename);
+ NPMMsg ('output ' + lPrefs.Outname);
+ NPMMsg ('val file: '+lPrefs.ValFilename);
DoLesion(lPrefs);
- MainForm.close;
+ //MainForm.close;
end else begin
- MsgX('Error: unable to find '+lStr);
+ NPMMsg('Error: unable to find '+lStr);
if not lHelpShown then
Showhelp;
lHelpShown := true;
@@ -248,7 +242,7 @@ begin
end else begin
ShowHelp;
end;{param count > 0}
-end;
+end; *)
end.
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/npm/regression.pas b/npm/regression.pas
old mode 100644
new mode 100755
index 2b24f71..9e17564
--- a/npm/regression.pas
+++ b/npm/regression.pas
@@ -2,166 +2,26 @@ unit regression;
//only for Delphi - not Freepascal
//Unit for running multiple regression
interface
+{$Include ..\common\isgui.inc}
uses
{$H+}
+{$IFDEF GUI} Forms, {$ENDIF}
{$IFNDEF UNIX} Windows, {$ENDIF}
{$IFDEF FPC} utypes,regmult,{$ELSE}
utypes,regmult,
{$ENDIF}define_types,Classes,nifti_hdr,sysutils,nifti_img,
- StatThdsUtil,Forms,Distr,Dialogs,npmform;
+ StatThdsUtil,Distr,Dialogsx, tfce_clustering, unpm;
-function GetValReg (var lnSubj,lnFactors: integer; var X : PMatrix; var lImageNames: TStrings; var lPredictorList: TStringList): boolean;
-function ARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string): boolean;
-function Regress2NPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lOutname: string; var lXadditional: PMatrix; lnAdditionalFactors: integer ): boolean;
+function GetValReg (var lVALFilename: string; var lnSubj,lnFactors: integer; var X : PMatrix; var lImageNames: TStrings; var lPredictorList: TStringList): boolean;
+function ARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string; lnPermute, TFCEconn: integer): boolean;
+function Regress2NPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lOutname: string; var lXadditional: PMatrix; lnAdditionalFactors, lnPermute: integer ): boolean;
function TtoR(t,df: double): double;
implementation
uses valformat,hdr,math;
-(*function readCSV (lFilename: string; var lnObservations,lnFactors : integer; var X : PMatrix; var Y: PVector): boolean;
-var
- lNumStr: string;
- F: TextFile;
- lTempFloat: double;
- lCh: char;
- lPos,MaxC,R,C:integer;
- lError: boolean;
-
-begin
- result := false;
- if not fileexists(lFilename) then exit;
- AssignFile(F, lFilename);
- FileMode := 0; //Set file access to read only
- //First pass: determine column height/width
- Reset(F);
- C := 0;
- MaxC := 0;
- R := 0;
- while not Eof(F) do begin
- //read next line
- //read next line
- Read(F, lCh);
- if lCh = '#' then
- while not (lCh in [#10,#13]) do
- Read(F, lCh)
- else if not (lCh in [#10,#13,#9,',']) then begin
- lNumStr := lNumStr + lCh;
- end else if lNumStr <> '' then begin
- lNumStr := '';
- inc(C);
- if C > MaxC then
- MaxC := C;
- if (lCh in [#10,#13]) then begin
- C := 0;
- inc(R);
- end; //eoln
- end; //if lNumStr <> '' and not tab
- end;
- if lNumStr <> '' then //july06- read data immediately prior to EOF
- inc(R);
-
- if (R < 2) or (MaxC < 5) then begin
- showmessage('problems reading CSV');
- exit;
- end;
- lnObservations := MaxC;
- lnFactors := R -1;
- DimVector(Y, lnObservations);
- DimMatrix(X, lnFactors, lnObservations);
- //second pass
- Reset(F);
- C := 0;
- MaxC := 0;
- R := 1;
- lNumStr := '';
- while not Eof(F) do begin
- //read next line
- Read(F, lCh);
- if lCh = '#' then
- while not (lCh in [#10,#13]) do
- Read(F, lCh)
- else if not (lCh in [#10,#13,#9,',']) then begin
- lNumStr := lNumStr + lCh;
- end else if lNumStr <> '' then begin
- if lNumStr = '-' then begin
- lTempFloat := 0;
- end else begin //number
- try
- lTempFloat := strtofloat(lNumStr);
- except
- on EConvertError do begin
- if not lError then
- showmessage('Empty cells? Error reading VAL file row:'+inttostr(R)+' col:'+inttostr(C)+' - Unable to convert the string '+lNumStr+' to a number');
- lError := true;
- lTempFloat := nan;
- end;
- end;
- if R = 1 then
- Y^[C+1] := lTempFloat
- else
- X^[R-1]^[C+1] := lTempFloat;
- //xxx := lTempFloat;//DataGrid.Cells[ C, kMaxFactors+R-1 ] := (lNumStr) ;
- end;
- lNumStr := '';
- inc(C);
- if C > MaxC then
- MaxC := C;
- if (lCh in [#10,#13]) then begin
- C := 0;
- inc(R);
- end; //eoln
- end; //if lNumStr <> '' and not tab
- end;
- CloseFile(F);
- FileMode := 2; //Set file access to read/write
- result := true;
-end;
-
-function TestMultReg: boolean;
-var
-i,lnFactors, lnObservations: integer;
-X : PMatrix;
-Y: PVector;
-lOutT,lOutSlope: DoubleP0;
-lStart: dword;
-begin
- if not readCSV('C:\xio.csv',lnObservations,lnFactors,X,Y ) then exit;
- //showmessage('alpha');
- getmem(lOutT, (lnFactors+1)* sizeof(double));
- getmem(lOutSlope, (lnFactors+1)* sizeof(double));
- lStart := gettickcount;
- for i := 1 to 10000 do
- MultipleRegressionVec (lnObservations,lnFactors, X, Y, lOutT,lOutSlope);
- fx(gettickcount-lstart);
-
-
- if MultipleRegressionVec (lnObservations,lnFactors, X, Y, lOutT,lOutSlope) then begin
- for i := 0 to lnFactors do
- fx(lOutT^[i],lOutSlope^[i]);
-
- end;
- freemem(lOutT);
- freemem(lOutSlope);
- DelMatrix(X, lnFactors, lnObservations);
- DelVector(Y, lnObservations);
-end; *)
-
-(*procedure rx(lnObs,lnFactors: integer; X: PMatrix; lObs: Doublep0);
-var
- n,f: integer;
- str: string;
-begin
- for n := 1 to lnObs do begin
- str := floattostr(lObs^[n-1]);
- for f := 1 to lnFactors do
- str := str+','+floattostr(X^[f]^[n]);
-
- MainForm.NPMmsg(str);
- end;//each obs
- str := '----------';
-end;//proc RX*)
function Sign(value: double): double;
begin
@@ -185,7 +45,7 @@ end;
{$DEFINE SaveT} //if SaveT then t-score map will be saved
{$DEFINE SaveRnotZ} //if SaveRnotZ then r-value map will be saved, but not Z-score map
-function Regress2NPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lOutname: string; var lXadditional: PMatrix; lnAdditionalFactors: integer ): boolean;
+function Regress2NPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lOutname: string; var lXadditional: PMatrix; lnAdditionalFactors, lnPermute: integer ): boolean;
//lImages is list 1..N of 1st images followed by 1..N of corresponding control images
//example c1.img, c2.img,c3.img,e1.img,e2.img,e3.img
//lImages.Count must be even
@@ -206,7 +66,7 @@ var
lObs: Doublep0;
lStatHdr: TNIfTIhdr;
lFdata: file;
- lnPermute: integer;
+
lRanOrderp: pointer;
lRanOrder: Doublep0;
lZP: Pointer;
@@ -214,16 +74,15 @@ var
X : PMatrix;
begin
lnFactors := 1+lnAdditionalFactors;
- lnPermute := MainForm.ReadPermute;
if odd(lImages.Count) then begin
- showmessage('Regress2NPMAnalyze must be passed an even number of images: the first half of the list is the experimental images, followed by corresponding control images.');
+ ShowMsg('Regress2NPMAnalyze must be passed an even number of images: the first half of the list is the experimental images, followed by corresponding control images.');
exit;
end;
lnObservations := lImages.Count;
lnObservationsDiv2 := lImages.Count div 2;
lDF := lnObservationsDiv2-lnFactors-1;
if lDF < 1 then begin
- showmessage('Regress2NPMAnalyze: DF must be >0 (DF=[Num-Factors-1]) Num='+inttostr(lnObservationsDiv2)+' Factors='+inttostr(lnFactors) );
+ ShowMsg('Regress2NPMAnalyze: DF must be >0 (DF=[Num-Factors-1]) Num='+inttostr(lnObservationsDiv2)+' Factors='+inttostr(lnFactors) );
exit;
end;
DimMatrix(X, lnFactors, lnObservationsDiv2);
@@ -238,19 +97,19 @@ begin
end; //pos 2
end; //additional factros
//Memo1.Lines.Add('Permutations = ' +IntToStr(lnPermute));
- MainForm.Memo1.Lines.Add('Analysis began = ' +TimeToStr(Now));
+ NPMmsg('Analysis began = ' +TimeToStr(Now));
lTotalMemory := 0;
lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
if (lVolVox < 1) then goto 667;
lnStatFact := lnFactors + 1; //factors + overall model
if lnStatFact > (kMaxFact-1) then begin //-1 because factors + model
- MainForm.Memo1.Lines.Add('ERROR: Can not analyze more than = ' +inttostr(kMaxFact-1)+' factors');
+ NPMmsg('ERROR: Can not analyze more than = ' +inttostr(kMaxFact-1)+' factors');
goto 667;
end;
//load mask
getmem(lMaskImg,lVolVox*sizeof(single));
if not LoadImg(lMaskHdr.ImgFileName, lMaskImg, 1, lVolVox,round(gOffsetRA[0]),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
- MainForm.Memo1.Lines.Add('Unable to load mask ' +lMaskHdr.ImgFileName);
+ NPMmsg('Unable to load mask ' +lMaskHdr.ImgFileName);
goto 667;
end;
//next find start and end of mask
@@ -265,17 +124,17 @@ begin
until (lMaskImg^[lPos] > 0) or (lPos = 1);
lMaxMask := lPos;
if lMaxMask = 1 then begin
- MainForm.Memo1.Lines.Add('Mask appears empty' +lMaskHdr.ImgFileName);
+ NPMmsg('Mask appears empty' +lMaskHdr.ImgFileName);
goto 667;
end;
- MainForm.Memo1.Lines.Add('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
+ NPMmsg('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
lVoxPerPlank := kPlankSz div lnObservations div sizeof(single) ;
if (lVoxPerPlank = 0) then goto 667; //no data
lTotalMemory := ((lMaxMask+1)-lMinMask) * lnObservations;
if (lTotalMemory = 0) then goto 667; //no data
lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lnObservations) ) + 1;
- MainForm.Memo1.Lines.Add('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lnObservations)));
- MainForm.Memo1.Lines.Add('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
+ NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lnObservations)));
+ NPMmsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
if (lnPlanks = 1) then
getmem(lPlankImg,lTotalMemory*sizeof(single)) //assumes 4bpp
else
@@ -299,8 +158,8 @@ begin
createArray64(lZp,lZra,lnFactors+1); //+1 as we include full model
//InitPermute (lImages.Count, lnPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxTW, lPermuteMinTW,lPermuteMaxWMW, lPermuteMinWMW, lRanOrderp, lRanOrder);
for lPlank := 1 to lnPlanks do begin
- MainForm.Memo1.Lines.Add('Computing plank = ' +Inttostr(lPlank));
- MainForm.Refresh;
+ NPMmsg('Computing plank = ' +Inttostr(lPlank));
+ Refresher;
lEndVox := lEndVox + lVoxPerPlank;
if lEndVox > lMaxMask then begin
lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
@@ -315,8 +174,7 @@ begin
lPosPct := lVoxPerPlank div 100;
for lPos2 := 1 to lVoxPerPlank do begin
if (lPos2 mod lPosPct) = 0 then begin
- MainForm.ProgressBar1.Position := round((lPos2/lVoxPerPlank)*100);
- Application.Processmessages;
+ NPMProgressBar( round((lPos2/lVoxPerPlank)*100) );
end;
lPos2Offset := lPos2+lStartVox-1;
if lMaskImg^[lPos2Offset] <> 0 then begin
@@ -348,8 +206,8 @@ begin
lStartVox := lEndVox + 1;
end;
//next report findings
- MainForm.Memo1.Lines.Add('Voxels tested = ' +Inttostr(lnVoxTested));
- MainForm.reportBonferroni('Std',lnVoxTested);
+ NPMMsg('Voxels tested = ' +Inttostr(lnVoxTested));
+ reportBonferroni('Std',lnVoxTested);
//next: save data
if lnFactors = 1 then
lRunName := 'reg'
@@ -401,24 +259,25 @@ begin
freemem(lObsp);
freemem(lMaskImg);
freemem(lPlankImg);
- MainForm.Memo1.Lines.Add('Analysis finished = ' +TimeToStr(Now));
+ NPMmsg('Analysis finished = ' +TimeToStr(Now));
lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes'+lRunName,'.txt');
- MainForm.Memo1.Lines.SaveToFile(lOutNameMod);
- MainForm.ProgressBar1.Position := 0;
+ NPMMsgSave(lOutNameMod);
+ NPMProgressBar(0);
DelMatrix(X, lnFactors, lnObservationsDiv2);
exit;
667: //you only get here if you aborted ... free memory and report error
DelMatrix(X, 1, lnObservationsDiv2);
if lVolVox > 1 then freemem(lMaskImg);
if lTotalMemory > 1 then freemem(lPlankImg);
- MainForm.Memo1.Lines.Add('Unable to complete analysis.');
- MainForm.ProgressBar1.Position := 0;
+ NPMmsg('Unable to complete analysis.');
+ NPMProgressBar(0);
end;
{$DEFINE NoThread}
-function ARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string): boolean;
+function InnerARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string; lSaveData: boolean; var lMinZ,lMaxZ: double; var lMaxNegTFCEZ, lMaxTFCEZ:single; TFCEconn: integer): boolean;
+//TFCEmode 0 = no TFCE, 1 = only report min/maxTFCE, 2 = save TFCE map to disk
{$IFNDEF Thread}
const
kMaxFact = 80;
@@ -453,27 +312,30 @@ var
{$ENDIF}
begin
+
+
lnObservations := lImages.Count;
lDF := lnObservations-lnFactors-1;
if lDF < 1 then begin
- showmessage('Regress2NPMAnalyze: DF must be >0 (DF=[Num-Factors-1]) Num='+inttostr(lnObservations)+' Factors='+inttostr(lnFactors) );
+ ShowMsg('Regress2NPMAnalyze: DF must be >0 (DF=[Num-Factors-1]) Num='+inttostr(lnObservations)+' Factors='+inttostr(lnFactors) );
exit;
end;
- MainForm.NPMmsg('Analysis began = ' +TimeToStr(Now));
+ if (lSaveData) then NPMmsg('Analysis began = ' +TimeToStr(Now));
lTotalMemory := 0;
lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
if (lVolVox < 1) then goto 667;
lnStatFact := lnFactors + 1; //factors + overall model
if lnStatFact > (kMaxFact-1) then begin //-1 because factors + model
- MainForm.NPMmsg('ERROR: Can not analyze more than = ' +inttostr(kMaxFact-1)+' factors');
+ NPMmsg('ERROR: Can not analyze more than = ' +inttostr(kMaxFact-1)+' factors');
goto 667;
end;
//load mask
getmem(lMaskImg,lVolVox*sizeof(single));
if not LoadImg(lMaskHdr.ImgFileName, lMaskImg, 1, lVolVox,round(gOffsetRA[0]),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
- MainForm.NPMmsg('Unable to load mask ' +lMaskHdr.ImgFileName);
+ NPMmsg('Unable to load mask ' +lMaskHdr.ImgFileName);
goto 667;
end;
+
//next find start and end of mask
lPos := 0;
repeat
@@ -486,17 +348,17 @@ begin
until (lMaskImg^[lPos] > 0) or (lPos = 1);
lMaxMask := lPos;
if lMaxMask = 1 then begin
- MainForm.NPMmsg('Mask appears empty' +lMaskHdr.ImgFileName);
+ NPMmsg('Mask appears empty' +lMaskHdr.ImgFileName);
goto 667;
end;
- MainForm.NPMmsg('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
+ if (lSaveData) then NPMmsg('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
lVoxPerPlank := kPlankSz div lnObservations div sizeof(single) ;
if (lVoxPerPlank = 0) then goto 667; //no data
lTotalMemory := ((lMaxMask+1)-lMinMask) * lnObservations;
if (lTotalMemory = 0) then goto 667; //no data
lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lnObservations) ) + 1;
- MainForm.NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lnObservations)));
- MainForm.NPMmsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
+ if (lSaveData) then NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lnObservations)));
+ if (lSaveData) then NPMmsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
if (lnPlanks = 1) then
getmem(lPlankImg,lTotalMemory* sizeof(single)) //assumes 4bpp
else
@@ -524,8 +386,8 @@ begin
lnVoxTested := 0;
{$ENDIF}
for lPlank := 1 to lnPlanks do begin
- MainForm.NPMmsg('Computing plank = ' +Inttostr(lPlank));
- MainForm.Refresh;
+ if (lSaveData) then NPMmsg('Computing plank = ' +Inttostr(lPlank));
+ Refresher;
lEndVox := lEndVox + lVoxPerPlank;
if lEndVox > lMaxMask then begin
lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
@@ -562,8 +424,7 @@ begin
lPosPct := lVoxPerPlank div 100;
for lPos2 := 1 to lVoxPerPlank do begin
if (lPos2 mod lPosPct) = 0 then begin
- MainForm.ProgressBar1.Position := round((lPos2/lVoxPerPlank)*100);
- Application.Processmessages;
+ NPMProgressBar(round((lPos2/lVoxPerPlank)*100));
end;
lPos2Offset := lPos2+lStartVox-1;
if lMaskImg^[lPos2Offset] <> 0 then begin
@@ -580,7 +441,7 @@ begin
lVar := true;
end;
lOutImgMn^[lPos2Offset] := lSum/lnObservations;
- if {lPos2Offset = 762287 }lVar then begin
+ if lVar then begin
MultipleRegression (lnObservations,lnFactors, X, lObs, lZra);
//if {lZra^[0] < -5.548} lPos2Offset = 762287 then
// ReportRegression (lPos2Offset,lnObservations,lnFactors, X, lObs, lZra );
@@ -597,9 +458,22 @@ begin
{$IFDEF Thread}
lnVoxTested := SumThreadDataLite(gnCPUThreads);
{$ENDIF}
+ //FACTOR 1 MinMax
+ lFact := 1;
+ lMinZ := lOutImgR[lFact]^[1];
+ for lPos := 1 to lVolVox do
+ if (lOutImgR[lFact]^[lPos] < lMinZ) then lMinZ :=lOutImgR[lFact]^[lPos];
+ lMinZ := TtoZ (lMinZ,lDF);
+ lMaxZ := lOutImgR[lFact]^[1];
+ for lPos := 1 to lVolVox do
+ if (lOutImgR[lFact]^[lPos] > lMaxZ) then lMaxZ :=lOutImgR[lFact]^[lPos];
+ lMaxZ := TtoZ (lMaxZ,lDF);
+ //NPMmsg('Factor1MinMax ' +floattostr(lMinZ)+' '+floattostr(lMaxZ));
+
+ if (lSaveData) then begin
//next report findings
- MainForm.NPMmsg('Voxels tested = ' +Inttostr(lnVoxTested));
- MainForm.reportBonferroni('Std',lnVoxTested);
+ NPMmsg('Voxels tested = ' +Inttostr(lnVoxTested));
+ reportBonferroni('Std',lnVoxTested);
//next: save data
if lnFactors = 1 then
lRunName := lPredictorList[0]
@@ -608,6 +482,9 @@ begin
//savedata
MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
+
+
+
//save mean
lOutNameMod := ChangeFilePostfixExt(lOutName,'Mean'+lRunName,'.hdr');
if not FileExistsEX(lOutNameMod) then
@@ -634,33 +511,123 @@ begin
//{ DoF = Nb points - Nb parameters }
for lPos := 1 to lVolVox do
lOutImgR[lFact]^[lPos] := TtoZ (lOutImgR[lFact]^[lPos],lDF);
- MainForm.reportFDR ('wls'+lFactName, lVolVox, lnVoxTested, lOutImgR[lFact]);
+ reportFDR ('wls'+lFactName, lVolVox, lnVoxTested, lOutImgR[lFact]);
lOutNameMod := ChangeFilePostfixExt(lOutName, 'wls'+lFactName,'.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgR[lFact],1);
- freemem(lOutImgR[lFact]);
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgR[lFact],1);
+ if (lFact = 1) and (TFCEconn > 0) then begin //TFCE
+ //lMinZ := lOutImgR[lFact]^[1];
+
+ MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,lDF,0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
+ doTFCEbothPolarities (lStatHdr, lOutImgR[lFact], TFCEconn {NumConn}, 2.0{H}, 0.5 {E}, 0, lMaxZ/100, 0, lMinZ/100, lMaxTFCEZ, lMaxNegTFCEZ);
+ lOutNameMod := ChangeFilePostfixExt(lOutName, 'tfce'+lFactName,'.hdr');
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgR[lFact],1);
+ end; //TFCE
+
end;//if..else intercept and lnFactors = 1
end;//for each statfactor
+ end; //if lSaveData
+
+
+ if (not (lSaveData)) and (TFCEconn > 0) and ((lMaxTFCEZ <> 0) or (lMaxNegTFCEZ <> 0)) then begin
+ //lMinZ := lOutImgR[lFact]^[1];
+ lFact := 1;
+ MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,lDF,0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
+ doTFCEbothPolarities (lStatHdr, lOutImgR[lFact], TFCEconn {NumConn}, 2.0{H}, 0.5 {E}, 0, lMaxTFCEZ, 0, lMaxNegTFCEZ, lMaxTFCEZ, lMaxNegTFCEZ)
+
+ end; //xxx
//next: close images
+ for lFact := 1 to (lnStatFact) do
+ freemem(lOutImgR[lFact]);
+
//Freemem(lZp);
freemem(lOutImgMn);
//freemem(lObsp);
freemem(lMaskImg);
freemem(lPlankImg);
- MainForm.NPMmsg('Analysis finished = ' +TimeToStr(Now));
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes'+lRunName,'.txt');
- MainForm.MsgSave(lOutNameMod);
- MainForm.ProgressBar1.Position := 0;
+
+ //lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes'+lRunName,'.txt');
+ //MainForm.MsgSave(lOutNameMod);
+ NPMProgressBar(0);
exit;
667: //you only get here if you aborted ... free memory and report error
if lVolVox > 1 then freemem(lMaskImg);
if lTotalMemory > 1 then freemem(lPlankImg);
- MainForm.NPMmsg('Unable to complete analysis.');
- MainForm.ProgressBar1.Position := 0;
+ NPMmsg('Unable to complete analysis.');
+ NPMProgressBar(0);
+end;
+
+procedure PermuteMatrix(var Src, Dest: PMatrix; lnSubj: integer); //assumes only one column/factor!!!
+var
+ lRow,lPos: integer;
+ lSwap: double;
+begin
+ for lRow := 1 to lnSubj do
+ Dest^[1]^[lRow] := Src^[1]^[lRow];
+ for lRow := lnSubj downto 1 do begin
+ lPos := random(lRow)+1;
+ lSwap := Dest^[1]^[lRow];
+ Dest^[1]^[lRow] := Dest^[1]^[lPos];
+ Dest^[1]^[lPos] := lSwap;
+ end;
+
end;
-function GetValReg (var lnSubj,lnFactors: integer; var X : PMatrix; var lImageNames: TStrings; var lPredictorList: TStringList): boolean;
+function ARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string; lnPermute, TFCEconn: integer ): boolean;
+label
+ 777;
var
- lVALFilename,lTemplateName: string;
+ //SaveData: boolean; var
+ lMaxTFCEZ, lMaxNegTFCEZ: single;
+ lMinZ,lMaxZ,lTFCEdh,lNegTFCEdh:double;
+ Xp : PMatrix;
+ lp,lnSubj,lRow : integer;
+ lPermuteMaxZ, lPermuteMinZ,lPermuteMaxTFCEZ, lPermuteMinTFCEZ: singleP;
+begin
+ InnerARegressNPMAnalyze (lImages, lMaskHdr, X, lnFactors, lPredictorList, lOutname, TRUE,lMinZ,lMaxZ, lMaxNegTFCEZ, lMaxTFCEZ, TFCEconn );
+ if lnFactors > 1 then goto 777;
+ if (lnPermute < 1) then goto 777;
+ //NPMmsg('0 ObservedzMinMax ' +floattostr(lMinZ)+' '+floattostr(lMaxZ));
+ NPMmsg('OBSERVED Factor1 zMin zMax zMinTFCE zMaxTFCE ' +floattostr(lMinZ)+' '+floattostr(lMaxZ) +' ' +floattostr(lMaxNegTFCEZ)+' '+floattostr(lMaxTFCEZ));
+
+ lnSubj := lImages.Count;
+ DimMatrix(Xp, lnFactors, lnSubj);
+ randomize;
+ getmem(lPermuteMaxZ,lnPermute* sizeof(single));
+ getmem(lPermuteMinZ,lnPermute* sizeof(single));
+ getmem(lPermuteMaxTFCEZ,lnPermute* sizeof(single));
+ getmem(lPermuteMinTFCEZ,lnPermute* sizeof(single));
+ lTFCEdh := lMaxZ / 100;
+ lNegTFCEdh := abs(lMinZ) / 100;
+ for lp := 1 to lnPermute do begin
+ //for lRow := 1 to lnSubj do
+ // Xp^[1]^[lRow] := X^[1]^[lRow];
+ lMaxNegTFCEZ := lNegTFCEdh;
+ lMaxTFCEZ := lTFCEdh;
+ PermuteMatrix(X,Xp,lnSubj);
+
+ InnerARegressNPMAnalyze (lImages, lMaskHdr, Xp, lnFactors, lPredictorList, lOutname, FALSE,lMinZ,lMaxZ,lMaxNegTFCEZ, lMaxTFCEZ, TFCEconn);
+ NPMmsg(inttostr(lp)+' Factor1 zMin zMax zMinTFCE zMaxTFCE ' +floattostr(lMinZ)+' '+floattostr(lMaxZ) +' ' +floattostr(lMaxNegTFCEZ)+' '+floattostr(lMaxTFCEZ));
+ lPermuteMaxZ^[lp] := lMaxZ;
+ lPermuteMinZ^[lp] := lMinZ;
+ lPermuteMaxTFCEZ^[lp] := lMaxTFCEZ;
+ lPermuteMinTFCEZ^[lp] := lMaxNegTFCEZ;
+ end;
+ DelMatrix(Xp, lnFactors, lnSubj);
+ reportPermute ('Permutation', lnPermute, lPermuteMaxZ, lPermuteMinZ);
+ reportPermute ('TFCEPermutation', lnPermute, lPermuteMaxTFCEZ, lPermuteMinTFCEZ);
+ Freemem(lPermuteMaxZ);
+ Freemem(lPermuteMinZ);
+ Freemem(lPermuteMaxTFCEZ);
+ Freemem(lPermuteMinTFCEZ);
+ 777:
+ NPMmsg('Analysis finished = ' +TimeToStr(Now));
+ NPMMsgSave( ChangeFilePostfixExt(lOutName,'Notes','.txt'));
+
+end;
+
+function GetValReg (var lVALFilename: string; var lnSubj,lnFactors: integer; var X : PMatrix; var lImageNames: TStrings; var lPredictorList: TStringList): boolean;
+var
+ lTemplateName: string;
lnRow,lnColWObs,lnCritPct,lInc,lRow,lCol: integer;
lDesignUnspecified : boolean;
lFileList:TStringList;
@@ -668,13 +635,14 @@ var
lInP: Pointer;
begin
result := false;
+
lnSubj := 0;
- if not MainForm.OpenDialogExecute('Select MRIcron VAL file',false,false,'MRIcron VAL (*.val)|*.val') then begin
- showmessage('NPM aborted: VAL file selection failed.');
+ if not FileExistsEX(lVALFilename) then begin
+ ShowMsg('NPM aborted: VAL file selection failed.');
exit;
end; //if not selected
- lVALFilename := MainForm.OpenHdrDlg.Filename;
- MainForm.Memo1.Lines.Add( 'VAL filename: '+lVALFilename);
+
+ NPMmsg( 'VAL filename: '+lVALFilename);
lFileList := TStringList.Create;
if not OpenValFile (lVALFilename,lTemplateName, lnRow,lnFactors,lnColWObs,lnCritPct,
@@ -691,11 +659,11 @@ begin
DimMatrix(X, lnFactors, lnSubj);
for lCol := 1 to lnFactors do begin
for lRow := 1 to lnSubj do begin
- //MainForm.Memo1.Lines.Add(inttostr( (lRow*lnColWObsAndCovary)-4+lCol ));
+ //NPMmsg(inttostr( (lRow*lnColWObsAndCovary)-4+lCol ));
X^[lCol]^[lRow] := lInRA^[(lRow*lnColWObs)-lnColWObs-1+lCol];
end;
end;
- MainForm.Memo1.Lines.Add(inttostr(lnFactors)+' '+inttostr(lnSubj));
+ NPMmsg(inttostr(lnFactors)+' '+inttostr(lnSubj));
for lInc := 1 to lnSubj do
lImageNames.add(ExtractFileDirWithPathDelim(lVALFilename)+lFileList.Strings[lInc-1]);
result := true;
@@ -706,4 +674,4 @@ begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/npm/results.niiNotesseverity.txt b/npm/results.niiNotesseverity.txt
old mode 100644
new mode 100755
diff --git a/npm/roc.pas b/npm/roc.pas
old mode 100644
new mode 100755
index 4b5a309..05de27f
--- a/npm/roc.pas
+++ b/npm/roc.pas
@@ -4,7 +4,7 @@ interface
uses
define_types,SysUtils,
part,StatThds,statcr,StatThdsUtil,Brunner,//Brunner,nifti_img, DISTR
- Messages, Classes, Graphics, Controls, Forms, Dialogs,
+ Messages, Classes, Graphics, Controls, Forms, Dialogsx,
StdCtrls, ComCtrls,ExtCtrls,Menus, //overlap,ReadInt,stats,LesionStatThds,nifti_hdr,
{$IFDEF FPC} LResources,gzio2,
@@ -36,7 +36,7 @@ begin
lError := false;
result := false;
if not fileexists(lFilename) then begin
- showmessage('Can not find '+lFilename);
+ ShowMsg('Can not find '+lFilename);
exit;
end;
AssignFile(F, lFilename);
@@ -71,7 +71,7 @@ begin
inc(R);
if (R <= (kHdrRow+1)) or (MaxC < (kHdrCol+lCol1)) or (MaxC < (kHdrCol+lCol2)) then begin
- showmessage('problems reading CSV - not enough columns/rows '+inttostr(lCol1)+' '+inttostr(lCol2));
+ ShowMsg('problems reading CSV - not enough columns/rows '+inttostr(lCol1)+' '+inttostr(lCol2));
exit;
end;
@@ -109,7 +109,7 @@ begin
except
on EConvertError do begin
if not lError then
- showmessage('Empty cells? Error reading CSV file row:'+inttostr(R)+' col:'+inttostr(C)+' - Unable to convert the string '+lNumStr+' to a number');
+ ShowMsg('Empty cells? Error reading CSV file row:'+inttostr(R)+' col:'+inttostr(C)+' - Unable to convert the string '+lNumStr+' to a number');
lError := true;
lTempFloat := nan;
end;
@@ -139,7 +139,7 @@ begin
except
on EConvertError do begin
if not lError then
- showmessage('Empty cells? Error reading CSV file row:'+inttostr(R)+' col:'+inttostr(C)+' - Unable to convert the string '+lNumStr+' to a number');
+ ShowMsg('Empty cells? Error reading CSV file row:'+inttostr(R)+' col:'+inttostr(C)+' - Unable to convert the string '+lNumStr+' to a number');
lError := true;
lTempFloat := nan;
end;
@@ -227,7 +227,7 @@ begin
exit;
npmform.MainForm.memo1.lines.add(' ...observations: '+inttostr(lnObservations));
if lnObservations < 3 then begin
- showmessage('At least 3 subjects required.');
+ ShowMsg('At least 3 subjects required.');
exit;
end;
lnSubj := lnObservations;
@@ -237,7 +237,7 @@ begin
inc (lnGroup0);
npmform.MainForm.memo1.lines.add(' ...observations with deficit [0]: '+inttostr(lnGroup0));
if (lnGroup0 = lnSubj) or (lnGroup0 = 0) then begin
- showmessage('Some values in the first column must be zero, some must be non-zero.');
+ ShowMsg('Some values in the first column must be zero, some must be non-zero.');
exit;
end;
lROC := AUCbinomcont (ldatara1,ldatara2, lnSubj);
@@ -299,7 +299,7 @@ begin
exit;
npmform.MainForm.memo1.lines.add(' ...observations: '+inttostr(lnObservations));
if lnObservations < 3 then begin
- showmessage('At least 3 subjects required.');
+ ShowMsg('At least 3 subjects required.');
exit;
end;
lnSubj := lnObservations;
@@ -309,7 +309,7 @@ begin
if ldatara1^[lI] <> lF then
lVariable := true;
if (not lVariable) then begin
- showmessage('The columns must have some variability.');
+ ShowMsg('The columns must have some variability.');
exit;
end;
Getmem(lIn,lnSubj*sizeof(double));
@@ -352,4 +352,4 @@ begin
end; *)
-end.
+end.
\ No newline at end of file
diff --git a/npm/spread.dfm b/npm/spread.dfm
old mode 100644
new mode 100755
index de192fa..f7aaee9
Binary files a/npm/spread.dfm and b/npm/spread.dfm differ
diff --git a/npm/spread.lfm b/npm/spread.lfm
old mode 100644
new mode 100755
index 2f04966..224dbf7
--- a/npm/spread.lfm
+++ b/npm/spread.lfm
@@ -5,7 +5,7 @@ object SpreadForm: TSpreadForm
Width = 326
ActiveControl = DataGrid
Caption = 'Voxelwise Analysis of Lesions'
- ClientHeight = 513
+ ClientHeight = 538
ClientWidth = 326
Font.Name = 'MS Sans Serif'
Menu = MainMenu1
@@ -13,10 +13,10 @@ object SpreadForm: TSpreadForm
OnCreate = FormCreate
OnResize = FormResize
Position = poScreenCenter
- LCLVersion = '0.9.28.2'
+ LCLVersion = '0.9.30.2'
object DataGrid: TStringGrid
Left = 0
- Height = 467
+ Height = 498
Top = 25
Width = 326
Align = alClient
@@ -45,7 +45,6 @@ object SpreadForm: TSpreadForm
Top = 0
Width = 120
Caption = 'Design'
- Color = clBtnFace
Glyph.Data = {
76010000424D7601000000000000760000002800000020000000100000000100
0400000000000001000000000000000000001000000010000000000000000000
@@ -68,8 +67,8 @@ object SpreadForm: TSpreadForm
end
object StatusBar1: TStatusBar
Left = 0
- Height = 21
- Top = 492
+ Height = 15
+ Top = 523
Width = 326
Panels = <
item
diff --git a/npm/spread.lrs b/npm/spread.lrs
old mode 100644
new mode 100755
index c9f625c..cf9ecb9
--- a/npm/spread.lrs
+++ b/npm/spread.lrs
@@ -1,66 +1,66 @@
{ This is an automatically generated lazarus resource file }
-
-LazarusResources.Add('TSpreadForm','FORMDATA',[
- 'TPF0'#11'TSpreadForm'#10'SpreadForm'#4'Left'#3#145#1#6'Height'#3#26#2#3'Top'
- +#3#183#0#5'Width'#3'F'#1#13'ActiveControl'#7#8'DataGrid'#7'Caption'#6#29'Vox'
- +'elwise Analysis of Lesions'#12'ClientHeight'#3#1#2#11'ClientWidth'#3'F'#1#9
- +'Font.Name'#6#13'MS Sans Serif'#4'Menu'#7#9'MainMenu1'#7'OnClose'#7#9'FormCl'
- +'ose'#8'OnCreate'#7#10'FormCreate'#8'OnResize'#7#10'FormResize'#8'Position'#7
- +#14'poScreenCenter'#10'LCLVersion'#6#8'0.9.28.2'#0#11'TStringGrid'#8'DataGri'
- +'d'#4'Left'#2#0#6'Height'#3#211#1#3'Top'#2#25#5'Width'#3'F'#1#5'Align'#7#8'a'
- +'lClient'#9'FixedRows'#2#2#7'Options'#11#15'goFixedVertLine'#10'goVertLine'
- +#10'goHorzLine'#13'goRangeSelect'#19'goDrawFocusSelected'#6'goTabs'#15'goThu'
- +'mbTracking'#0#8'RowCount'#2#12#8'TabOrder'#2#0#14'TitleFont.Name'#6#13'MS S'
- +'ans Serif'#10'OnDrawCell'#7#16'DataGridDrawCell'#10'OnKeyPress'#7#16'DataGr'
- +'idKeyPress'#11'OnMouseDown'#7#17'DataGridMouseDown'#11'OnMouseMove'#7#17'Da'
- +'taGridMouseMove'#12'OnSelectCell'#7#18'DataGridSelectCell'#0#0#8'TToolBar'#8
- +'ToolBar1'#4'Left'#2#0#6'Height'#2#25#3'Top'#2#0#5'Width'#3'F'#1#11'EdgeBord'
- +'ers'#11#0#8'TabOrder'#2#1#0#12'TSpeedButton'#9'DesignBtn'#4'Left'#2#1#6'Hei'
- +'ght'#2#22#4'Hint'#6#5'ANOVA'#3'Top'#2#0#5'Width'#2'x'#7'Caption'#6#6'Design'
- +#5'Color'#7#9'clBtnFace'#10'Glyph.Data'#10'z'#1#0#0'v'#1#0#0'BMv'#1#0#0#0#0#0
- +#0'v'#0#0#0'('#0#0#0' '#0#0#0#16#0#0#0#1#0#4#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#0
- +#0#16#0#0#0#16#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128#0#128#0#0#0#128#0
- +#128#0#128#128#0#0#127#127#127#0#191#191#191#0#0#0#255#0#0#255#0#0#0#255#255
- +#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0'3s3s3s3s3'#127'?'#127'?'
- +#127'?'#127'3sssssss?'#127#127#127#127#127#127#127'w'#0#0#0#0#0#0#0'wwwwwwww'
- +'3'#3'33<3333'#127#255'37'#243'3?7'#9#147'3<33'#153'7ws'#243'7'#243'3w3'#3'9'
- +'3<393?'#127#247#255#247#255#247#255'w'#7'w'#151'|w'#151'wwwwwwwww3'#3'3'#147
- +'<3'#147'33'#127'3s'#247#243's37'#3'39<9337'#127'377'#247'333'#3'33'#153#147
- +'33?'#127#255#255'w'#127#255#255'w'#7'ww|wwwwwwwwwww3'#3'33<3'#3'33'#127'337'
- +#255#127#243'7'#3'33<'#0#0'<7'#127'337ww73'#3'33<3'#3'3?'#127#255#255#247#255
- +#127#255'w'#7'wwwwwwwwwwwwww3333333333333333'#9'NumGlyphs'#2#2#7'OnClick'#7
- +#14'DesignBtnClick'#8'ShowHint'#9#14'ParentShowHint'#8#0#0#0#10'TStatusBar'
- +#10'StatusBar1'#4'Left'#2#0#6'Height'#2#21#3'Top'#3#236#1#5'Width'#3'F'#1#6
- +'Panels'#14#1#5'Width'#3#140#0#0#1#5'Width'#2'2'#0#0#11'SimplePanel'#8#0#0#9
- +'TMainMenu'#9'MainMenu1'#4'left'#2'l'#3'top'#2','#0#9'TMenuItem'#5'File1'#7
- +'Caption'#6#5'&File'#0#9'TMenuItem'#4'New1'#7'Caption'#6#6'New...'#8'ShortCu'
- +'t'#3'N@'#7'OnClick'#7#11'NewBtnClick'#0#0#9'TMenuItem'#5'Open1'#7'Caption'#6
- +#7'Open...'#8'ShortCut'#3'O@'#7'OnClick'#7#12'OpenBtnClick'#0#0#9'TMenuItem'
- +#5'Save1'#7'Caption'#6#4'Save'#8'ShortCut'#3'S@'#7'OnClick'#7#12'SaveBtnClic'
- +'k'#0#0#9'TMenuItem'#5'Quit1'#7'Caption'#6#12'Close window'#8'ShortCut'#3'W@'
- +#7'OnClick'#7#10'Quit1Click'#0#0#0#9'TMenuItem'#5'Edit1'#7'Caption'#6#4'Edit'
- +#0#9'TMenuItem'#5'Copy1'#7'Caption'#6#4'Copy'#8'ShortCut'#3'C@'#7'OnClick'#7
- +#10'Copy1Click'#0#0#9'TMenuItem'#6'Paste1'#7'Caption'#6#5'Paste'#8'ShortCut'
- +#3'V@'#7'OnClick'#7#11'Paste1Click'#0#0#9'TMenuItem'#10'Selectall1'#7'Captio'
- +'n'#6#16'Select all cells'#8'ShortCut'#3'A@'#7'OnClick'#7#15'Selectall1Click'
- +#0#0#9'TMenuItem'#14'Clearallcells1'#7'Caption'#6#18'Clear all cells...'#7'O'
- +'nClick'#7#19'Clearallcells1Click'#0#0#9'TMenuItem'#15'DescriptiveMenu'#7'Ca'
- +'ption'#6#12'Descriptives'#7'OnClick'#7#16'DescriptiveClick'#0#0#0#9'TMenuIt'
- +'em'#4'View'#7'Caption'#6#4'View'#0#9'TMenuItem'#5'Font1'#7'Caption'#6#4'Fon'
- +'t'#0#9'TMenuItem'#3'N81'#3'Tag'#2#8#7'Caption'#6#1'8'#7'Checked'#9#10'Group'
- +'Index'#2'o'#9'RadioItem'#9#7'OnClick'#7#14'FontSizeChange'#0#0#9'TMenuItem'
- +#4'N101'#3'Tag'#2#10#7'Caption'#6#2'10'#10'GroupIndex'#2'o'#9'RadioItem'#9#7
- +'OnClick'#7#14'FontSizeChange'#0#0#9'TMenuItem'#4'N121'#3'Tag'#2#12#7'Captio'
- +'n'#6#2'12'#10'GroupIndex'#2'o'#9'RadioItem'#9#7'OnClick'#7#14'FontSizeChang'
- +'e'#0#0#9'TMenuItem'#4'N141'#3'Tag'#2#14#7'Caption'#6#2'14'#10'GroupIndex'#2
- +'o'#9'RadioItem'#9#7'OnClick'#7#14'FontSizeChange'#0#0#0#9'TMenuItem'#7'Desi'
- +'gn1'#7'Caption'#6#6'Design'#8'ShortCut'#3'D@'#7'OnClick'#7#14'DesignBtnClic'
- +'k'#0#0#0#9'TMenuItem'#5'Help1'#7'Caption'#6#5'&Help'#0#9'TMenuItem'#18'Abou'
- +'tthissoftware1'#7'Caption'#6#20'&About this software'#7'OnClick'#7#23'About'
- +'thissoftware1Click'#0#0#0#0#11'TOpenDialog'#11'OpenDialog1'#10'DefaultExt'#6
- +#4'.val'#6'Filter'#6'<Native [val]|.val|Tab delimited text [txt]|.txt|All fi'
- +'les|.*'#11'FilterIndex'#2#0#4'left'#2'$'#3'top'#2','#0#0#11'TSaveDialog'#11
- +'SaveDialog1'#10'DefaultExt'#6#4'.val'#6'Filter'#6'8Native format [val]|*.va'
- +'l|Tab delimited text [txt]|*.txt'#11'FilterIndex'#2#0#7'Options'#11#17'ofOv'
- +'erwritePrompt'#14'ofHideReadOnly'#0#4'left'#2'J'#3'top'#2','#0#0#0
-]);
+
+LazarusResources.Add('TSpreadForm','FORMDATA',[
+ 'TPF0'#11'TSpreadForm'#10'SpreadForm'#4'Left'#3#145#1#6'Height'#3#26#2#3'Top'
+ +#3#183#0#5'Width'#3'F'#1#13'ActiveControl'#7#8'DataGrid'#7'Caption'#6#29'Vox'
+ +'elwise Analysis of Lesions'#12'ClientHeight'#3#26#2#11'ClientWidth'#3'F'#1#9
+ +'Font.Name'#6#13'MS Sans Serif'#4'Menu'#7#9'MainMenu1'#7'OnClose'#7#9'FormCl'
+ +'ose'#8'OnCreate'#7#10'FormCreate'#8'OnResize'#7#10'FormResize'#8'Position'#7
+ +#14'poScreenCenter'#10'LCLVersion'#6#8'0.9.30.2'#0#11'TStringGrid'#8'DataGri'
+ +'d'#4'Left'#2#0#6'Height'#3#242#1#3'Top'#2#25#5'Width'#3'F'#1#5'Align'#7#8'a'
+ +'lClient'#9'FixedRows'#2#2#7'Options'#11#15'goFixedVertLine'#10'goVertLine'
+ +#10'goHorzLine'#13'goRangeSelect'#19'goDrawFocusSelected'#6'goTabs'#15'goThu'
+ +'mbTracking'#0#8'RowCount'#2#12#8'TabOrder'#2#0#14'TitleFont.Name'#6#13'MS S'
+ +'ans Serif'#10'OnDrawCell'#7#16'DataGridDrawCell'#10'OnKeyPress'#7#16'DataGr'
+ +'idKeyPress'#11'OnMouseDown'#7#17'DataGridMouseDown'#11'OnMouseMove'#7#17'Da'
+ +'taGridMouseMove'#12'OnSelectCell'#7#18'DataGridSelectCell'#0#0#8'TToolBar'#8
+ +'ToolBar1'#4'Left'#2#0#6'Height'#2#25#3'Top'#2#0#5'Width'#3'F'#1#11'EdgeBord'
+ +'ers'#11#0#8'TabOrder'#2#1#0#12'TSpeedButton'#9'DesignBtn'#4'Left'#2#1#6'Hei'
+ +'ght'#2#22#4'Hint'#6#5'ANOVA'#3'Top'#2#0#5'Width'#2'x'#7'Caption'#6#6'Design'
+ +#10'Glyph.Data'#10'z'#1#0#0'v'#1#0#0'BMv'#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0' '
+ +#0#0#0#16#0#0#0#1#0#4#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#0#0#16#0#0#0#16#0#0#0#0#0
+ +#0#0#0#0#128#0#0#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#127
+ +#127#127#0#191#191#191#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255
+ +#0#255#255#0#0#255#255#255#0'3s3s3s3s3'#127'?'#127'?'#127'?'#127'3sssssss?'
+ +#127#127#127#127#127#127#127'w'#0#0#0#0#0#0#0'wwwwwwww3'#3'33<3333'#127#255
+ +'37'#243'3?7'#9#147'3<33'#153'7ws'#243'7'#243'3w3'#3'93<393?'#127#247#255#247
+ +#255#247#255'w'#7'w'#151'|w'#151'wwwwwwwww3'#3'3'#147'<3'#147'33'#127'3s'#247
+ +#243's37'#3'39<9337'#127'377'#247'333'#3'33'#153#147'33?'#127#255#255'w'#127
+ +#255#255'w'#7'ww|wwwwwwwwwww3'#3'33<3'#3'33'#127'337'#255#127#243'7'#3'33<'#0
+ +#0'<7'#127'337ww73'#3'33<3'#3'3?'#127#255#255#247#255#127#255'w'#7'wwwwwwwww'
+ +'wwwww3333333333333333'#9'NumGlyphs'#2#2#7'OnClick'#7#14'DesignBtnClick'#8'S'
+ +'howHint'#9#14'ParentShowHint'#8#0#0#0#10'TStatusBar'#10'StatusBar1'#4'Left'
+ +#2#0#6'Height'#2#15#3'Top'#3#11#2#5'Width'#3'F'#1#6'Panels'#14#1#5'Width'#3
+ +#140#0#0#1#5'Width'#2'2'#0#0#11'SimplePanel'#8#0#0#9'TMainMenu'#9'MainMenu1'
+ +#4'left'#2'l'#3'top'#2','#0#9'TMenuItem'#5'File1'#7'Caption'#6#5'&File'#0#9
+ +'TMenuItem'#4'New1'#7'Caption'#6#6'New...'#8'ShortCut'#3'N@'#7'OnClick'#7#11
+ +'NewBtnClick'#0#0#9'TMenuItem'#5'Open1'#7'Caption'#6#7'Open...'#8'ShortCut'#3
+ +'O@'#7'OnClick'#7#12'OpenBtnClick'#0#0#9'TMenuItem'#5'Save1'#7'Caption'#6#4
+ +'Save'#8'ShortCut'#3'S@'#7'OnClick'#7#12'SaveBtnClick'#0#0#9'TMenuItem'#5'Qu'
+ +'it1'#7'Caption'#6#12'Close window'#8'ShortCut'#3'W@'#7'OnClick'#7#10'Quit1C'
+ +'lick'#0#0#0#9'TMenuItem'#5'Edit1'#7'Caption'#6#4'Edit'#0#9'TMenuItem'#5'Cop'
+ +'y1'#7'Caption'#6#4'Copy'#8'ShortCut'#3'C@'#7'OnClick'#7#10'Copy1Click'#0#0#9
+ +'TMenuItem'#6'Paste1'#7'Caption'#6#5'Paste'#8'ShortCut'#3'V@'#7'OnClick'#7#11
+ +'Paste1Click'#0#0#9'TMenuItem'#10'Selectall1'#7'Caption'#6#16'Select all cel'
+ +'ls'#8'ShortCut'#3'A@'#7'OnClick'#7#15'Selectall1Click'#0#0#9'TMenuItem'#14
+ +'Clearallcells1'#7'Caption'#6#18'Clear all cells...'#7'OnClick'#7#19'Clearal'
+ +'lcells1Click'#0#0#9'TMenuItem'#15'DescriptiveMenu'#7'Caption'#6#12'Descript'
+ +'ives'#7'OnClick'#7#16'DescriptiveClick'#0#0#0#9'TMenuItem'#4'View'#7'Captio'
+ +'n'#6#4'View'#0#9'TMenuItem'#5'Font1'#7'Caption'#6#4'Font'#0#9'TMenuItem'#3
+ +'N81'#3'Tag'#2#8#7'Caption'#6#1'8'#7'Checked'#9#10'GroupIndex'#2'o'#9'RadioI'
+ +'tem'#9#7'OnClick'#7#14'FontSizeChange'#0#0#9'TMenuItem'#4'N101'#3'Tag'#2#10
+ +#7'Caption'#6#2'10'#10'GroupIndex'#2'o'#9'RadioItem'#9#7'OnClick'#7#14'FontS'
+ +'izeChange'#0#0#9'TMenuItem'#4'N121'#3'Tag'#2#12#7'Caption'#6#2'12'#10'Group'
+ +'Index'#2'o'#9'RadioItem'#9#7'OnClick'#7#14'FontSizeChange'#0#0#9'TMenuItem'
+ +#4'N141'#3'Tag'#2#14#7'Caption'#6#2'14'#10'GroupIndex'#2'o'#9'RadioItem'#9#7
+ +'OnClick'#7#14'FontSizeChange'#0#0#0#9'TMenuItem'#7'Design1'#7'Caption'#6#6
+ +'Design'#8'ShortCut'#3'D@'#7'OnClick'#7#14'DesignBtnClick'#0#0#0#9'TMenuItem'
+ +#5'Help1'#7'Caption'#6#5'&Help'#0#9'TMenuItem'#18'Aboutthissoftware1'#7'Capt'
+ +'ion'#6#20'&About this software'#7'OnClick'#7#23'Aboutthissoftware1Click'#0#0
+ +#0#0#11'TOpenDialog'#11'OpenDialog1'#10'DefaultExt'#6#4'.val'#6'Filter'#6'<N'
+ +'ative [val]|.val|Tab delimited text [txt]|.txt|All files|.*'#11'FilterIndex'
+ +#2#0#4'left'#2'$'#3'top'#2','#0#0#11'TSaveDialog'#11'SaveDialog1'#10'Default'
+ +'Ext'#6#4'.val'#6'Filter'#6'8Native format [val]|*.val|Tab delimited text [t'
+ +'xt]|*.txt'#11'FilterIndex'#2#0#7'Options'#11#17'ofOverwritePrompt'#14'ofHid'
+ +'eReadOnly'#0#4'left'#2'J'#3'top'#2','#0#0#0
+]);
\ No newline at end of file
diff --git a/npm/spread.pas b/npm/spread.pas
old mode 100644
new mode 100755
index c087182..0873ed9
--- a/npm/spread.pas
+++ b/npm/spread.pas
@@ -570,6 +570,20 @@ begin
DataGrid.ColCount := 9;
DataGrid.RowCount := 15;
FormResize(nil);
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+
+New1.ShortCut := ShortCut(Word('N'), [ssMeta]);
+ Open1.ShortCut := ShortCut(Word('O'), [ssMeta]);
+ Save1.ShortCut := ShortCut(Word('S'), [ssMeta]);
+ Quit1.ShortCut := ShortCut(Word('W'), [ssMeta]);
+ Copy1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ Paste1.ShortCut := ShortCut(Word('V'), [ssMeta]);
+ Selectall1.ShortCut := ShortCut(Word('A'), [ssMeta]);
+ DescriptiveMenu.ShortCut := ShortCut(Word('L'), [ssMeta]);
+
+ {$ENDIF}//Carbon
+ {$ENDIF}//Darwin
end;
procedure TSpreadForm.DataGridMouseDown(Sender: TObject; Button: TMouseButton;
@@ -688,7 +702,11 @@ begin
C := StartC;
while( length( S ) > 0 ) do begin
// Extract next line...
+ {$IFDEF UNIX}
+ Dummy := pos( #13, S + #13 ) ;
+ {$ELSE}
Dummy := pos( #13#10, S + #13#10 ) ;
+ {$ENDIF}
Line := copy( S, 1, Dummy - 1 ) ;
if (Dummy+1) < length(S) then //last line may not have eol
S := copy( S, Dummy + 1, length( S ) )
@@ -1015,4 +1033,4 @@ initialization
{$I spread.lrs}
{$ENDIF}
-end.
+end.
\ No newline at end of file
diff --git a/npm/statcr.pas b/npm/statcr.pas
old mode 100644
new mode 100755
index bb5b52a..2a2c27c
--- a/npm/statcr.pas
+++ b/npm/statcr.pas
@@ -1,6 +1,6 @@
Unit statcr;
interface
-uses Dialogs,define_types;
+uses dialogsx,define_types;
const
ITMAX = 300;
@@ -437,7 +437,7 @@ end;
procedure AlertMsg (pWarningStr: String);
begin
- MessageDLG(pWarningStr, mtWarning,[mbOK],0);
+ ShowMsg(pWarningStr);
end;
function gammln (xx: double): double; {Numerical Recipes for Pascal, p 177}
@@ -628,4 +628,4 @@ procedure Chi2x2 (A, B, C, D: integer; var pMinExp, pChi, p, puChi, pup: double)
END.
-
+
\ No newline at end of file
diff --git a/npm/stats.pas b/npm/stats.pas
old mode 100644
new mode 100755
index 9a10915..ccee73d
--- a/npm/stats.pas
+++ b/npm/stats.pas
@@ -3,7 +3,7 @@ unit stats;
interface
uses define_types,statcr,DISTR
-,SysUtils,Dialogs,ClipBrd;
+,SysUtils,Dialogsx;
procedure TStat2 (lnSubj, lnGroupX: integer; var lIn: DoubleP0; var lOutT: double);
//procedure TStatAbs (lnSubj, lnGroupX: integer; var lIn: DoubleP0; var lOutT: double);
procedure PairedTStat (lnSubj: integer; var lIn: DoubleP0; var lOutT: double);
@@ -101,7 +101,7 @@ begin
else
result := 0.75 + ((lH-lF)*0.25) - ((1-lH)/(4*(1-lF)))
end else
- showmessage('error in Zhang and Mueller, 2005 (func rocA)');
+ ShowMsg('error in Zhang and Mueller, 2005 (func rocA)');
if lHit < lFA then //worse than chance
result := 1 - result;
@@ -374,7 +374,7 @@ begin
if not gFactRAready then InitFact;
if (k < 1) or (n <0) then begin
result := 20000001;
- showmessage('error k_out_n: k and n must be positive '+inttostr(n)+':'+inttostr(k))
+ ShowMsg('error k_out_n: k and n must be positive '+inttostr(n)+':'+inttostr(k))
end else if (n > kMaxFact) or (k > kMaxFact) then
result := 20000001
else begin
@@ -622,7 +622,7 @@ begin
if abs(ls) < tiny then
exit;
if ls < 0 then
- showmessage('Error: t-test variance should not be zero.');
+ ShowMsg('Error: t-test variance should not be zero.');
//deepshit (lnSubj, lnGroupX, lIn,lS);
//if ls <= 0 then
// exit; xxx
@@ -1007,4 +1007,4 @@ end;
end.
-
+
\ No newline at end of file
diff --git a/npm/tfce_clustering.7z b/npm/tfce_clustering.7z
new file mode 100755
index 0000000..0287bcc
Binary files /dev/null and b/npm/tfce_clustering.7z differ
diff --git a/npm/tfce_clustering.pas b/npm/tfce_clustering.pas
new file mode 100755
index 0000000..7ca95e0
--- /dev/null
+++ b/npm/tfce_clustering.pas
@@ -0,0 +1,273 @@
+unit tfce_clustering;
+//USED by stats to select only regions with a given number of connected/contiguous voxels
+{$IFDEF FPC} {$mode delphi}{$H+} {$ENDIF}
+{$Include ..\common\isgui.inc}
+interface
+uses
+{$IFNDEF UNIX} Windows,
+ {$ELSE}
+ {$IFDEF GUI} LCLType, LCLintf,{$ENDIF}
+ {$ENDIF}
+define_types,dialogsx,SysUtils,nifti_hdr,nifti_img, math,unpm;
+
+//procedure FindClusters (lMultiBuf: SingleP; lXdim, lYDim, lZDim, lThreshClusterSz: integer; lMinNeg, lMinPos: single);
+
+//function ClusterTFCE (var lHdr: TMRIcroHdr; lThreshClusterSz: integer; lThresh: double ): boolean;
+
+function doTFCE (var lHdr: TNIFTIhdr; lImg: SingleP; NumConn: integer; H, E, minT, deltaT: single ): boolean;
+//mimics FSL's function "TFCE" in newimagefns.h
+
+function doTFCEbothPolarities (var lHdr: TNIFTIhdr; lImg: SingleP; NumConn: integer; H, E, minT, deltaT, minNegT, NegdeltaT: single; var maxTFCE, maxNegTFCE: single): boolean;
+//both polarities computes TFCE for both positive and negative values
+
+implementation
+
+
+procedure countClusterSize (lX,lY,lZ, lnumConnIn: integer; var lClusterBuff: LongIntP);
+//input CountImg is volume X*Y*Z where voxels are either 0 or 1
+// output: CountImg voxels report number of connected neighbors
+const
+ lClusterSign = 1; //input CountImg has this value set to 1
+ lClusterFillValue = -1; //impossible cluster size - used to denote actively growing cluster
+var
+ lQHead,lV,lXY, lXYZ,lClusterSz, lQTail,lnumConn,lI,lNeighbor: integer;
+ lQra: LongIntP;
+ ConnOffset : ARRAY [1..26] of integer;
+procedure InitConn;
+begin
+ //first 6 share face
+ ConnOffset[1] := -1;//L
+ ConnOffset[2] := 1; //R
+ ConnOffset[3] := -lX; //A
+ ConnOffset[4] := lX; //P
+ ConnOffset[5] := -lXY;//I
+ ConnOffset[6] := lXY;//S
+ if lnumConnIn < 7 then begin
+ lnumConn := 6;
+ exit;
+ end;
+ //share edge
+ //..check plane above
+ ConnOffset[7] := (lXY-1); //left
+ ConnOffset[8] := (lXY+1); //right
+ ConnOffset[9] := (lXY-lX); //up
+ ConnOffset[10] := (lXY+lX); //down
+ //..check plane below
+ ConnOffset[11] := (-lXY-1); //left
+ ConnOffset[12] := (-lXY+1); //right
+ ConnOffset[13] := (-lXY-lX); //up
+ ConnOffset[14] := (-lXY+lX); //down
+ //..check diagonals of current plane
+ ConnOffset[15] := (-lX-1); //up, left
+ ConnOffset[16] := (-lX+1); //up, right
+ ConnOffset[17] := (+lX-1); //down, left
+ ConnOffset[18] := (+lX+1); //down, right
+ if lnumConnIn < 19 then begin
+ lnumConn := 18;
+ exit;
+ end;
+ //share corner
+ //..check plane above
+ ConnOffset[19] := (lXY-1-lX); //left
+ ConnOffset[20] := (lXY-1+lX); //right
+ ConnOffset[21] := (lXY+1-lX); //up
+ ConnOffset[22] := (lXY+1+lX); //down
+ //..check plane BELOW
+ ConnOffset[23] := (-lXY-1-lX); //left
+ ConnOffset[24] := (-lXY-1+lX); //right
+ ConnOffset[25] := (-lXY+1-lX); //up
+ ConnOffset[26] := (-lXY+1+lX); //down
+ lnumConn := 26;
+end; //InitConn
+begin
+ lXY := lX * lY;
+ lXYZ := lX*lY*lZ;
+ InitConn;
+ if lXYZ < 1 then exit;
+ GetMem(lQra,lXYZ * sizeof(longint) );
+ //check every voxel to see if it is isolated
+ for lV := 1 to lXYZ do begin
+ if (lClusterBuff^[lV]=lClusterSign) then begin //new cluster detected
+ lClusterSz := 1;
+ lQHead := 1;
+ lQTail := 1;
+ lQra^[lQTail] := lV;
+ lClusterBuff^[lV] := lClusterFillValue;
+ while (lQHead >= lQTail) do begin
+ //RetirePixel: lQTail incremented once, lQHead is incremented 0..nummConn
+ for lI := 1 to lnumConn do begin
+ lNeighbor := lQra^[lQTail]+ConnOffset[lI];
+ if (lClusterBuff^[lNeighbor]=lClusterSign) then begin//add item
+ inc(lQHead);
+ inc(lClusterSz);
+ lClusterBuff^[lNeighbor] := lClusterFillValue;
+ lQra^[lQHead] := lNeighbor;
+ end; //if new item detected
+ end; //for each connector
+ inc(lQTail); //done with this pixel
+ end; //while items in Queue
+ for lI := lV to lXYZ do
+ if (lClusterBuff^[lI]=lClusterFillValue) then
+ lClusterBuff^[lI] := lClusterSz;
+ end; //new item found
+ end; //for each voxel
+ freemem(lQra);
+end;
+
+procedure ZeroFaces (var lHdr: TNIFTIhdr; lImg: SingleP );
+var
+ lV,lX,lY,lZ,lZi,lYi,lXi: integer;
+begin
+ lX := lHdr.Dim[1];
+ lY := lHdr.Dim[2];
+ lZ := lHdr.Dim[3];
+ if (lX < 3) or (lY < 3) or (lZ < 3) then exit;
+ for lV := 1 to (lX*lY) do lImg[lV] := 0; //bottom slice
+ for lV := ((lX*lY*lZ)-(lX*lY)) to (lX*lY*lZ) do lImg[lV] := 0; //top slice
+ //left side
+ lV := 1;
+ for lZi := 1 to lZ do begin
+ for lYi := 1 to lY do begin
+ lImg[lV] := 0;
+ lV := lV+lX;
+ end;
+ end;
+ //right side
+ lV := lX;
+ for lZi := 1 to lZ do begin
+ for lYi := 1 to lY do begin
+ lImg[lV] := 0;
+ lV := lV+lX;
+ end;
+ end;
+ //anterior
+ for lZi := 1 to lZ do begin
+ lV := (lZi-1) * lX*lY;
+ for lXi := 1 to lX do begin
+ lV := lV+1;
+ lImg[lV] := 0;
+ end;
+ end;
+ //posterior
+ for lZi := 1 to lZ do begin
+ lV := (lZi-1) * lX*lY;
+ lV := lV + ((lY-1) *lX);
+ for lXi := 1 to lX do begin
+ lV := lV+1;
+ lImg[lV] := 0;
+ end;
+ end;
+end;
+
+
+function doTFCEbothPolarities (var lHdr: TNIFTIhdr; lImg: SingleP; NumConn: integer; H, E, minT, deltaT, minNegT, NegdeltaT: single; var maxTFCE, maxNegTFCE: single): boolean;
+var
+ lV,lXYZ,lX,lY,lZ: integer;
+
+ lNegImg: SingleP;
+
+begin
+ result := false;
+ lX := lHdr.Dim[1];
+ lY := lHdr.Dim[2];
+ lZ := lHdr.Dim[3];
+ lXYZ := lX*lY*lZ;
+ if lXYZ < 1 then exit;
+ getmem(lNegImg,lXYZ*sizeof(single));
+ for lV := 1 to lXYZ do
+ lNegImg[lV] := -lImg[lV];
+
+
+ doTFCE (lHdr, lImg, NumConn, H, E, minT, deltaT);
+ maxTFCE :=lImg[lV];
+ for lV := 1 to lXYZ do
+ if (maxTFCE < lImg[lV]) then
+ maxTFCE:= lImg[lV];
+
+
+ doTFCE (lHdr, lNegImg, NumConn, H, E, abs(minNegT), abs(NegdeltaT));
+ maxNegTFCE :=lImg[lV];
+ for lV := 1 to lXYZ do
+ if (maxNegTFCE < lNegImg[lV]) then
+ maxNegTFCE:= lNegImg[lV];
+ maxNegTFCE := -maxNegTFCE;
+
+ for lV := 1 to lXYZ do begin
+ if (lNegImg[lV] > 0) then
+ lImg[lV] := -lNegImg[lV];
+ end;
+
+ freemem(lNegImg);
+end;
+
+
+
+function doTFCE (var lHdr: TNIFTIhdr; lImg: SingleP; NumConn: integer; H, E, minT, deltaT: single ): boolean;
+const
+ kSteps = 100;
+label
+ 777;
+var
+ lV,lXYZ,lX,lY,lZ: integer;
+ maxval, lThresh, ThreshPowerHxdh, dh: single;
+ lThreshImg: SingleP;
+ lCountImg: LongIntP;
+ lStartTime: DWord;
+begin
+ lX := lHdr.Dim[1];
+ lY := lHdr.Dim[2];
+ lZ := lHdr.Dim[3];
+ {$IFDEF GUI} lStartTime := GetTickCount; {$ENDIF}
+ result := false;//assume failure
+ lXYZ := lX*lY*lZ;
+ if lXYZ < 1 then exit;
+ //E := 0.5; //0.5
+ //H := 2;//2
+ getmem(lThreshImg,lXYZ*sizeof(single));
+ getmem(lCountImg,lXYZ*sizeof(longint));
+ ZeroFaces (lHdr, lImg );
+ maxval := lImg[1];
+ for lV := 1 to lXYZ do begin
+ lThreshImg[lV] := lImg[lV];
+ if lImg[lV] > maxval then maxval := lImg[lV];
+ lImg[lV] := 0; //initialize sum map to zero
+ end;
+
+ if (maxval <= 0) then goto 777;
+ if (maxval < minT) then goto 777;
+ if (deltaT = 0) then
+ dh := (maxval-minT) / kSteps
+ else
+ dh := deltaT;
+ NPMmsg('max = '+floattostr(maxval)+' deltaT = '+floattostr(dh));
+ lThresh := minT+dh;
+ while lThresh < maxval do begin
+
+
+ for lV := 1 to lXYZ do begin
+ if (lThreshImg[lV] <= lThresh) then
+ lCountImg[lV] := 0
+ else
+ lCountImg[lV] := 1;
+ end;
+ countClusterSize (lX,lY,lZ,NumConn, lCountImg);
+ ThreshPowerHxdh := power(lThresh,H)*dh;
+ for lV := 1 to lXYZ do
+ if (lCountImg[lV] > 0) then
+ lImg[lV] := lImg[lV] + (exp(E*ln(lCountImg[lV])) * ThreshPowerHxdh); //faster than power
+ (*for lV := 1 to lXYZ do
+ if (lCountImg[lV] > 0) then
+ lImg[lV] := lImg[lV] + (power(lCountImg[lV],E) * ThreshPowerHxdh); *)
+ lThresh := lThresh + dh;
+ end;
+777:
+ {$IFDEF GUI} NPMmsg('Time = '+inttostr(GetTickCount - lStartTime)); {$ENDIF}
+ freemem(lCountImg);
+ freemem(lThreshImg);
+ result := true; //report success!
+end;
+
+
+
+
+end.
\ No newline at end of file
diff --git a/npm/tfce_clustering.zip b/npm/tfce_clustering.zip
new file mode 100755
index 0000000..c22aed6
Binary files /dev/null and b/npm/tfce_clustering.zip differ
diff --git a/npm/turbolesion.pas b/npm/turbolesion.pas
old mode 100644
new mode 100755
index 133c57d..6b18218
--- a/npm/turbolesion.pas
+++ b/npm/turbolesion.pas
@@ -1,11 +1,12 @@
unit turbolesion;
interface
-{$H+}
+{$H+}
+{$Include ..\common\isgui.inc}
uses
define_types,SysUtils,
part,StatThds,statcr,StatThdsUtil,Brunner,DISTR,nifti_img, hdr,
Messages, Classes, Graphics, Controls, Forms, Dialogs,
-StdCtrls, ComCtrls,ExtCtrls,Menus, overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr,
+StdCtrls, ComCtrls,ExtCtrls,Menus, overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr, unpm,
{$IFDEF FPC} LResources,gzio2,
{$ELSE} gziod,associate,{$ENDIF} //must be in search path, e.g. C:\pas\mricron\npm\math
@@ -24,7 +25,11 @@ function TurboLDM (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var lPrefs:
implementation
-uses npmform;
+{$IFDEF GUI}
+ uses npmform;
+{$ELSE}
+ // uses npmcl;
+{$ENDIF}
(*procedure Debog (var lSumImg: Smallintp; lVox: integer);
var
@@ -60,7 +65,7 @@ begin
lSumImg^[lVox] := lSumImg^[lVox]+1;*)
for lImg := 1 to lImages.Count do begin
lPosPct := round(100*(lImg / lImages.Count));
- MainForm.ProgressBar1.Position := lPosPct;
+ NPMProgressBar( lPosPct);
Application.Processmessages;
if not LoadImg8(lImages[lImg-1], lVolImg, 1, lVolVox,round(gOffsetRA[lImg]),1,gDataTypeRA[lImg],lVolVox) then
goto 667;
@@ -68,8 +73,8 @@ begin
if lVolImg^[lVox] <> 0 then
lSumImg^[lVox] := lSumImg^[lVox]+1;
end;//for each image
- MainForm.NPMmsg('Sum image finished = ' +TimeToStr(Now));
- MainForm.ProgressBar1.Position := 0;
+ NPMmsg('Sum image finished = ' +TimeToStr(Now));
+ NPMProgressBar(0);
//Debog(lSumImg, lVolVox);
freemem(lVolImg);
result := true;
@@ -77,8 +82,8 @@ begin
667: //you only get here if you aborted ... free memory and report error
freemem(lVolImg);
freemem(lSumImg);
- MainForm.NPMMsg('Unable to complete analysis.');
- MainForm.ProgressBar1.Position := 0;
+ NPMMsg('Unable to complete analysis.');
+ NPMProgressBar(0);
end;
@@ -109,11 +114,11 @@ label
begin
result := 0;
if (lVolVox < 1) or (not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr)) then begin
- MainForm.NPMmsg('Error: unable to load explicit mask named '+lMaskName);
+ NPMmsg('Error: unable to load explicit mask named '+lMaskName);
exit;
end;
if lVolVox <> (lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3]) then begin
- MainForm.NPMmsg('Error: data and explicit mask have different sizes '+lMaskName);
+ NPMmsg('Error: data and explicit mask have different sizes '+lMaskName);
exit;
end;
@@ -127,7 +132,6 @@ begin
lSumImg^[lPos] := 0
else
inc(result);
-
666:
freemem(lMaskData);
end;
@@ -186,13 +190,13 @@ begin
end;//reformat
-function NULPcount (lPlankImg: bytep; lVoxPerPlank,lImagesCount: integer; var lUniqueOrders: integer; var lOverlapRA: Overlapp): boolean;
+function NULPcount (lPlankImg: bytep; lVoxPerPlank,lImagesCount,lnCrit: integer; var lUniqueOrders: integer; var lOverlapRA: Overlapp): boolean;
procedure CheckOrder(var lObservedOrder: TLesionPattern);
var
lInc: integer;
begin
if lUniqueOrders > 0 then begin //see if this is unique
- for lInc := 1 to lUniqueOrders do
+ for lInc := lUniqueOrders downto 1 do //check most recent patterns first
if SameOrder(lObservedOrder,lOverlapRA^[lInc],lImagesCount) then
exit; //not unique
end; //UniqueOrders > 0
@@ -202,10 +206,20 @@ begin
end;
var
- lVox,lPlankImgPos,lPos: integer;
+ lVox,lPlankImgPos,lPos,lnLesion: integer;
lOrder,lPrevOrder: TLesionPattern;
begin
result := false;
+ if lImagesCount > kMaxObs then begin
+ NPMmsg('Warning: unable to count unique lesion patterns for so many participants');
+ exit;
+ end;
+ if lImagesCount > 64 then
+ NPMMsg('Counting unique lesion patterns - this may take a while (edit preferences to skip this step)');
+ Application.Processmessages;
+ NPMProgressBar(0); //this forces a refresh for GUI applications
+ Sleep(30);
+
lPrevOrder := EmptyOrder;//impossible: forces first voxel of each order to be checked
for lVox := 1 to lVoxPerPlank do begin
(*if (lVox mod lVoxPerPlankDiv10) = 0 then begin
@@ -214,20 +228,21 @@ begin
Application.processmessages;
end;*)
lOrder := EmptyOrder;
+ lnLesion := 0;
lPlankImgPos := 0;
//lnDeficits := 0;
for lPos := 1 to lImagesCount do begin
if (lPlankImg^[lPlankImgPos + lVox] > 0) then begin
- //inc(lnDeficits);
+ inc(lnLesion);
SetBit(lPos,lOrder);
end;
lPlankImgPos := lPlankImgPos + lVoxPerPlank;
end;
- //if (lnDeficits >= lminDeficits) then begin //this is different from the last voxel: perhaps this is a new ordering
+ if (lnLesion >= lnCrit) then begin //statistics computed - more than nCrit injured
if (not SameOrder(lOrder,lPrevOrder,lImagesCount)) then
CheckOrder(lOrder);
//inc(lnVoxels);
- //end;//nDeficies
+ end;//lnLesion
lPrevOrder := lOrder;
end;//for lVox
result := true;
@@ -264,6 +279,7 @@ label
123,667;
var
lOutNameMod: string;
+ lNULPcalculated: boolean;
lStatHdr: TNIfTIhdr;
lThreshFDR,lThreshPermute,lThreshBonf,lThreshNULP :double;
lObsp: pointer;
@@ -277,10 +293,12 @@ var
lUniqueOrders,lThread,lThreadStart,lThreadInc,lThreadEnd,
lPos2,lPosPct,lPos,lPlankImgPos,lPlank,lStartVox,lEndVox: integer;
lOverlapRA: Overlapp;
+ lPrevThreadsRunning: integer;
{$IFNDEF FPC} lStartTime :DWord;{$ENDIF}
begin
{$IFNDEF FPC} lStartTime := GetTickCount;{$ENDIF}
result := false;
+ lNULPcalculated := false;
lSumImg := nil;
lPlankImg := nil;
lOutImgSum := nil;
@@ -293,25 +311,25 @@ begin
lPrefs.Ttest := false;
lPrefs.BMtest := false;
end else if (not lPrefs.Ttest) and (not lPrefs.BMtest) then begin//not binomial
- MainForm.NPMmsg('Error no tests specified');
+ NPMmsg('Error no tests specified');
exit;
end;
- MainForm.NPMmsg('Permutations = ' +IntToStr(lPrefs.nPermute));
- MainForm.NPMmsg('Analysis began = ' +TimeToStr(Now));
+ NPMmsg('Permutations = ' +IntToStr(lPrefs.nPermute));
+ NPMmsg('Analysis began = ' +TimeToStr(Now));
lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
if (lVolVox < 1) then goto 667;
if not MakeSum( lImages, lMaskHdr, lSumImg) then goto 667;
lnVoxTested := ThreshSumImg(lSumImg,lVolVox,lPrefs.nCrit);
- MainForm.NPMmsg('Voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individuals = ' +Floattostr(lnVoxTested));
+ NPMmsg('Voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individuals = ' +Floattostr(lnVoxTested));
if lnVoxTested < 1 then begin
- MainForm.NPMmsg('Error: no voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individuals.');
+ NPMmsg('Error: no voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individuals.');
goto 667;
end;
if (lPrefs.ExplicitMaskName <> '') then begin
lnVoxTested := ExplicitMaskSumImg (lPrefs.ExplicitMaskName, lSumImg, lVolVox);
- MainForm.NPMmsg('Voxels also non-zero in mask '+lPrefs.ExplicitMaskName+' = ' +Floattostr(lnVoxTested));
+ NPMmsg('Voxels also non-zero in mask '+lPrefs.ExplicitMaskName+' = ' +Floattostr(lnVoxTested));
if lnVoxTested < 1 then begin
- MainForm.NPMmsg('Error: no remaing voxels also non-zero in mask '+lPrefs.ExplicitMaskName);
+ NPMmsg('Error: no remaing voxels also non-zero in mask '+lPrefs.ExplicitMaskName);
goto 667;
end;
end;
@@ -320,7 +338,7 @@ begin
lTotalMemory := lnVoxTested * lImages.Count;
if (lTotalMemory = 0) then goto 667; //no data
lnPlanks := trunc(lTotalMemory/kPlankSz ) + 1;
- MainForm.NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/kPlankSz));
+ NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/kPlankSz));
if (lnPlanks = 1) then begin
lVoxPerPlank := lnVoxTested; //we can do this in a single pass
getmem(lPlankImg,lTotalMemory)
@@ -334,7 +352,7 @@ begin
getmem(lOutImgT,lVolVox*sizeof(single));
getmem(lOutImgAUC,lVolVox*sizeof(single));
//initialize memory
- MainForm.InitPermute (lImages.Count, lPrefs.nPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
+ InitPermute (lImages.Count, lPrefs.nPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
for lPos := 1 to lVolVox do begin
lOutImgSum^[lPos] := 0;
lOutImgBM^[lPos] := 0;
@@ -343,8 +361,8 @@ begin
end;
//next create permuted BM bounds
if lPrefs.BMtest then begin
- MainForm.NPMmsg('Generating BM permutation thresholds');
- MainForm.Refresh;
+ NPMmsg('Generating BM permutation thresholds');
+ //MainForm.Refresh;
createArray64(lObsp,lObs,lImages.Count);
for lPos := 1 to lImages.Count do
lObs^[lPos-1] := lSymptomRA^[lPos];
@@ -361,7 +379,7 @@ begin
lStartVox := 1;
lEndVox := 0;
for lPlank := 1 to lnPlanks do begin
- MainForm.NPMmsg('Computing plank = ' +Inttostr(lPlank)+' of '+inttostr(lnPlanks));
+ NPMmsg('Computing plank = ' +Inttostr(lPlank)+' of '+inttostr(lnPlanks));
lEndVox := lEndVox + lVoxPerPlank;
if lEndVox > lnVoxTested then begin
lVoxPerPlank := lnVoxTested-lStartVox+1{lVoxPerPlank - (lEndVox-lVolVox)};
@@ -392,30 +410,31 @@ begin
lThreadStart := lThreadEnd + 1;
lThreadEnd :=lThreadEnd + lThreadInc;
end; //for each thread
+ lPrevThreadsRunning := gThreadsRunning;
repeat
Application.processmessages;
+ sleep(30);
+ if (gThreadsRunning <> lPrevThreadsRunning) then begin
+ NPMmsg(' '+inttostr(gThreadsRunning)+' threads still running ' +TimeToStr(Now));
+ lPrevThreadsRunning := gThreadsRunning;
+ end;
until gThreadsRunning = 0;
Application.processmessages;
//end of threading
-
if lPrefs.NULP then
- NULPcount (lPlankImg, lVoxPerPlank,lImages.Count, lUniqueOrders, lOverlapRA);
-
+ lNULPcalculated := NULPcount (lPlankImg, lVoxPerPlank,lImages.Count,lPrefs.nCrit, lUniqueOrders, lOverlapRA);
lStartVox := lEndVox + 1;
end;
- //calculate max per thread
+ //calculate max per thread x
SumThreadData(gnCPUThreads,lPrefs.nPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM);
-
//data in maps is stored in voxels 1..lnVoxTested - put in spatial order
reformat(lOutImgSum,lSumImg,lVolVox);
reformat(lOutImgBM,lSumImg,lVolVox);
reformat(lOutImgT,lSumImg,lVolVox);
reformat(lOutImgAUC,lSumImg,lVolVox);
- lThreshBonf := MainForm.reportBonferroni('Std',lnVoxTested);
- if lPrefs.NULP then
- lThreshBonf := MainForm.reportBonferroni('Number of Unique Lesion Patterns',lUniqueOrders);
-
-
+ lThreshBonf := reportBonferroni('Std',lnVoxTested);
+ if lNULPcalculated {lPrefs.NULP} then
+ lThreshBonf := reportBonferroni('(Number of Unique Lesion Patterns with at least '+inttostr(lPrefs.nCrit)+' lesions)',lUniqueOrders);
//next: save data
MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
//save sum map
@@ -442,13 +461,13 @@ begin
lPermuteMaxT^[lPos] := TtoZ (lPermuteMaxT^[lPos],lImages.Count-2);
lPermuteMinT^[lPos] := TtoZ (lPermuteMinT^[lPos],lImages.Count-2);
end;
- lThreshFDR := MainForm.reportFDR ('ttest', lVolVox, lnVoxTested, lOutImgT);
- lThreshPermute := MainForm.reportPermute('ttest',lPrefs.nPermute,lPermuteMaxT, lPermuteMinT);
+ lThreshFDR := reportFDR ('ttest', lVolVox, lnVoxTested, lOutImgT);
+ lThreshPermute := reportPermute('ttest',lPrefs.nPermute,lPermuteMaxT, lPermuteMinT);
lOutNameMod := ChangeFilePostfixExt(lOutName,'ttest'+lFactName,'.hdr');
{$IFNDEF FPC}
- if lPrefs.Run > 0 then begin
- MainForm.NPMmsgAppend('threshtt,'+inttostr(lPrefs.Run)+','+inttostr(MainForm.ThreshMap(lThreshBonf,lVolVox,lOutImgT))+','+realtostr(lThreshNULP,3)+','+realtostr(lThreshPermute,3)+','+realtostr(lThreshBonf,3)+','+inttostr(round((GetTickCount - lStartTime)/1000)));
- end;
+ //if lPrefs.Run > 0 then begin
+ // NPMmsg('threshtt,'+inttostr(lPrefs.Run)+','+inttostr(MainForm.ThreshMap(lThreshBonf,lVolVox,lOutImgT))+','+realtostr(lThreshNULP,3)+','+realtostr(lThreshPermute,3)+','+realtostr(lThreshBonf,3)+','+inttostr(round((GetTickCount - lStartTime)/1000)));
+ //end;
{$ENDIF}
NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgT,1);
end;
@@ -456,22 +475,24 @@ begin
PtoZpermute (lPrefs.nPermute, lPermuteMaxT, lPermuteMinT);
lOutNameMod := ChangeFilePostfixExt(lOutName,'L'+lFactName,'.hdr');
NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgBM,1);
- MainForm.reportFDR ('L', lVolVox, lnVoxTested, lOutImgBM);
- MainForm.reportPermute('L',lPrefs.nPermute,lPermuteMaxT, lPermuteMinT);
+ reportFDR ('L', lVolVox, lnVoxTested, lOutImgBM);
+ reportPermute('L',lPrefs.nPermute,lPermuteMaxT, lPermuteMinT);
end;//Liebermeister
if lPrefs.BMtest then begin //save Brunner Munzel
- lThreshFDR := MainForm.reportFDR ('BM', lVolVox, lnVoxTested, lOutImgBM);
- lThreshPermute := MainForm.reportPermute('BM',lPrefs.nPermute,lPermuteMaxBM, lPermuteMinBM);
+ lThreshFDR := reportFDR ('BM', lVolVox, lnVoxTested, lOutImgBM);
+ lThreshPermute := reportPermute('BM',lPrefs.nPermute,lPermuteMaxBM, lPermuteMinBM);
lOutNameMod := ChangeFilePostfixExt(lOutName,'BM'+lFactName,'.hdr');
if lPrefs.Run > 0 then
- MainForm.NPMmsgAppend('threshbm,'+inttostr(lPrefs.Run)+','+inttostr(MainForm.ThreshMap(lThreshBonf,lVolVox,lOutImgBM))+','+realtostr(lThreshNULP,3)+','+realtostr(lThreshPermute,3)+','+realtostr(lThreshBonf,3));
+ NPMmsg('threshbm,'+inttostr(lPrefs.Run)+','+inttostr(ThreshMap(lThreshBonf,lVolVox,lOutImgBM))+','+realtostr(lThreshNULP,3)+','+realtostr(lThreshPermute,3)+','+realtostr(lThreshBonf,3));
+
+ //NPMmsgAppend('threshbm,'+inttostr(lPrefs.Run)+','+inttostr(MainForm.ThreshMap(lThreshBonf,lVolVox,lOutImgBM))+','+realtostr(lThreshNULP,3)+','+realtostr(lThreshPermute,3)+','+realtostr(lThreshBonf,3));
NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgBM,1);
end;
- MainForm.NPMmsg('Analysis finished = ' +TimeToStr(Now));
- {$IFNDEF FPC} MainForm.NPMmsg('Processing Time = ' +inttostr(round((GetTickCount - lStartTime)/1000)));{$ENDIF}
+ NPMmsg('Analysis finished = ' +TimeToStr(Now));
+ {$IFNDEF FPC} NPMmsg('Processing Time = ' +inttostr(round((GetTickCount - lStartTime)/1000)));{$ENDIF}
lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes'+lFactName,'.txt');
- MainForm.MsgSave(lOutNameMod);
+ NPMMsgSave(lOutNameMod);
//all done
result := true;//all done without aborting
667: // free memory and report error
@@ -484,8 +505,8 @@ begin
if lOverlapRA <> nil then freemem(lOverlapRA);
if not result then
- MainForm.NPMmsg('Unable to complete analysis.');
- MainForm.ProgressBar1.Position := 0;
+ NPMmsg('Unable to complete analysis.');
+ NPMProgressBar( 0);
end; //TurboLDM
-end.
+end.
\ No newline at end of file
diff --git a/npm/turbolesion.pas b/npm/turbolesion_cmdLine.pas
old mode 100644
new mode 100755
similarity index 78%
copy from npm/turbolesion.pas
copy to npm/turbolesion_cmdLine.pas
index 133c57d..af4be89
--- a/npm/turbolesion.pas
+++ b/npm/turbolesion_cmdLine.pas
@@ -1,13 +1,16 @@
unit turbolesion;
interface
-{$H+}
+{$H+}
+{$Include ..\common\isgui.inc}
uses
- define_types,SysUtils,
+ // Messages, Graphics, Controls, Forms, Dialogs,StdCtrls, ComCtrls,ExtCtrls,Menus,
+ {$IFDEF GUI} ComCtrls,ReadInt,Forms, {$ENDIF}
+ Classes,dialogsx, define_types,SysUtils,unpm,
part,StatThds,statcr,StatThdsUtil,Brunner,DISTR,nifti_img, hdr,
- Messages, Classes, Graphics, Controls, Forms, Dialogs,
-StdCtrls, ComCtrls,ExtCtrls,Menus, overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr,
-{$IFDEF FPC} LResources,gzio2,
+overlap,lesion_pattern,stats,LesionStatThds,nifti_hdr,
+
+{$IFDEF FPC} {$IFDEF GUI} LResources,{$ENDIF} gzio2,
{$ELSE} gziod,associate,{$ENDIF} //must be in search path, e.g. C:\pas\mricron\npm\math
{$IFNDEF UNIX} Windows, {$ENDIF}
upower,firthThds,firth,IniFiles,cpucount,userdir,math,
@@ -23,8 +26,11 @@ function TurboLDM (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var lPrefs:
implementation
-
-uses npmform;
+{$IFDEF GUI}
+ uses npmform;
+{$ELSE}
+ // uses npmcl;
+{$ENDIF}
(*procedure Debog (var lSumImg: Smallintp; lVox: integer);
var
@@ -60,16 +66,15 @@ begin
lSumImg^[lVox] := lSumImg^[lVox]+1;*)
for lImg := 1 to lImages.Count do begin
lPosPct := round(100*(lImg / lImages.Count));
- MainForm.ProgressBar1.Position := lPosPct;
- Application.Processmessages;
+ NPMProgressBar(lPosPct);
if not LoadImg8(lImages[lImg-1], lVolImg, 1, lVolVox,round(gOffsetRA[lImg]),1,gDataTypeRA[lImg],lVolVox) then
goto 667;
for lVox := 1 to lVolVox do
if lVolImg^[lVox] <> 0 then
lSumImg^[lVox] := lSumImg^[lVox]+1;
end;//for each image
- MainForm.NPMmsg('Sum image finished = ' +TimeToStr(Now));
- MainForm.ProgressBar1.Position := 0;
+ NPMmsg('Sum image finished = ' +TimeToStr(Now));
+ NPMProgressBar( 0);
//Debog(lSumImg, lVolVox);
freemem(lVolImg);
result := true;
@@ -77,8 +82,8 @@ begin
667: //you only get here if you aborted ... free memory and report error
freemem(lVolImg);
freemem(lSumImg);
- MainForm.NPMMsg('Unable to complete analysis.');
- MainForm.ProgressBar1.Position := 0;
+ NPMMsg('Unable to complete analysis.');
+ NPMProgressBar( 0 );
end;
@@ -109,11 +114,11 @@ label
begin
result := 0;
if (lVolVox < 1) or (not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr)) then begin
- MainForm.NPMmsg('Error: unable to load explicit mask named '+lMaskName);
+ NPMmsg('Error: unable to load explicit mask named '+lMaskName);
exit;
end;
if lVolVox <> (lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3]) then begin
- MainForm.NPMmsg('Error: data and explicit mask have different sizes '+lMaskName);
+ NPMmsg('Error: data and explicit mask have different sizes '+lMaskName);
exit;
end;
@@ -277,6 +282,7 @@ var
lUniqueOrders,lThread,lThreadStart,lThreadInc,lThreadEnd,
lPos2,lPosPct,lPos,lPlankImgPos,lPlank,lStartVox,lEndVox: integer;
lOverlapRA: Overlapp;
+
{$IFNDEF FPC} lStartTime :DWord;{$ENDIF}
begin
{$IFNDEF FPC} lStartTime := GetTickCount;{$ENDIF}
@@ -293,25 +299,25 @@ begin
lPrefs.Ttest := false;
lPrefs.BMtest := false;
end else if (not lPrefs.Ttest) and (not lPrefs.BMtest) then begin//not binomial
- MainForm.NPMmsg('Error no tests specified');
+ NPMmsg('Error no tests specified');
exit;
end;
- MainForm.NPMmsg('Permutations = ' +IntToStr(lPrefs.nPermute));
- MainForm.NPMmsg('Analysis began = ' +TimeToStr(Now));
+ NPMmsg('Permutations = ' +IntToStr(lPrefs.nPermute));
+ NPMmsg('Analysis began = ' +TimeToStr(Now));
lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
if (lVolVox < 1) then goto 667;
if not MakeSum( lImages, lMaskHdr, lSumImg) then goto 667;
lnVoxTested := ThreshSumImg(lSumImg,lVolVox,lPrefs.nCrit);
- MainForm.NPMmsg('Voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individuals = ' +Floattostr(lnVoxTested));
+ NPMmsg('Voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individuals = ' +Floattostr(lnVoxTested));
if lnVoxTested < 1 then begin
- MainForm.NPMmsg('Error: no voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individuals.');
+ NPMmsg('Error: no voxels damaged in at least '+inttostr(lPrefs.nCrit)+' individuals.');
goto 667;
end;
if (lPrefs.ExplicitMaskName <> '') then begin
lnVoxTested := ExplicitMaskSumImg (lPrefs.ExplicitMaskName, lSumImg, lVolVox);
- MainForm.NPMmsg('Voxels also non-zero in mask '+lPrefs.ExplicitMaskName+' = ' +Floattostr(lnVoxTested));
+ NPMmsg('Voxels also non-zero in mask '+lPrefs.ExplicitMaskName+' = ' +Floattostr(lnVoxTested));
if lnVoxTested < 1 then begin
- MainForm.NPMmsg('Error: no remaing voxels also non-zero in mask '+lPrefs.ExplicitMaskName);
+ NPMmsg('Error: no remaing voxels also non-zero in mask '+lPrefs.ExplicitMaskName);
goto 667;
end;
end;
@@ -320,7 +326,7 @@ begin
lTotalMemory := lnVoxTested * lImages.Count;
if (lTotalMemory = 0) then goto 667; //no data
lnPlanks := trunc(lTotalMemory/kPlankSz ) + 1;
- MainForm.NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/kPlankSz));
+ NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/kPlankSz));
if (lnPlanks = 1) then begin
lVoxPerPlank := lnVoxTested; //we can do this in a single pass
getmem(lPlankImg,lTotalMemory)
@@ -334,7 +340,7 @@ begin
getmem(lOutImgT,lVolVox*sizeof(single));
getmem(lOutImgAUC,lVolVox*sizeof(single));
//initialize memory
- MainForm.InitPermute (lImages.Count, lPrefs.nPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
+ InitPermute (lImages.Count, lPrefs.nPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
for lPos := 1 to lVolVox do begin
lOutImgSum^[lPos] := 0;
lOutImgBM^[lPos] := 0;
@@ -343,9 +349,8 @@ begin
end;
//next create permuted BM bounds
if lPrefs.BMtest then begin
- MainForm.NPMmsg('Generating BM permutation thresholds');
- MainForm.Refresh;
- createArray64(lObsp,lObs,lImages.Count);
+ NPMmsg('Generating BM permutation thresholds');
+ createArray64(lObsp,lObs,lImages.Count);
for lPos := 1 to lImages.Count do
lObs^[lPos-1] := lSymptomRA^[lPos];
genBMsim (lImages.Count, lObs);
@@ -361,7 +366,7 @@ begin
lStartVox := 1;
lEndVox := 0;
for lPlank := 1 to lnPlanks do begin
- MainForm.NPMmsg('Computing plank = ' +Inttostr(lPlank)+' of '+inttostr(lnPlanks));
+ NPMmsg('Computing plank = ' +Inttostr(lPlank)+' of '+inttostr(lnPlanks));
lEndVox := lEndVox + lVoxPerPlank;
if lEndVox > lnVoxTested then begin
lVoxPerPlank := lnVoxTested-lStartVox+1{lVoxPerPlank - (lEndVox-lVolVox)};
@@ -376,26 +381,55 @@ begin
lThreadStart := 1;
lThreadInc := lVoxPerPlank div gnCPUThreads;
lThreadEnd := lThreadInc;
- Application.processmessages;
+ NPMmsg('starting threads '+inttostr(gnCPUThreads));
+ {$IFDEF aaaaa}
for lThread := 1 to gnCPUThreads do begin
if lThread = gnCPUThreads then
lThreadEnd := lVoxPerPlank; //avoid integer rounding error
+ ThreadArray[lThread]:= TLesionContinuous.Create (MainForm.ProgressBar1,lPrefs.ttest,lPrefs.BMtest,lPrefs.nCrit, lPrefs.nPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,0,lPlankImg,lOutImgSum,lOutImgBM,lOutImgT,lOutImgAUC,lSymptomRA) ;
+ inc(gThreadsRunning);
+
+ lThreadStart := lThreadEnd + 1;
+ lThreadEnd :=lThreadEnd + lThreadInc;
+ end;
+
+ NPMmsg('started threads '+inttostr(gnCPUThreads));
+ for lThread := 1 to gnCPUThreads do if not ThreadArray[lThread].Terminated then Sleep(100);
+ NPMmsg('done threads '+inttostr(gnCPUThreads));
+ {$ELSE}
+ for lThread := 1 to gnCPUThreads do begin
+ if lThread = gnCPUThreads then
+ lThreadEnd := lVoxPerPlank; //avoid integer rounding error
if lPrefs.Ltest then begin
with TLesionBinom.Create (MainForm.ProgressBar1,false,true,lPrefs.nCrit, lPrefs.nPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,0,lPlankImg,lOutImgSum,lOutImgBM,lOutIMgT{not used},lOutImgAUC,lSymptomRA) do
- {$IFDEF FPC} OnTerminate := @MainForm.ThreadDone; {$ELSE}OnTerminate := MainForm.ThreadDone;{$ENDIF}
+ {$IFDEF GUI}
+ {$IFDEF FPC} OnTerminate := @MainForm.ThreadDone; {$ELSE}OnTerminate := MainForm.ThreadDone;{$ENDIF}
+ {$ELSE}
+ NPMmsg(inttostr(gThreadsRunning));
+ //OnTerminate := @NPMThreadDone;
+ {$ENDIF}
end else begin
with TLesionContinuous.Create (MainForm.ProgressBar1,lPrefs.ttest,lPrefs.BMtest,lPrefs.nCrit, lPrefs.nPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,0,lPlankImg,lOutImgSum,lOutImgBM,lOutImgT,lOutImgAUC,lSymptomRA) do
//with TLesionContinuous.Create (MainForm.ProgressBar1,lttest,lBM,lnCrit, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,lPlankImg,lOutImgSum,lOutImgBM,lOutImgT,lSymptomRA) do
+ {$IFDEF GUI}
{$IFDEF FPC} OnTerminate := @MainForm.ThreadDone; {$ELSE}OnTerminate := MainForm.ThreadDone;{$ENDIF}
+
+ {$ELSE}
+
+ OnTerminate := @Application.ThreadDone;
+ NPMmsg('starting '+inttostr(gThreadsRunning));
+ {$ENDIF}
end;
inc(gThreadsRunning);
lThreadStart := lThreadEnd + 1;
lThreadEnd :=lThreadEnd + lThreadInc;
end; //for each thread
repeat
- Application.processmessages;
+ Sleep(100);
+ refresher;
until gThreadsRunning = 0;
- Application.processmessages;
+ refresher;
+ {$ENDIF}
//end of threading
if lPrefs.NULP then
@@ -411,9 +445,9 @@ begin
reformat(lOutImgBM,lSumImg,lVolVox);
reformat(lOutImgT,lSumImg,lVolVox);
reformat(lOutImgAUC,lSumImg,lVolVox);
- lThreshBonf := MainForm.reportBonferroni('Std',lnVoxTested);
+ lThreshBonf := reportBonferroni('Std',lnVoxTested);
if lPrefs.NULP then
- lThreshBonf := MainForm.reportBonferroni('Number of Unique Lesion Patterns',lUniqueOrders);
+ lThreshBonf := reportBonferroni('Number of Unique Lesion Patterns',lUniqueOrders);
//next: save data
@@ -442,8 +476,8 @@ begin
lPermuteMaxT^[lPos] := TtoZ (lPermuteMaxT^[lPos],lImages.Count-2);
lPermuteMinT^[lPos] := TtoZ (lPermuteMinT^[lPos],lImages.Count-2);
end;
- lThreshFDR := MainForm.reportFDR ('ttest', lVolVox, lnVoxTested, lOutImgT);
- lThreshPermute := MainForm.reportPermute('ttest',lPrefs.nPermute,lPermuteMaxT, lPermuteMinT);
+ lThreshFDR := reportFDR ('ttest', lVolVox, lnVoxTested, lOutImgT);
+ lThreshPermute := reportPermute('ttest',lPrefs.nPermute,lPermuteMaxT, lPermuteMinT);
lOutNameMod := ChangeFilePostfixExt(lOutName,'ttest'+lFactName,'.hdr');
{$IFNDEF FPC}
if lPrefs.Run > 0 then begin
@@ -456,22 +490,22 @@ begin
PtoZpermute (lPrefs.nPermute, lPermuteMaxT, lPermuteMinT);
lOutNameMod := ChangeFilePostfixExt(lOutName,'L'+lFactName,'.hdr');
NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgBM,1);
- MainForm.reportFDR ('L', lVolVox, lnVoxTested, lOutImgBM);
- MainForm.reportPermute('L',lPrefs.nPermute,lPermuteMaxT, lPermuteMinT);
+ reportFDR ('L', lVolVox, lnVoxTested, lOutImgBM);
+ reportPermute('L',lPrefs.nPermute,lPermuteMaxT, lPermuteMinT);
end;//Liebermeister
if lPrefs.BMtest then begin //save Brunner Munzel
- lThreshFDR := MainForm.reportFDR ('BM', lVolVox, lnVoxTested, lOutImgBM);
- lThreshPermute := MainForm.reportPermute('BM',lPrefs.nPermute,lPermuteMaxBM, lPermuteMinBM);
+ lThreshFDR := reportFDR ('BM', lVolVox, lnVoxTested, lOutImgBM);
+ lThreshPermute := reportPermute('BM',lPrefs.nPermute,lPermuteMaxBM, lPermuteMinBM);
lOutNameMod := ChangeFilePostfixExt(lOutName,'BM'+lFactName,'.hdr');
if lPrefs.Run > 0 then
- MainForm.NPMmsgAppend('threshbm,'+inttostr(lPrefs.Run)+','+inttostr(MainForm.ThreshMap(lThreshBonf,lVolVox,lOutImgBM))+','+realtostr(lThreshNULP,3)+','+realtostr(lThreshPermute,3)+','+realtostr(lThreshBonf,3));
+ NPMmsg('threshbm,'+inttostr(lPrefs.Run)+','+inttostr(ThreshMap(lThreshBonf,lVolVox,lOutImgBM))+','+realtostr(lThreshNULP,3)+','+realtostr(lThreshPermute,3)+','+realtostr(lThreshBonf,3));
NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgBM,1);
end;
- MainForm.NPMmsg('Analysis finished = ' +TimeToStr(Now));
+ NPMmsg('Analysis finished = ' +TimeToStr(Now));
{$IFNDEF FPC} MainForm.NPMmsg('Processing Time = ' +inttostr(round((GetTickCount - lStartTime)/1000)));{$ENDIF}
lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes'+lFactName,'.txt');
- MainForm.MsgSave(lOutNameMod);
+ NPMMsgSave(lOutNameMod);
//all done
result := true;//all done without aborting
667: // free memory and report error
@@ -484,8 +518,8 @@ begin
if lOverlapRA <> nil then freemem(lOverlapRA);
if not result then
- MainForm.NPMmsg('Unable to complete analysis.');
- MainForm.ProgressBar1.Position := 0;
+ NPMmsg('Unable to complete analysis.');
+ NPMProgressBar( 0);
end; //TurboLDM
-end.
+end.
\ No newline at end of file
diff --git a/npm/unpm.pas b/npm/unpm.pas
new file mode 100755
index 0000000..1628b6a
--- /dev/null
+++ b/npm/unpm.pas
@@ -0,0 +1,1679 @@
+unit unpm;
+{$IFDEF FPC}{$mode objfpc}{$H+} {$ENDIF}
+{$Include ..\common\isgui.inc}
+interface
+
+uses
+ upower,math,utypes,
+regmult,IniFiles,Classes, SysUtils, define_types,distr, statcr, StatThdsUtil, userdir, dialogsx, nifti_hdr, StatThds, lesion_pattern;
+Type
+ TNPMPrefs = record
+ NULP,ROI,ttest,BMtest: boolean;
+ TFCE,PlankMB,nPermute: integer;
+ end;
+
+ procedure ComputePlankSize (var lPlankMB: integer);
+ procedure InitPermute (lnSubj, lnPermute: integer; var lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP; var lRanOrderp: pointer; var lRanOrder: Doublep0);
+ procedure NPMThreadDone;
+ function reportBonferroni(lLabel: string; lnTests: integer): double; //returns 5% Z score
+ function reportFDR (lLabel:string; lnVox, lnTests: integer; var lData: SingleP): double;
+ function reportPermute (lLabel:string; lnPermute: integer; var lPermuteMaxZ, lPermuteMinZ: singleP): double;
+ function ThreshMap(lThresh: single; lVolVox: integer;lOutImg: singleP): integer;
+ procedure NPMMsgSave(lFilename: string);
+ procedure NPMProgressBar(lPos: integer);
+ procedure NPMmsg(str: string);
+ procedure NPMMsgClear;
+ function GetKVers: string;
+ function ReportDescriptives (var RA: SingleP; n: integer): boolean;
+ procedure FreePermute (lnPermute: integer; var lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP;var lRanOrderp: pointer);
+ procedure ReadIniFile;
+ procedure WriteIniFile;
+ function Add2ndScans(var lImageNames: TStrings): boolean;
+ function ChangeName (lInName: string): string;
+ function NPMzscore (var lImages: TStrings; var lMnHdr,lStDevHdr: TMRIcroHdr): boolean;
+ function NPMAnalyze (var lImages: TStrings; var lMaskname: string; lMaskVoxels,lnGroup1: integer; lNPMPrefs: TNPMPrefs; var lOutName: string): boolean;
+
+ //function NPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lMaskVoxels,lnGroup1: integer; lNPMPrefs: TNPMPrefs; var lOutName: string): boolean;
+ function ComputeLesionVolume (lImgName: string): integer;
+ procedure Refresher;
+ function MakeMean (lImages: TStrings; lBinarize,lVariance : boolean; lOutName: string): boolean;
+ procedure NPMTitleMsg (S: string);
+ //function MakeMean (var lImages: TStrings; lBinarize,lVariance : boolean; lOutName: string): boolean;
+ function NPMAnalyzePaired (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lMaskVoxels: integer; lOutName: string): boolean;
+ procedure NPMMultipleRegressClick(var lVALFilename, lMaskname,lOutname: string);
+ procedure NPMSingleRegress (var lVALFilename, lMaskname,lOutname: string);
+ function ComputeOverlap ( lROIname: string; var lLesionNames: TStrings; var lROIvol: double; lFracROIinjured: singlep): boolean;
+ function Balance (var lImageName,lMaskName: String; {lInflection: boolean}lMethod: integer): boolean;
+ function ReadPairedFilenames(var lImageNames: TStrings): boolean;
+ var
+ gNPMPrefs: TNPMPrefs;
+
+
+implementation
+uses
+ {$IFDEF GUI}npmform,Forms,{$ENDIF} regression, valformat,
+ firthThds,firth,hdr, prefs, nifti_img, tfce_clustering;
+{$IFNDEF GUI}
+var
+ NPMmemo: TStringList;
+{$ENDIF}
+
+var
+ gThreadsRunning: integer = 0;
+procedure NPMTitleMsg (S: string);
+begin
+ MainForm.Caption := S;
+end;
+
+
+procedure NPMProgressBar(lPos: integer);
+begin
+ {$IFDEF GUI}
+ MainForm.ProgressBar1.Position := lPos;
+ MainForm.Refresh;
+ {$ENDIF}
+end;
+
+procedure NPMMsgClear;
+begin
+ {$IFDEF GUI}
+ MainForm.NPMMsgClearUI;
+ {$ELSE}
+ //shittt
+ {$ENDIF}
+end;
+
+procedure NPMmsg(str: string);
+begin
+ {$IFDEF GUI}
+ MainForm.NPMmsgUI(str);
+ {$ELSE}
+ writeln(str);
+ //shittt
+ {$ENDIF}
+end;
+
+procedure NPMMsgSave(lFilename: string);
+var
+ i: integer;
+ f: textfile;
+begin
+ {$IFDEF GUI}
+ MainForm.NPMmsgSaveUI(lFilename);
+ {$ELSE}
+ ShowMsg('SHITTTT');
+ {$ENDIF}
+end;
+
+const
+ {$IFDEF CPU32}
+ kVers : string = 'Chris Rorden''s 32-bit NPM: '+kMRIcronVers;
+ {$ELSE}
+ kVers : string = 'Chris Rorden''s 64-bit NPM: '+kMRIcronVers;
+ {$ENDIF}
+
+function GetKVers: string;
+begin
+ result := kVers +'; Threads used = '+inttostr(gnCPUThreads )+' plankSize: '+inttostr(gNPMPrefs.PlankMB)+'mb';
+end;
+
+procedure Refresher;
+begin
+ {$IFDEF GUI}
+ Application.processmessages;
+ MainForm.Refresh;
+ {$ENDIF}
+end;
+
+
+function ReadPairedFilenames(var lImageNames: TStrings): boolean;
+var
+ lLen,lPos: integer;
+ lFilenames,lF1,lF2: string;
+ lImageNames2: TStrings;
+ lF: TextFile;
+begin
+ result := false;
+ ShowMsg('Please select a text file with the image names. '+kCR+
+ 'Each line of the file should specify the control and experimental filenames, separated by an *'+kCR+
+ 'C:\vbmdata\c1.nii.gz*C:\vbmdata\e1.nii.gz'+kCR +
+ 'C:\vbmdata\c2.nii.gz*C:\vbmdata\e2.nii.gz'+kCR+
+ 'C:\vbmdata\c3.nii.gz*C:\vbmdata\e3.nii.gz'+kCR+
+ '...' );
+(*SHITTT if not MainForm.OpenDialogExecute('Select asterix separated filenames ',false,false,kTxtFilter) then
+ exit;
+ lImageNames2:= TStringList.Create; //not sure why TStrings.Create does not work???
+ //xxx
+ assignfile(lF,MainForm.OpenHdrDlg.FileName ); *)
+ FileMode := 0; //read only
+ reset(lF);
+ while not EOF(lF) do begin
+ readln(lF,lFilenames);
+ lLen := length(lFilenames);
+
+ if lLen > 0 then begin
+ lF1:= '';
+ lF2 := '';
+ lPos := 1;
+ while (lPos <= lLen) and (lFilenames[lPos] <> '*') do begin
+ lF1 := lF1 + lFilenames[lPos];
+ inc(lPos);
+ end;
+ inc(lPos);
+ while (lPos <= lLen) do begin
+ lF2 := lF2 + lFilenames[lPos];
+ inc(lPos);
+ end;
+ if (length(lF1) > 0) and (length(lF2)>0) then begin
+ if Fileexists4D(lF1) then begin
+ if Fileexists4D(lF2) then begin
+ lImageNames.add(lF1);
+ lImageNames2.add(lF2);
+ end else //F2exists
+ ShowMsg('Can not find image '+lF2);
+ end else //F1 exists
+ ShowMsg('Can not find image '+lF1);
+ end;
+ end;//len>0
+ end; //while not EOF
+ closefile(lF);
+ FileMode := 2; //read/write
+ if (lImageNames.count > 0) and (lImageNames2.count = lImageNames.count) then begin
+ lImageNames.AddStrings(lImageNames2);
+
+ result := true;
+ end;
+ lImageNames2.Free;
+end;
+
+
+function MinMax (var lImg: SingleP; var lVolVox: integer; var lMin, lMax: single): boolean;
+var
+ lC: integer;
+begin
+ result := false;
+ if lVolVox < 1 then
+ exit;
+ lMax := lImg^[1];
+ for lC := 1 to lVolVox do
+ if lImg^[lC] > lMax then
+ lMax := lImg^[lC];
+ //lCx := lC;
+ lMin := lImg^[1];
+ for lC := 1 to lVolVox do
+ if lImg^[lC] < lMin then
+ lMin := lImg^[lC];
+ result := true;
+end;
+
+function DetectMode (var lImg: SingleP; var lVolVox: integer; var lMin, lMax, lModeLo,lModeHi: single; lInflection: boolean): boolean;
+const
+ kHistoBins = 255;//numbers of bins for histogram/image balance
+var
+ lSmooth,lPrevSmooth,lModeWid,lC,lMinPos,lMode,lModePos,lMaxModePos,lMode2NotInflection: integer;
+ lMod,lRng: single;
+ lHisto : array [0..kHistoBins] of longint;
+begin
+
+ result := false;
+ if (lVolVox < 1) or (lMax < lMin) then
+ exit;
+ //zero array
+ for lC := 1 to kHistoBins do
+ lHisto[lC] := 0;
+ //find scaling
+ lRng := abs(lMax-lMin);
+ if lRng > 0 then
+ lMod := (kHistoBins)/lRng
+ else
+ lMod := 0;
+ //fill histogram
+ for lC := 1 to lVolVox do
+ if lImg^[lC] <> 0 then
+ inc(lHisto[round((lImg^[lC]-lMin)*lMod)]);
+
+ {for lC := 1 to lVolVox do
+ inc(lHisto[round((lImg^[lC]-lMin)*lMod)]); }
+ //smooth histogram
+ lPrevSmooth := lHisto[1];
+ for lC := 2 to (kHistoBins-1) do begin
+ lSmooth := round( (lHisto[lC-1]+lHisto[lC]+lHisto[lC]+lHisto[lC+1])/4);
+ lHisto[lC-1] := lPrevSmooth;
+ lPrevSmooth := lSmooth;
+ end;
+ lHisto[kHistoBins-1] := lPrevSmooth;
+ //find mode
+ lMode := 0;
+ lMinPos := 1;//indexed from zero
+ //find highest peak
+ for lC := lMinPos to kHistoBins do begin
+ if lHisto[lC] > lMode then begin
+ lModePos := lC;
+ lMode := lHisto[lC];
+ end;//if new mode
+ end; //for each bin
+ if lMode > 0 then
+ lMaxModePos := lModePos
+ else
+ exit;
+ //find 2nd highest peak
+ //find 2nd highest peak
+ lModeWid := 25;
+ lModePos := lMinPos;
+ lMode := lHisto[lMinPos];
+ if (lMaxModePos - lModeWid) > lMinPos then begin
+ for lC := lMinPos to (lMaxModePos - lModeWid) do begin
+ if lHisto[lC] > lMode then begin
+ lModePos := lC;
+ lMode := lHisto[lC];
+ end;//if new mode
+ end; //for each bin
+ end; //check below highest peak
+ if (lMaxModePos + lModeWid) < kHistoBins then begin
+ for lC := (lMaxModePos + lModeWid) to kHistoBins do begin
+ if lHisto[lC] > lMode then begin
+ lModePos := lC;
+ lMode := lHisto[lC];
+ end;//if new mode
+ end; //for each bin
+ end; //check above highest peak
+ //fx(lModePos);
+ //an alternative method to find mode is to look for inflection - less assumptions, more sensitive to noise
+ if lInflection then begin
+ lMode2NotInflection := lModePos;
+ lModePos := lMinPos;
+
+ lMode := 0;
+ lC := lMaxModePos;
+ while ((lC-1) > lMinPos) and (lHisto[lC] > lHisto[lC-1]) do
+ dec(lC); //find inflection
+ while ((lC-1) > lMinPos) do begin
+ dec(lC);
+ if lHisto[lC] > lMode then begin
+ lModePos := lC;
+ lMode := lHisto[lC];
+ end;//if new mode
+ end; //look for mode
+
+ lC := lMaxModePos;
+ while ((lC+1) <= kHistoBins) and (lHisto[lC] > lHisto[lC+1]) do
+ inc(lC); //find inflection
+ while ((lC+1) <= kHistoBins) do begin
+ inc(lC);
+ if lHisto[lC] > lMode then begin
+ lModePos := lC;
+ lMode := lHisto[lC];
+ end;//if new mode
+ end; //look for mode
+
+ if abs(lMode2NotInflection-lModePos) > 3 then
+ ShowMsg('Warning: inflection and windowed algorithms find different 2nd modes. Using inflection 2nd mode. inflection ='+inttostr(lModePos)+' windowed: '+inttostr(lMode2NotInflection));
+
+ end;
+ //now, return scaled values...
+ if lMod = 0 then exit;
+ lModeLo := (lModePos/lMod)+lMin;
+ lModeHi := (lMaxModePos/lMod)+lMin;
+ if lModeLo > lModeHi then begin
+ lMod := lModeLo;
+ lModeLo := lModeHi;
+ lModeHi := lMod;
+ end;
+ result := true;
+end;
+
+function DetectMeanStDev (var lImg: SingleP; var lVolVox: integer; var lMean,lStDev: double): boolean;
+var
+ lIncVox,lVox: integer;
+ lSum,lSumSqr,lSE: double;
+begin
+ lMean := 0;
+ lStDev := 0;
+ result := false;
+ if (lVolVox < 1) then
+ exit;
+ lSum := 0;
+ lSumSqr := 0;
+ lIncVox := 0; //voxels included - e.g. not masked
+ for lVox := 1 to lVolVox do begin
+ if lImg^[lVox] <> 0 then begin //not in mask
+ inc(lIncVox);
+ lSum := lSum + lImg^[lVox];
+ lSumSqr := lSumSqr + sqr(lImg^[lVox]);
+ end;
+ end;
+ if lincVox < 3 then
+ exit;
+ Descriptive (lincVox, lSumSqr, lSum,lMean,lStDev,lSE);
+ result := true;
+end; //DetectMeanStDev
+
+
+
+function Balance (var lImageName,lMaskName: String; {lInflection: boolean}lMethod: integer): boolean;
+//0 = masked peak
+//1 = inflection
+//2 = mean =1, stdev=1
+var
+ lImg,lMaskImg: SingleP;
+ lHdr,lMaskHdr: TMRIcroHdr;
+ lVolVox,lVox,lMasked: integer;
+ lMaskedInten,lMean,lStDev: double;
+ lMin,lMax: single;
+ lModeLo,lModeHi,lIntercept,lSlope: single;
+ lOutNameMod: string;
+begin
+ //lOutName := lMaskHdr.ImgFileName;
+ result := false;
+ //if not SaveHdrName ('Statistical Map', lOutName) then exit;
+ if not NIFTIhdr_LoadHdr(lImageName,lHdr) then begin
+ ShowMsg('Error reading '+lImageName);
+ exit;
+ end;
+ lVolVox := lHdr.NIFTIhdr.dim[1]*lHdr.NIFTIhdr.dim[2]* lHdr.NIFTIhdr.dim[3];
+ if (lVolVox < 1) then exit;
+ getmem(lImg,lVolVox*sizeof(single));
+ if not LoadImg(lHdr.ImgFileName, lImg, 1, lVolVox,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMMsg('Unable to load ' +lHdr.ImgFileName);
+ exit;
+ end;
+ if lMaskName <> '' then begin
+ if not NIFTIhdr_LoadHdr(lMaskName,lMaskHdr) then begin
+ ShowMsg('Error reading '+lMaskName);
+ exit;
+ end;
+ if lVolVox <> (lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3]) then begin
+ ShowMsg('Mask and header must have identical dimensions '+lMaskName+ ' ' + lImageName);
+ exit;
+
+ end;
+ getmem(lMaskImg,lVolVox*sizeof(single));
+ if not LoadImg(lMaskHdr.ImgFileName, lMaskImg, 1, lVolVox,round(lMaskHdr.NIFTIhdr.vox_offset),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMMsg('Unable to load mask ' +lMaskHdr.ImgFileName);
+ exit;
+ end;
+ lMasked := 0;
+ lMaskedInten := 0;
+ for lVox := 1 to lVolVox do
+ if lMaskImg^[lVox] = 0 then begin
+ lMaskedInten := lMaskedInten + lImg^[lVox];
+ lImg^[lVox] := 0;
+ inc(lMasked);
+ end;
+ if lMasked < 1 then
+ NPMMsg('Warning: no voxels masked with image '+lMaskName)
+ else
+ NPMMsg('Mask='+ lMaskName+' Number of voxels masked= '+inttostr(lMasked)+' Mean unscaled intensity of masked voxels= '+floattostr(lMaskedInten/lMasked));
+ freemem(lMaskImg);
+ end;//mask
+
+ if not MinMax(lImg,lVolVox,lMin,lMax) then exit;
+ NPMMsg(lImageName+' -> '+lHdr.ImgFileName);
+ NPMMsg('min..max ' +floattostr(lMin)+'..'+floattostr(lMax));
+ if (lMethod = 0) or (lMethod = 1) then begin
+ if not DetectMode(lImg,lVolVox,lMin,lMax,lModeLo,lModeHi, odd(lMethod)) then exit;
+ if odd(lMethod) then
+ NPMMsg('method for finding second mode: inflection')
+ else
+ NPMMsg('method for finding second mode: masked peak');
+ NPMMsg('modes Lo Hi ' +floattostr(lModeLo)+'..'+floattostr(lModeHi));
+ if lModeLo >= lModeHi then exit;
+ lSlope := 1/abs(lModeHi-lModeLo);
+ lIntercept := (abs(lModeHi-lModeLo)-(lModeLo))*lSlope ; //make mode lo = 1;
+ end else begin
+ DetectMeanStDev (lImg, lVolVox, lMean,lStDev);
+ if lStDev <>0 then
+ lSlope := 1/lStDev
+ else begin
+ NPMMsg('Warning: StDev = 0!!!!');
+ lSlope := 1;
+ end;
+ lIntercept := (-lMean*lSlope)+2; //mean voxel has intensity of zero
+
+ NPMMsg('method for intensity normalization: Mean = 2, StDev = 1');
+ NPMMsg('raw_Mean = '+floattostr(lMean)+' '+' raw_StDev = '+floattostr(lStDev));
+
+ end;
+ NPMMsg('Slope/Intercept ' +floattostr(lSlope)+'..'+floattostr(lIntercept));
+ lHdr.NIFTIhdr.scl_slope := lSlope;
+ lHdr.NIFTIhdr.scl_inter := lIntercept;
+ //CopyFileEX(lHdr.HdrFilename,changefileext( lHdr.HdrFilename,'.hdx'));
+ RenameFile(lHdr.HdrFilename,changefileext( lHdr.HdrFilename,'.hdx'));
+ //optional - save input
+ lOutNameMod := ChangeFilePrefixExt(lImageName,'i','.hdr');
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lHdr.NIFTIhdr,true,not IsNifTiMagic(lHdr.NIFTIhdr),true,lImg,1);
+ //end optional
+ NIFTIhdr_SaveHdr(lHdr.HdrFilename,lHdr.NIFTIhdr,true,not IsNifTiMagic(lHdr.NIFTIhdr));
+
+ freemem(lImg);
+end;
+
+function ComputeOverlap ( lROIname: string; var lLesionNames: TStrings; var lROIvol: double; lFracROIinjured: singlep): boolean;
+label 667;
+var
+ lName: string;
+ lSum: double;
+ lLesion,lnLesions,lVolVox,lVolVoxA,lVox: integer;
+ lROIImg,lImgB: SingleP;
+ lMaskHdr: TMRIcroHdr;
+begin
+ lROIvol := 0;
+ result := false;
+ lnLesions := lLesionNames.count;
+ if lnLesions < 1 then begin
+ ShowMsg('Error: no lesion names');
+ exit;
+ end;
+ for lLesion := 1 to lnLesions do
+ lFracROIinjured^[lLesion] := 0;
+ //read A
+ if not NIFTIhdr_LoadHdr(lROIname,lMaskHdr) then begin
+ ShowMsg('Error reading ROI - '+lROIname);
+ exit;
+ end;
+ lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
+ if (lVolVox < 1) then begin
+ ShowMsg('Error with Mask voxels ' + inttostr(lVolVox));
+ exit;
+ end;
+ if not CheckVoxelsGroupX(lLesionNames, lMaskHdr) then begin
+ ShowMsg('Error image dimensions vary.');
+ exit;
+ end;
+ getmem(lROIImg,lVolVox*sizeof(single));
+ getmem(lImgB,lVolVox*sizeof(single));
+ if not LoadImg(lROIname, lROIImg, 1, lVolVox,round(lMaskHdr.NIFTIhdr.vox_offset),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMmsg('Unable to load lesion ' +lMaskHdr.ImgFileName);
+ goto 667;
+ end;
+ lVolVoxA := lVolVox;
+ for lVox := 1 to lVolVox do
+ if (lROIImg^[lVox] > 0) then
+ lROIvol := lROIvol +lROIImg^[lVox];
+ //read Lesion
+ if lROIvol < 1 then begin
+ NPMmsg('ROI volume < 1');
+ goto 667;
+ end;
+ //for each lesion
+ //NPMmsg('Compute overlap started '+inttostr(lnLesions)+' '+floattostr(lROIvol)+' '+inttostr(lVolVoxA));
+ NPMProgressBar( 0);
+ for lLesion := 1 to lnLesions do begin
+ NPMProgressBar(round((lLesion/lnLesions)*100)) ;
+ lSum := 0;
+ lName := lLesionNames.Strings[lLesion-1];
+ if not NIFTIhdr_LoadHdr(lName,lMaskHdr) then begin
+ ShowMsg('Error reading lesion - '+lName);
+ exit;
+ end;
+ lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
+ if (lVolVoxA <> lVolVox) or (lVolVox < 1) then begin
+ NPMmsg('Volume does not have expected number of voxels ' +lMaskHdr.ImgFileName +'<>'+lROIname+ ' found ' +inttostr(lVolVox)+' expected '+inttostr(lVolVoxA));
+ goto 667;
+ end;
+ if not LoadImg(lName, lImgB, 1, lVolVox,round(lMaskHdr.NIFTIhdr.vox_offset),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMmsg('Unable to load mask ' +lMaskHdr.ImgFileName);
+ goto 667;
+ end;
+ for lVox := 1 to lVolVox do begin
+ //if {(lImgB^[lVox] <> 0) and} (lROIImg^[lVox] <> 0) then fx(lROIImg^[lVox]);
+
+ if (lROIImg^[lVox] > 0) and (lImgB^[lVox] <> 0) then
+ lSum := lSum + lROIImg^[lVox];
+ end;
+ lFracROIinjured^[lLesion] := lSum/lROIvol;
+ end;//for each lesion
+ result := true;
+ NPMProgressBar( 0);
+
+ (*for lLesion := 1 to lnLesions do begin
+ if lFracROIinjured^[lLesion] > 0 then
+ fx( lFracROIinjured^[lLesion], lLesion);
+ end; *)
+
+ 667:
+
+ freemem(lImgB);
+ freemem(lROIImg);
+end;
+
+procedure NPMSingleRegress (var lVALFilename, lMaskname,lOutname: string);
+label
+ 666;
+var
+ lnSubj1,lnFactors,lnSubj,lMaskVoxels,lRow,lCol: integer;
+ lImageNames,lImageNames1: TStrings;
+ lPredictorList,lPredictorList1: TStringList;
+ lTemp4D: string;
+ lMaskHdr: TMRIcroHdr;
+ X,X1 : PMatrix;
+begin
+
+ lTemp4D := '';
+ lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
+ lPredictorList := TStringList.Create;
+ lPredictorList1 := TStringList.Create;
+ if not GetValReg(lVALFilename,lnSubj,lnFactors,X,lImageNames,lPredictorList) then
+ goto 666;
+ if (length(lMaskname) < 1) then
+ lMaskName := lImageNames[0];
+ if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
+ ShowMsg('Error reading mask image.');
+ exit;
+ end;
+ lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
+ if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
+ ShowMsg('Mask file size too small.');
+ goto 666;
+ end;
+ if not CheckVoxelsGroupX(lImageNames,lMaskHdr{lMaskVoxels}) then begin
+ ShowMsg('File dimensions differ from mask.');
+ goto 666;
+ end;
+ lTemp4D := CreateDecompressed4D(lImageNames);
+
+ lImageNames1:= TStringList.Create;
+ for lCol := 1 to lnFactors do begin
+ lPredictorList1.Clear;
+ lPredictorList1.Add(lPredictorList[lCol-1]);
+ lImageNames1.clear;
+ for lRow := 1 to lnSubj do
+ if X^[lCol]^[lRow] <> kNaN then
+ lImageNames1.Add(lImageNames[lRow-1]);
+ DimMatrix(X1, 1, lImageNames1.Count);
+ lnSubj1 := 0;
+
+ for lRow := 1 to lnSubj do
+ if X^[lCol]^[lRow] <> kNaN then begin
+ inc(lnSubj1);
+ X1^[1]^[lnSubj1] := X^[lCol]^[lRow];
+ end;
+ if lnSubj1 <> lImageNames1.Count then //should be impossible
+ ShowMsg('NPMSingleRegress: serious error - number of participants does not match');
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ NPMMsg('Single Linear Regression [Weighted Least Squares]');
+ NPMMsg('Mask = '+lMaskname);
+ NPMMsg('Total voxels = '+inttostr(lMaskVoxels));
+ NPMMsg('Number of observations = '+inttostr(lnSubj1));
+ NPMMsg('Image,'+ lPredictorList1.Strings[0]);
+ for lRow := 1 to lnSubj1 do
+ NPMMsg(lImageNames1[lRow-1]+','+floattostr(X1^[1]^[lRow]) ) ;
+ ARegressNPMAnalyze(lImageNames1,lMaskHdr,X1,1,lPredictorList1,lOutName, gNPMPrefs.nPermute,gNPMPrefs.TFCE);
+ //PermuteRegressNPMAnalyze (lImageNames1,lMaskHdr,X1,1,lPredictorList1,lOutName);
+ DelMatrix(X1, 1, lnSubj1);
+ end;
+ lImageNames1.Free;
+ DelMatrix(X, lnFactors, lnSubj);
+ 666:
+DeleteDecompressed4D(lTemp4D);
+ lImageNames.Free;
+ lPredictorList.Free;
+ lPredictorList1.Free;
+end;
+
+procedure NPMMultipleRegressClick(var lVALFilename, lMaskname,lOutname: string);
+label
+ 666;
+var
+ lnFactors,lnSubj,lMaskVoxels,lRow,lCol: integer;
+ lImageNames: TStrings;
+ lPredictorList: TStringList;
+ lTemp4D,lStr: string;
+ lMaskHdr: TMRIcroHdr;
+ X : PMatrix;
+begin
+ lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
+ lPredictorList := TStringList.Create;
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ NPMMsg('Multiple Linear Regression [Weighted Least Squares]');
+ if not GetValReg(lVALFilename,lnSubj,lnFactors,X,lImageNames,lPredictorList) then
+ goto 666;
+ lTemp4D := CreateDecompressed4D(lImageNames);
+
+ //lMaskname := lImageNames[0];
+
+ if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
+ ShowMsg('Error reading 1st image.');
+ goto 666;
+ end;
+ lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
+ if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
+ ShowMsg('Mask file size too small.');
+ goto 666;
+ end;
+ NPMMsg('Mask = '+lMaskname);
+ NPMMsg('Total voxels = '+inttostr(lMaskVoxels));
+ NPMMsg('Number of observations = '+inttostr(lnSubj));
+ if not CheckVoxelsGroupX(lImageNames,lMaskHdr {lMaskVoxels}) then begin
+ ShowMsg('File dimensions differ from mask.');
+ goto 666;
+ end;
+ //show matrix
+ lStr := 'Image,';
+ for lCol := 1 to lnFactors do
+ lStr := lStr + lPredictorList.Strings[lCol-1]+', ';
+ NPMmsg(lStr);
+ for lRow := 1 to lnSubj do begin
+ lStr := lImageNames[lRow-1]+',';
+ for lCol := 1 to lnFactors do
+ lStr := lStr + floattostr(X^[lCol]^[lRow])+', ';
+ NPMmsg(lStr);
+ end;
+
+ ARegressNPMAnalyze(lImageNames,lMaskHdr,X,lnFactors,lPredictorList,lOutName,0,0);
+
+ DelMatrix(X, lnFactors, lnSubj);
+ 666:
+ lImageNames.Free;
+ lPredictorList.Free;
+ DeleteDecompressed4D(lTemp4D);
+end;
+
+function NPMAnalyzePaired (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lMaskVoxels: integer; lOutName: string): boolean;
+label
+ 667;
+var
+ //lOutName,
+ lOutNameMod: string;
+ lMaskImg,lPlankImg,lOutImgMn,lOutImgT,lDummy,lDummy2: SingleP;
+ lTotalMemory: double; //not integer - limit for 32bit int is 2Gb
+ lPlank,lVolVox,lPos,lMinMask,lMaxMask,lnPlanks,lVoxPerPlank,
+ lPos2,lPos2Offset,lStartVox,lEndVox,lPlankImgPos,lnTests,lnVoxTested,lThreadStart,lThreadEnd,lThreadInc: integer;
+ lT, lSum, lMn: double;
+ lStatHdr: TNIfTIhdr;
+ lFdata: file;
+ lThread,lnPermute: integer;
+ lPermuteMaxT, lPermuteMinT: singleP;
+ lRanOrderp: pointer;
+ lRanOrder: Doublep0;
+begin
+ //lnPermute := ReadPermute;
+ lnPermute := 0;//not yet
+ NPMmsg('Permutations = ' +IntToStr(lnPermute));
+
+ NPMmsg('Analysis began = ' +TimeToStr(Now));
+ lTotalMemory := 0;
+ lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
+ if (lVolVox < 1) then goto 667;
+ //load mask
+ getmem(lMaskImg,lVolVox*sizeof(single));
+ if not LoadImg(lMaskHdr.ImgFileName, lMaskImg, 1, lVolVox,round(gOffsetRA[0]),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMmsg('Unable to load mask ' +lMaskHdr.ImgFileName);
+ goto 667;
+ end;
+ //next find start and end of mask
+ lPos := 0;
+ repeat
+ inc(lPos);
+ until (lMaskImg^[lPos] > 0) or (lPos = lVolVox);
+ lMinMask := lPos;
+ lPos := lVolVox+1;
+ repeat
+ dec(lPos);
+ until (lMaskImg^[lPos] > 0) or (lPos = 1);
+ lMaxMask := lPos;
+ if lMaxMask = 1 then begin
+ NPMmsg('Mask appears empty' +lMaskHdr.ImgFileName);
+ goto 667;
+ end;
+ NPMmsg('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
+ lVoxPerPlank := kPlankSz div lImages.Count div sizeof(single) ;
+ if (lVoxPerPlank = 0) then goto 667; //no data
+ lTotalMemory := ((lMaxMask+1)-lMinMask) * lImages.Count;
+ if (lTotalMemory = 0) then goto 667; //no data
+ lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
+ NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
+ NPMmsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
+ getmem(lPlankImg,kPlankSz);
+ lStartVox := lMinMask;
+ lEndVox := lMinMask-1;
+ for lPos := 1 to lImages.Count do
+ if gScaleRA[lPos] = 0 then
+ gScaleRA[lPos] := 1;
+ getmem(lOutImgMn,lVolVox* sizeof(single));
+ getmem(lOutImgT,lVolVox* sizeof(single));
+ //not yet InitPermute (lImages.Count, lnPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
+ for lPos := 1 to lVolVox do begin
+ lOutImgMn^[lPos] := 0;
+ lOutImgT^[lPos] := 0;
+ end;
+ ClearThreadData(gnCPUThreads,lnPermute);
+ for lPlank := 1 to lnPlanks do begin
+ NPMmsg('Computing plank = ' +Inttostr(lPlank));
+ Refresher;
+ lEndVox := lEndVox + lVoxPerPlank;
+ if lEndVox > lMaxMask then begin
+ lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
+ lEndVox := lMaxMask;
+ end;
+ lPlankImgPos := 1;
+ for lPos := 1 to lImages.Count do begin
+ if not LoadImg(lImages[lPos-1], lPlankImg, lStartVox, lEndVox,round(gOffsetRA[lPos]),lPlankImgPos,gDataTypeRA[lPos],lVolVox) then
+ goto 667;
+ lPlankImgPos := lPlankImgPos + lVoxPerPlank;
+ end;//for each image
+ //threading start
+ (**SHITTTT
+ lThreadStart := 1;
+ lThreadInc := lVoxPerPlank div gnCPUThreads;
+ lThreadEnd := lThreadInc;
+ Application.processmessages;
+ for lThread := 1 to gnCPUThreads do begin
+ if lThread = gnCPUThreads then
+ lThreadEnd := lVoxPerPlank; //avoid integer rounding error
+ with TPairedTStat.Create (ProgressBar1,false,false,0, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,666, lMaskImg,lPlankImg,lOutImgMn,lDummy2,lOutImgT,lDummy) do
+ {$IFDEF FPC} OnTerminate := @ThreadDone; {$ELSE}OnTerminate := ThreadDone;{$ENDIF}
+ inc(gThreadsRunning);
+ lThreadStart := lThreadEnd + 1;
+ lThreadEnd :=lThreadEnd + lThreadInc;
+ end; //for each thread
+ repeat
+ Application.processmessages;
+ until gThreadsRunning = 0;
+ Application.processmessages;
+ *)
+ //threading end
+ lStartVox := lEndVox + 1;
+ end;
+ lnVoxTested := SumThreadDataLite(gnCPUThreads);//not yet SumThreadData(gnCPUThreads,lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM);
+ //next report findings
+ NPMmsg('Voxels tested = ' +Inttostr(lnVoxTested));
+ reportBonferroni('Std',lnVoxTested);
+ //next: save data
+(*savedata *)
+ MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
+//save mean
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'Mean','.hdr');
+ if lnVoxTested > 1 then
+
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgMn,1);
+ MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
+
+if (lnVoxTestED > 1 ) then begin //save Ttest
+ //next: convert t-scores to z scores
+ for lPos := 1 to lVolVox do
+ lOutImgT^[lPos] := TtoZ (lOutImgT^[lPos],(lImages.Count div 2)-1);
+ for lPos := 1 to lnPermute do begin
+ lPermuteMaxT^[lPos] := TtoZ (lPermuteMaxT^[lPos],lImages.Count-2);
+ lPermuteMinT^[lPos] := TtoZ (lPermuteMinT^[lPos],lImages.Count-2);
+ end;
+
+ reportFDR ('ttest', lVolVox, lnVoxTested, lOutImgT);
+ reportPermute('ttest',lnPermute,lPermuteMaxT, lPermuteMinT);
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'ttest','.hdr');
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgT,1);
+end;
+//next: close images
+ //not yet FreePermute (lnPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp);
+ freemem(lOutImgT);
+ freemem(lOutImgMn);
+ //freemem(lObsp);
+ freemem(lMaskImg);
+ freemem(lPlankImg);
+ NPMmsg('Analysis finished = ' +TimeToStr(Now));
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes','.txt');
+ NPMMsgSave(lOutNameMod);
+ NPMProgressBar(0);
+ exit;
+667: //you only get here if you aborted ... free memory and report error
+ if lVolVox > 1 then freemem(lMaskImg);
+ if lTotalMemory > 1 then freemem(lPlankImg);
+ NPMmsg('Unable to complete analysis.');
+ NPMProgressBar(0);
+end;
+
+
+(*function ApplyTFCE (lImageName: string): boolean;
+var
+ lImg: SingleP;
+ lHdr: TMRIcroHdr;
+ lVolVox: integer;
+ maxTFCE, maxNegTFCE: single;
+ lOutNameMod: string;
+begin
+ result := false;
+ if not NIFTIhdr_LoadHdr(lImageName,lHdr) then begin
+ ShowMsg('Error reading '+lImageName);
+ exit;
+ end;
+ lVolVox := lHdr.NIFTIhdr.dim[1]*lHdr.NIFTIhdr.dim[2]* lHdr.NIFTIhdr.dim[3];
+ if (lVolVox < 1) then exit;
+ getmem(lImg,lVolVox*sizeof(single));
+ if not LoadImg(lHdr.ImgFileName, lImg, 1, lVolVox,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMMsg('Unable to load ' +lHdr.ImgFileName);
+ exit;
+ end;
+ //lHdr.NIFTIhdr.scl_slope := 1; lHdr.NIFTIhdr.scl_inter := 0;
+ doTFCEbothPolarities (lHdr.NIFTIhdr, lImg, 6 {NumConn}, 2.0 {H}, 0.5 { E}, 0, 0,0,0 ,maxTFCE, maxNegTFCE);
+
+ lOutNameMod := ChangeFilePrefixExt(lImageName,'i','.hdr');
+ NPMMsg('Creating ' +lOutNameMod);
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lHdr.NIFTIhdr,true,not IsNifTiMagic(lHdr.NIFTIhdr),true,lImg,1);
+ freemem(lImg);
+end;*)
+
+
+function MakeMean ( lImages: TStrings; lBinarize,lVariance : boolean; lOutName: string): boolean;
+label
+ 667;
+var
+ lMaskname,lOutNameMod: string;
+ lMaskHdr: TMRIcroHdr;
+ lCountRA,lOutImgMn,lOutStDev,lPlankImg: SingleP;
+ lTotalMemory: double;
+ lMaskVoxels,lPlank,lVolVox,lPos,lMinMask,lMaxMask,lnPlanks,lVoxPerPlank,
+ lPos2,lPos2Offset,lStartVox,lEndVox,lPlankImgPos,lnTests,lnVoxTested,lPosPct: integer;
+ lStDev: boolean;
+ lT, lSum,lSumSqr,lSD, lMn,lTotalSum,lTotalN: double;
+ lStatHdr: TNIfTIhdr;
+ lFdata: file;
+begin
+
+ if lImages.count < 2 then begin
+ ShowMsg('Error: you must select at least two images');
+ exit;
+ end;
+ lMaskname := lImages[0];
+ if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
+ ShowMsg('Error reading '+lMaskName);
+ exit;
+ end;
+ lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
+ if not CheckVoxelsGroupX(lImages,lMaskHdr {lMaskVoxels}) then begin
+ ShowMsg('File dimensions differ from mask.');
+ exit;
+ end;
+
+
+ result := false;
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+
+ if (not lVariance) and (not lBinarize) then
+ lStDev := true
+ else
+ lStDev := false;
+ NPMMsg('Analysis began = ' +TimeToStr(Now));
+ lTotalMemory := 0;
+ lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
+ NPMMsg('Voxels = '+inttostr(lMaskVoxels)+' '+inttostr(kPlankSz));
+ if (lVolVox < 1) then goto 667;
+ lMinMask := 1;
+ lMaxMask := lVolVox;
+ lVoxPerPlank := kPlankSz div lImages.Count div sizeof(single) ;
+ if (lVoxPerPlank = 0) then goto 667; //no data
+ lTotalMemory := ((lMaxMask+1)-lMinMask) * lImages.Count;
+ if (lTotalMemory = 0) then goto 667; //no data
+ lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
+ NPMMsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
+ NPMMsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
+ // fx(kPlankSz,8888);
+ getmem(lPlankImg,kPlankSz);
+ lStartVox := lMinMask;
+ lEndVox := lMinMask-1;
+ NPMMsg('Number of scans = '+inttostr(lImages.count));
+ NPMMsg(' Index,Filename,Intercept,Slope');
+ if lBinarize then begin
+ getmem(lCountRA,lImages.Count*sizeof(single));
+ for lPos := 1 to lImages.Count do begin
+ gInterceptRA[lPos] := 0;
+ gScaleRA[lPos] := 1;
+ lCountRA^[lPos] := 0;
+ end;
+ end else begin
+ for lPos := 1 to lImages.Count do begin
+ NPMMsg(' '+inttostr(lPos)+','+lImages[lPos-1]+','+realtostr(gInterceptRA[lPos],4)+','+realtostr(gScaleRA[lPos],4));
+ if gScaleRA[lPos] = 0 then
+ gScaleRA[lPos] := 1;
+ end;
+ end;
+
+ lTotalSum := 0;
+ lTotalN := 0;
+ //createArray64(lObsp,lObs,lImages.Count);
+ getmem(lOutImgMn,lVolVox* sizeof(single));
+ if lStDev then
+ getmem(lOutStDev,lVolVox* sizeof(single));
+ for lPlank := 1 to lnPlanks do begin
+ NPMMsg('Computing plank = ' +Inttostr(lPlank));
+ Refresher;
+ lEndVox := lEndVox + lVoxPerPlank;
+ if lEndVox > lMaxMask then begin
+ lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
+ lEndVox := lMaxMask;
+ end;
+ lPlankImgPos := 1;
+ for lPos := 1 to lImages.Count do begin
+ if not LoadImg(lImages[lPos-1], lPlankImg, lStartVox, lEndVox,round(gOffsetRA[lPos]),lPlankImgPos,gDataTypeRA[lPos],lVolVox) then
+ goto 667;
+ lPlankImgPos := lPlankImgPos + lVoxPerPlank;
+ end;//for each image
+ lPosPct := lVoxPerPlank div 100;
+ for lPos2 := 1 to lVoxPerPlank do begin
+ if (lPos2 mod lPosPct) = 0 then begin
+ NPMProgressBar(round((lPos2/lVoxPerPlank)*100));
+ refresher;
+ end;
+ lPos2Offset := lPos2+lStartVox-1;
+ lSum := 0;
+ if lVariance then begin
+ lSum := sqr(lPlankImg^[lPos2]-lPlankImg^[lVoxPerPlank+lPos2]);//actually variance...
+ //% signal
+ //if lPlankImg[lVoxPerPlank+lPos2] <> 0 then
+
+ // lSum := lPlankImg[lPos2]/lPlankImg[lVoxPerPlank+lPos2]
+ //else
+ // lSum := 0;//pct signal...
+ //end % signal
+ lOutImgMn^[lPos2Offset] := lSum;
+ lTotalSum := lTotalSum + lOutImgMn^[lPos2Offset];
+ lTotalN := lTotalN + 1;
+ end else begin //not variance
+
+ if lBinarize then begin
+ for lPos := 1 to lImages.Count do
+ if lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2] <> 0 then begin
+ lSum := lSum+1;
+ lCountRA^[lPos] := lCountRA^[lPos] + 1;
+ end;
+ end else
+ for lPos := 1 to lImages.Count do
+ lSum := lSum +(gScaleRA[lPos]*lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2])+gInterceptRA[lPos];
+ // fx(lPos, gScaleRA[lPos],gInterceptRA[lPos]);
+ lOutImgMn^[lPos2Offset] := lSum/lImages.Count;
+ if lStDev then begin
+ //lSum := 0;
+ //for lPos := 1 to lImages.Count do
+ // lSum := lSum + (gScaleRA[lPos]*lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2])+gInterceptRA[lPos];
+ lSumSqr := 0;
+ for lPos := 1 to lImages.Count do
+ lSumSqr := lSumSqr + Sqr((gScaleRA[lPos]*lPlankImg^[((lPos-1)* lVoxPerPlank)+lPos2])+gInterceptRA[lPos]);
+ lSD := (lSumSqr - ((Sqr(lSum))/lImages.Count));
+ if (lSD > 0) then
+ lSD := Sqrt ( lSD/(lImages.Count-1))
+ else begin
+ lSD := 0;
+
+ end;
+ lOutStDev^[lPos2Offset] := lSD;
+ end;
+ end; //not variance
+ if lSum > 0 then begin
+ lTotalSum := lTotalSum + lOutImgMn^[lPos2Offset];
+ lTotalN := lTotalN + 1;
+ end;
+
+ end;
+ lStartVox := lEndVox + 1;
+ end;
+ if lBinarize then begin
+ for lPos := 1 to lImages.Count do begin
+ NPMMsg(' '+inttostr(lPos)+','+lImages[lPos-1]+','+inttostr(round(lCountRA^[lPos])) );
+
+ lCountRA^[lPos] := 0;
+ end;
+ freemem(lCountRA);
+ end; //if binar
+ //next: save data
+ MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
+//save mean
+
+
+if lVariance then
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'var','.hdr')
+else
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'Mean','.hdr');
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgMn,1);
+ freemem(lOutImgMn);
+ if lStDev then begin
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'StDev','.hdr');
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutStDev,1);
+ freemem(lOutStDev);
+ end;
+
+ //freemem(lObsp);
+ freemem(lPlankImg);
+ NPMMsg('Analysis finished = ' +TimeToStr(Now));
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes','.txt');
+ NPMMsgSave(lOutNameMod);
+ if (lTotalN > 0) then
+ NPMMsg('num voxels >0 = ' +inttostr(round(lTotalN))+' mean value for voxels >0: '+floattostr(lTotalSum/lTotalN));
+
+ NPMProgressBar(0);
+ exit;
+667: //you only get here if you aborted ... free memory and report error
+ if lTotalMemory > 1 then freemem(lPlankImg);
+ NPMMsg('Unable to complete analysis.');
+ NPMProgressBar(0);
+end;
+function ComputeLesionVolume (lImgName: string): integer;
+var
+ lHdr: TMRIcroHdr;
+ lImg: byteP;
+ lVolVox,lVox:integer;
+begin
+ result := -1; //error
+ NIFTIhdr_LoadHdr(lImgName,lHdr);
+ lVolVox := lHdr.NIFTIhdr.dim[1]*lHdr.NIFTIhdr.dim[2]* lHdr.NIFTIhdr.dim[3];
+ getmem(lImg,lVolVox*sizeof(byte));
+ if not LoadImg8(lImgName, lImg, 1, lVolVox,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMMsg('Unable to load ' +lHdr.ImgFileName);
+ freemem(lImg);
+ exit;
+ end;
+ result := 0;
+ for lVox := 1 to lVolVox do
+ if (lImg^[lVox] <> 0) then
+ inc(result);
+ freemem(lImg);
+end;
+
+function NPMAnalyze (var lImages: TStrings; var lMaskname: string; lMaskVoxels,lnGroup1: integer; lNPMPrefs: TNPMPrefs; var lOutName: string): boolean;
+
+label
+ 667;
+var
+ //lOutName,
+ lOutNameMod: string;
+ lMaskHdr: TMRIcroHdr;
+ lMaskImg,lPlankImg,lOutImgMn,lOutImgBM,lOutImgT,lDummy: SingleP;
+ lTotalMemory: double; //not integer - limit for 32bit int is 2Gb
+ lPlank,lVolVox,lPos,lMinMask,lMaxMask,lnPlanks,lVoxPerPlank,
+ lPos2,lPos2Offset,lStartVox,lEndVox,lPlankImgPos,lnTests,lnVoxTested,lThreadStart,lThreadEnd,lThreadInc: integer;
+ lT, lSum, lMn: double;
+ lStatHdr: TNIfTIhdr;
+ lFdata: file;
+ lThread: integer;
+ lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP;
+ lRanOrderp: pointer;
+ lRanOrder: Doublep0;
+begin
+ result := false;
+ NPMMsgClear;
+ NPMMsg(GetKVers);
+ NPMMsg('Threads: '+inttostr(gnCPUThreads));
+
+ NPMMsg('Mask name = '+ lMaskname);
+ NPMMsg('Total voxels = '+inttostr(lMaskVoxels));
+ NPMMsg('Scans in Group 1 = '+inttostr(lnGroup1));
+ NPMMsg('Scans in Group 2 = '+inttostr(lImages.count-lnGroup1));
+ if (lnGroup1 < 1) or ((lImages.count-lnGroup1) < 1) then begin
+ ShowMsg('Error: group size(s) too small');
+ exit;
+ end;
+
+ if not NIFTIhdr_LoadHdr(lMaskname,lMaskHdr) then begin
+ showMsg('Error reading mask.');
+ exit;
+ end;
+ lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
+ if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
+ ShowMsg('Mask file size too small.');
+ exit;
+ end;
+ if not CheckVoxelsGroupX(lImages,lMaskHdr ) then begin
+ ShowMsg('File dimensions differ from mask.');
+ exit;
+ end;
+
+
+ NPMmsg('Permutations = ' +IntToStr(lNPMPrefs.nPermute));
+ NPMmsg('Analysis began = ' +TimeToStr(Now));
+ lTotalMemory := 0;
+ lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
+ if (lVolVox < 1) then goto 667;
+ //load mask
+ getmem(lMaskImg,lVolVox*sizeof(single));
+ if not LoadImg(lMaskHdr.ImgFileName, lMaskImg, 1, lVolVox,round(gOffsetRA[0]),1,lMaskHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMmsg('Unable to load mask ' +lMaskHdr.ImgFileName);
+ goto 667;
+ end;
+ //next find start and end of mask
+ lPos := 0;
+ repeat
+ inc(lPos);
+ until (lMaskImg^[lPos] > 0) or (lPos = lVolVox);
+ lMinMask := lPos;
+ lPos := lVolVox+1;
+ repeat
+ dec(lPos);
+ until (lMaskImg^[lPos] > 0) or (lPos = 1);
+ lMaxMask := lPos;
+ if lMaxMask = 1 then begin
+ NPMmsg('Mask appears empty' +lMaskHdr.ImgFileName);
+ goto 667;
+ end;
+ NPMmsg('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
+ lVoxPerPlank := kPlankSz div lImages.Count div sizeof(single) ;
+ if (lVoxPerPlank = 0) then goto 667; //no data
+ lTotalMemory := ((lMaxMask+1)-lMinMask) * lImages.Count;
+ if (lTotalMemory = 0) then goto 667; //no data
+ lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lImages.Count) ) + 1;
+ NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lImages.Count)));
+ NPMmsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
+ getmem(lPlankImg,kPlankSz);
+ lStartVox := lMinMask;
+ lEndVox := lMinMask-1;
+ for lPos := 1 to lImages.Count do
+ if gScaleRA[lPos] = 0 then
+ gScaleRA[lPos] := 1;
+
+ getmem(lOutImgMn,lVolVox* sizeof(single));
+ getmem(lOutImgBM,lVolVox* sizeof(single));
+ getmem(lOutImgT,lVolVox* sizeof(single));
+ InitPermute (lImages.Count, lNPMPrefs.nPermute, lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp, lRanOrder);
+ for lPos := 1 to lVolVox do begin
+ lOutImgMn^[lPos] := 0;
+ lOutImgBM^[lPos] := 0;
+ lOutImgT^[lPos] := 0;
+ end;
+ ClearThreadData(gnCPUThreads,lNPMPrefs.nPermute);
+
+ for lPlank := 1 to lnPlanks do begin
+ NPMmsg('Computing plank = ' +Inttostr(lPlank));
+ Refresher;
+ lEndVox := lEndVox + lVoxPerPlank;
+ if lEndVox > lMaxMask then begin
+ lVoxPerPlank := lVoxPerPlank - (lEndVox-lMaxMask);
+ lEndVox := lMaxMask;
+ end;
+ lPlankImgPos := 1;
+ for lPos := 1 to lImages.Count do begin
+ if not LoadImg(lImages[lPos-1], lPlankImg, lStartVox, lEndVox,round(gOffsetRA[lPos]),lPlankImgPos,gDataTypeRA[lPos],lVolVox) then
+ goto 667;
+ lPlankImgPos := lPlankImgPos + lVoxPerPlank;
+ end;//for each image
+ //threading start
+ lThreadStart := 1;
+ lThreadInc := lVoxPerPlank div gnCPUThreads;
+ lThreadEnd := lThreadInc;
+ (*SHITTTT Application.processmessages;
+ for lThread := 1 to gnCPUThreads do begin
+ if lThread = gnCPUThreads then
+ lThreadEnd := lVoxPerPlank; //avoid integer rounding error
+ with TNNStat.Create (ProgressBar1,lttest,lBM,0, lnPermute,lThread,lThreadStart,lThreadEnd,lStartVox,lVoxPerPlank,lImages.Count,lnGroup1, lMaskImg,lPlankImg,lOutImgMn,lOutImgBM,lOutImgT,lDummy) do
+ {$IFDEF FPC} OnTerminate := @ThreadDone; {$ELSE}OnTerminate := ThreadDone;{$ENDIF}
+ inc(gThreadsRunning);
+ lThreadStart := lThreadEnd + 1;
+ lThreadEnd :=lThreadEnd + lThreadInc;
+ end; //for each thread
+ repeat
+ Application.processmessages;
+ until gThreadsRunning = 0;
+ Application.processmessages;
+ *)
+ //threading end
+ lStartVox := lEndVox + 1;
+ end;
+ lnVoxTested := SumThreadData(gnCPUThreads,lNPMPrefs.nPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM);
+ //next report findings
+ NPMmsg('Voxels tested = ' +Inttostr(lnVoxTested));
+ reportBonferroni('Std',lnVoxTested);
+ //next: save data
+(*savedata*)
+ MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
+//save mean
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'Mean','.hdr');
+ if lnVoxTested > 1 then
+
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgMn,1);
+ MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
+
+if (lNPMPrefs.ttest) and (lnVoxTestED > 1 ) then begin //save Ttest
+ //reportRange ('ttest', lVolVox, lnVoxTested, lOutImgT);
+ //next: convert t-scores to z scores
+ for lPos := 1 to lVolVox do
+ lOutImgT^[lPos] := TtoZ (lOutImgT^[lPos],lImages.Count-2);
+ for lPos := 1 to lNPMPrefs.nPermute do begin
+ lPermuteMaxT^[lPos] := TtoZ (lPermuteMaxT^[lPos],lImages.Count-2);
+ lPermuteMinT^[lPos] := TtoZ (lPermuteMinT^[lPos],lImages.Count-2);
+ end;
+
+ reportFDR ('ttest', lVolVox, lnVoxTested, lOutImgT);
+ reportPermute('ttest',lNPMPrefs.nPermute,lPermuteMaxT, lPermuteMinT);
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'ttest','.hdr');
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgT,1);
+end;
+if (lNPMPrefs.BMtest) and (lnVoxTested > 1 ) then begin //save Brunner Munzel
+ reportFDR ('BM', lVolVox, lnVoxTested, lOutImgBM);
+ reportPermute('BM',lNPMPrefs.nPermute,lPermuteMaxBM, lPermuteMinBM);
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'BM','.hdr');
+
+ {reportFDR ('absT', lVolVox, lnVoxTested, lOutImgBM);
+ reportPermute('absT',lnPermute,lPermuteMaxBM, lPermuteMinBM);
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'absT','.hdr');
+ }
+ //NIFTIhdr_SaveHdr(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr));
+ lOutNameMod := changefileext(lOutNameMod,'.img');
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgBM,1);
+end;(**)
+//next: close images
+ FreePermute (lNPMPrefs.nPermute,lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM, lRanOrderp);
+ freemem(lOutImgT);
+ freemem(lOutImgBM);
+ freemem(lOutImgMn);
+ //freemem(lObsp);
+ freemem(lMaskImg);
+ freemem(lPlankImg);
+ NPMmsg('Analysis finished = ' +TimeToStr(Now));
+ lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes','.txt');
+ NPMMsgSave(lOutNameMod);
+ NPMProgressBar(0);
+ result := true;
+ exit;
+667: //you only get here if you aborted ... free memory and report error
+ if lVolVox > 1 then freemem(lMaskImg);
+ if lTotalMemory > 1 then freemem(lPlankImg);
+ NPMmsg('Unable to complete analysis.');
+ NPMProgressBar(0);
+end;
+
+(*procedure MakeStatHdr (var lBGHdr,lStatHdr: TniftiHdr; lMinIntensity,lMaxIntensity,lIntent_p1,lIntent_p2,lIntent_p3: single; lIntent_code: smallint;lIntentName: string);
+var lIntentNameLen,lPos: integer;
+ lStr: string;
+begin
+ move(lBGHdr,lStatHdr,sizeof(TniftiHdr));
+ with lStatHdr do begin
+ magic :=kNIFTI_MAGIC_SEPARATE_HDR;
+ bitpix := 32; //32-bit real data
+ datatype := kDT_FLOAT;
+ scl_slope:= 1;
+ scl_inter:= 0;
+ glmin := round(lMinIntensity);
+ glmax := round(lMaxIntensity);
+ intent_code := lIntent_Code;// kNIFTI_INTENT_ESTIMATE;
+ intent_p1 := lIntent_p1;
+ intent_p2 := lIntent_p2;
+ intent_p3 := lIntent_p3;
+ lIntentNameLen := length(lIntentName);
+ descrip[1] := 'N';
+ descrip[2] := 'P';
+ descrip[3] := 'M';
+ if lIntent_code=kNIFTI_INTENT_TTEST then begin
+ descrip[4] := 't' ;
+ lStr := inttostr(trunc(lIntent_p1));
+ for lPos := 1 to length (lStr) do
+ descrip[4+lPos] := lStr[lPos] ;
+ end else
+ descrip[4] := 'z';
+ if lIntentNameLen > sizeof(intent_name) then
+ lIntentNameLen := sizeof(intent_name);
+ if lIntentNameLen > 0 then
+ for lPos := 1 to lIntentNameLen do
+ intent_name[lPos] := lIntentName[lPos];
+ end;
+end; *)
+
+function NPMzscore (var lImages: TStrings; var lMnHdr,lStDevHdr: TMRIcroHdr): boolean;
+label
+ 667;
+var
+ lOutNameMod: string;
+ lMnImg,lStDevImg,lSubjImg,lOutImg: SingleP;
+ lVal: single;
+ lSubj,lPos,lVolVox: integer;
+ lStatHdr: TNIfTIhdr;
+begin
+ result := false;
+ NPMMsg('Analysis began = ' +TimeToStr(Now));
+ lVolVox := lMnHdr.NIFTIhdr.dim[1]*lMnHdr.NIFTIhdr.dim[2]* lMnHdr.NIFTIhdr.dim[3];
+ if (lVolVox < 1) then goto 667;
+ //load mask
+ for lPos := 0 to lImages.Count do
+ if gScaleRA[lPos] = 0 then
+ gScaleRA[lPos] := 1;
+ if gScaleRA[kMaxImages] = 0 then
+ gScaleRA[kMaxImages] := 1;
+
+ getmem(lMnImg,lVolVox*sizeof(single));
+ if not LoadImg(lMnHdr.ImgFileName, lMnImg, 1, lVolVox,round(gOffsetRA[0]),1,lMnHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMMsg('Unable to load mean ' +lMnHdr.ImgFileName);
+ goto 667;
+ end;
+ //load StDev
+ getmem(lStDevImg,lVolVox*sizeof(single));
+ if not LoadImg(lStDevHdr.ImgFileName, lStDevImg, 1, lVolVox,round(gOffsetRA[kMaxImages]),1,lStDevHdr.NIFTIhdr.datatype,lVolVox) then begin
+ NPMMsg('Unable to load StDev ' +lStDevHdr.ImgFileName);
+ goto 667;
+ end;
+ getmem(lOutImg,lVolVox* sizeof(single));
+ for lPos := 1 to lVolVox do begin
+ lMnImg^[lPos] := (gScaleRA[0]*lMnImg^[lPos])+gInterceptRA[0];
+ lStDevImg^[lPos] := (gScaleRA[kMaxImages]*lStDevImg^[lPos])+gInterceptRA[kMaxImages];
+ if lStDevImg^[lPos] = 0 then
+ lOutImg^[lPos] := 0;
+ end;
+ getmem(lSubjImg,lVolVox* sizeof(single));
+ for lSubj := 1 to lImages.Count do begin
+ NPMProgressBar(round((lSubj/lImages.Count)*100));
+ NPMMsg( lImages.Strings[lSubj-1]);
+ ShowMsg(inttostr(round(gOffsetRA[lSubj])));
+ LoadImg(lImages.Strings[lSubj-1], lSubjImg, 1, lVolVox,round(gOffsetRA[lSubj]),1,gDataTypeRA[lSubj],lVolVox);
+ for lPos := 1 to lVolVox do begin
+ if lStDevImg^[lPos] <> 0 then begin
+ lVal := (gScaleRA[lSubj]*lSubjImg^[lPos])+gInterceptRA[lSubj];
+ lOutImg^[lPos] := (lVal-lMnImg^[lPos])/lStDevImg^[lPos];
+ end; //for each voxel with variance
+ end; //for each voxel
+ lOutNameMod := ChangeFilePostfixExt(lImages.Strings[lSubj-1],'Z','.hdr');
+ MakeStatHdr (lMnHdr.NIFTIhdr,lStatHdr,-6, 6,1{df},0,lVolVox,kNIFTI_INTENT_ZSCORE,inttostr(lVolVox) );
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMnHdr.NIFTIhdr),true,lOutImg,1);
+ end; //for each subj
+ freemem(lSubjImg);
+ freemem(lOutImg);
+ freemem(lMnImg);
+ freemem(lStDevImg);
+ NPMMsg('Analysis finished = ' +TimeToStr(Now));
+ NPMProgressBar(0);
+ result := true;
+ exit;
+667: //you only get here if you aborted ... free memory and report error
+ if lVolVox > 1 then freemem(lMnImg);
+ NPMMsg('Unable to complete analysis.');
+ NPMProgressBar(0);
+end;
+
+function ChangeName (lInName: string): string;
+var
+ lPath,lName,lExt: string;
+begin
+ FilenameParts (lInName, lPath,lName,lExt);
+ if length(lName) > 0 then
+ lName[1] := 'e'
+ else
+ lName := 'Unable to convert '+lInName;
+ result := lPath+lName+lExt;
+end;
+
+function Add2ndScans(var lImageNames: TStrings): boolean;
+var
+ lnSubj,lSubj: integer;
+ lFilename: string;
+begin
+ result := false;
+ lnSubj :=lImageNames.Count;
+ if lnSubj < 1 then
+ exit;
+ for lSubj := 1 to lnSubj do begin
+ lFilename := ChangeName(lImageNames[lSubj-1]);
+ if not (fileexists4D(lFilename)) then begin
+ ShowMsg('Unable to find a file named '+ lFilename);
+ exit;
+ end;
+ lImageNames.add(lFilename);
+ end;
+ result := true;
+end;
+
+procedure ComputePlankSize (var lPlankMB: integer);
+begin
+ if lPlankMB < 128 then
+ lPlankMB := 128;
+ {$IFDEF CPU32}
+ if lPlankMB > 1536 then
+ lPlankMB := 1536; //we use signed 32-bit pointers, so we can not exceed 2Gb
+ {$ELSE}
+ if lPlankMB > 8000 then
+ lPlankMB := 8000; //64-bit pointers, perhaps 8Gb is reasonable limit
+ {$ENDIF}
+ kPlankSz :=1024 {bytes/kb} * 1024 {bytes/mb} * lPlankMB;
+ //kVers := GetKVers + ' CacheMB = '+inttostr(kPlankMB);
+end;
+
+procedure DefaultPrefs( var lNPMPrefs: TNPMPrefs);
+begin
+ lNPMPrefs.NULP := true;
+ lNPMPrefs.ROI := true;
+ lNPMPrefs.TFCE := 0;
+ lNPMPrefs.ttest := true;
+ lNPMPrefs.BMtest := true;
+ lNPMPrefs.PlankMB := 512;
+ lNPMPrefs.nPermute := 0;
+ ComputePlankSize(lNPMPrefs.PlankMB);
+end;
+
+procedure ReadIniFile;
+var
+ lFilename: string;
+ lThreads: integer;
+ lIniFile: TIniFile;
+begin
+ DefaultPrefs(gNPMprefs);
+ lFilename := IniName;
+ if not FileexistsEx(lFilename) then
+ exit;
+
+ lIniFile := TIniFile.Create(lFilename);
+ //ttestmenu.checked := IniBool(lIniFile,'computettest',true);
+ //BMmenu.checked := IniBool(lIniFile,'computebm',false);
+ gNPMprefs.ttest := IniBool(lIniFile,'computettest',gNPMprefs.ttest);
+ gNPMprefs.BMtest := IniBool(lIniFile,'computebm',gNPMprefs.BMtest);
+ gNPMPrefs.NULP := IniBool(lIniFile,'countlesionpatterns',gNPMPrefs.NULP);
+ gNPMPrefs.ROI := IniBool(lIniFile,'ROI',gNPMPrefs.ROI);
+ gNPMPrefs.TFCE := IniInt(lIniFile,'TFCE',gNPMPrefs.TFCE);
+ gNPMPrefs.PlankMB := IniInt(lIniFile,'CacheMB',gNPMPrefs.PlankMB);
+ ComputePlankSize(gNPMPrefs.PlankMB);
+ gNPMPrefs.nPermute := IniInt(lIniFile,'nPermute',gNPMPrefs.nPermute);
+ //WritePermute(IniInt(lIniFile,'nPermute',0));
+ lThreads := IniInt(lIniFile,'nThread', gnCPUThreads );
+ if lThreads > gnCPUThreads then
+ lThreads := gnCPUThreads;
+ gnCPUThreads := lThreads;
+ ComputePlankSize(gNPMPrefs.PlankMB);
+ lIniFile.Free;
+end; //ReadIniFile
+
+procedure WriteIniFile;
+var
+ lIniName: string;
+ lIniFile: TIniFile;
+begin
+ lIniName := IniName;
+ if (DiskFreeEx(lIniName) < 1) then
+ exit;
+ lIniFile := TIniFile.Create(lIniName);
+ lIniFile.WriteString('BOOL', 'computettest',Bool2Char(gNPMprefs.ttest));
+ lIniFile.WriteString('BOOL', 'computebm',Bool2Char(gNPMprefs.BMtest));
+ lIniFile.WriteString('BOOL', 'countlesionpatterns',Bool2Char(gNPMPrefs.NULP));
+ lIniFile.WriteString('BOOL', 'ROI',Bool2Char(gNPMPrefs.ROI));
+ lIniFile.WriteString('INT', 'TFCE',inttostr(gNPMPrefs.TFCE));
+ lIniFile.WriteString('INT', 'CacheMB',inttostr(gNPMPrefs.PlankMB));
+ lIniFile.WriteString('INT', 'nPermute',inttostr(gNPMPrefs.nPermute));
+ lIniFile.WriteString('INT', 'nThread',inttostr(gnCPUThreads));
+ lIniFile.Free;
+end;
+
+procedure FreePermute (lnPermute: integer; var lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP;var lRanOrderp: pointer);
+begin
+ if (lnPermute < 2) then
+ exit;
+ Freemem(lRanOrderp);
+ Freemem(lPermuteMaxT);
+ Freemem(lPermuteMinT);
+ Freemem(lPermuteMaxBM);
+ Freemem(lPermuteMinBM);
+end;
+
+function ReportDescriptives (var RA: SingleP; n: integer): boolean;
+var lMn,lSD,lSE,lSkew,lZSkew: double;
+begin
+ SuperDescriptive (RA, n, lMn,lSD,lSE,lSkew,lZSkew);
+ NPMMsg('mean='+floattostr(lMn)+',StDev='+floattostr(lSD)+',StEr='+floattostr(lSE)+',Skew='+floattostr(lSkew)+',ZSkew='+floattostr(lZSkew));
+end;
+
+
+
+function ThreshMap(lThresh: single; lVolVox: integer;lOutImg: singleP): integer;
+var
+ lVox: integer;
+begin
+ result := 0;
+ for lVox := 1 to lVolVox do
+ if lOutImg^[lVox] >= lThresh then
+ inc(result);
+
+ for lVox := 1 to lVolVox do
+ if lOutImg^[lVox] >= lThresh then
+ lOutImg^[lVox] := 1
+ else
+ lOutImg^[lVox] := 0;
+end;
+
+procedure sort (lo, up: integer; var r:SingleP);
+//62ms Shell Sort http://www.dcc.uchile.cl/~rbaeza/handbook/algs/4/414.sort.p.html
+label 999;
+var d, i, j : integer;
+ tempr : single;
+begin
+ d := up-lo+1;
+ while d>1 do begin
+ if d<5 then
+ d := 1
+ else
+ d := trunc( 0.45454*d );
+ //Do linear insertion sort in steps size d
+ for i:=up-d downto lo do begin
+ tempr := r^[i];
+ j := i+d;
+ while j <= up do
+ if tempr > r^[j] then begin
+ r^[j-d] := r^[j];
+ j := j+d
+ end
+ else goto 999; //break
+ 999:
+ r^[j-d] := tempr
+ end //for
+ end //while
+end; //proc Sort
+
+function IndexPct(lnPermute: integer; lPct: single; lTop: boolean): integer;
+begin
+ result := round(lnPermute * lPct);
+ if lTop then
+ result := (lnPermute - result)+1;
+ if (result < 1) then
+ result := 1;
+ if (result > lnPermute) then
+ result := lnPermute;
+end;
+
+function ReportThresh (lLabel: string; lnPermute: integer; var lRankedData: singleP;lTop:boolean): double;
+begin
+ result := lRankedData^[IndexPct(lnPermute,0.050,lTop)];
+ NPMmsg(lLabel+': permutationFWE '+
+ //'0.500='+realtostr(lRankedData[IndexPct(lnPermute,0.500,lTop)],3)+
+ ', 0.050='+realtostr({lRankedData^[IndexPct(lnPermute,0.050,lTop)]} result,8)+
+ ', 0.025='+realtostr(lRankedData^[IndexPct(lnPermute,0.025,lTop)],8)+
+ ', 0.01='+realtostr(lRankedData^[IndexPct(lnPermute,0.010,lTop)],8)+
+ ' ');
+end;
+
+function reportPermute (lLabel:string; lnPermute: integer; var lPermuteMaxZ, lPermuteMinZ: singleP): double;
+begin
+ result := 0;
+ if (lnPermute < 2) then
+ exit;
+ sort (1, lnPermute,lPermuteMaxZ);
+ result := ReportThresh(lLabel+'+',lnPermute,lPermuteMaxZ,true);
+ sort (1, lnPermute,lPermuteMinZ);
+ ReportThresh(lLabel+'-',lnPermute,lPermuteMinZ,false);
+ //for lPos := 1 to lnPermute do
+ // msg(inttostr(lPos)+', '+realtostr(lPermuteMinZ[lPos],4));
+
+end;
+
+function reportFDR (lLabel:string; lnVox, lnTests: integer; var lData: SingleP): double;
+var
+ lC,lN: integer;
+ lPs: SingleP;
+ lFDR05r, lFDR01r,lFDR05p, lFDR01p,lMin,lMax : double;
+begin
+ result := 10000;
+ if (lnTests < 1) or (lnVox < 1) then
+ exit;
+ GetMem(lPs,lnTests*sizeof(single));
+ for lC := 1 to lnTests do
+ lPs^[lC] := 0;
+ lN := 0;
+ lMin := 0;
+ lMax := 0;
+ for lC := 1 to lnVox do begin
+ if lData^[lC] <> 0 then begin
+ inc(lN);
+ if lData^[lC] > lMax then lMax := lData^[lC]
+ else if lData^[lC] < lMin then lMin := lData^[lC];
+ if lN <= lnTests then
+ lPs^[lN] := pNormal(lData^[lC]);
+ end;
+ end;
+ EstimateFDR2(lnTests, lPs, lFDR05p, lFDR01p,lFDR05r, lFDR01r);
+ NPMmsg(lLabel+' Range '
+ +realtostr(lMin,3)+
+ '...'+realtostr(lMax,3));
+ {Msg(lLabel+' Range '
+ +realtostr(pNormalInv(lPs[lnTests]),3)+
+ '...'+realtostr(pNormalInv(lPs[1]),3)+
+ ' '); } //we could use this and save time computing lmin/lmax, but loss in precision
+ NPMmsg(lLabel+' +FDR Z '+
+ '0.050='+realtostr(pNormalInv(lFDR05p),8)+
+ ', 0.01='+realtostr(pNormalInv(lFDR01p),8)+
+ ' ');
+ NPMmsg(lLabel+' -FDR Z '+
+ '0.050='+realtostr(pNormalInv(1-lFDR05r),8)+
+ ', 0.01='+realtostr(pNormalInv(1-lFDR01r),8)+
+ ' ');
+ result := pNormalInv(lFDR01p);
+end;
+
+
+function reportBonferroni(lLabel: string; lnTests: integer): double; //returns 5% Z score
+begin
+ if lnTests < 1 then exit;
+ result := pNormalInv(0.05/lnTests);
+ NPMmsg(inttostr(lnTests)+' test '+lLabel+' Bonferroni FWE Z '+
+ '0.050='+realtostr(result,3)+
+ ', 0.025='+realtostr(pNormalInv(0.025/lnTests),3)+
+ ', 0.01='+realtostr(pNormalInv(0.01/lnTests),3));
+end;
+
+
+procedure NPMThreadDone;
+begin
+ Dec(gThreadsRunning);
+end;
+
+
+procedure InitRA (lnPermute: integer; var lRA: singleP);
+var
+ lInc: integer;
+begin
+ getmem(lRA,lnPermute* sizeof(single));
+ for lInc := 1 to lnPermute do
+ lRA^[lInc] := 0;
+end;
+
+procedure InitPermute (lnSubj, lnPermute: integer; var lPermuteMaxT, lPermuteMinT,lPermuteMaxBM, lPermuteMinBM: singleP; var lRanOrderp: pointer; var lRanOrder: Doublep0);
+begin
+ if (lnPermute < 2) then
+ exit;
+ InitRA(lnPermute,lPermuteMaxT);
+ InitRA(lnPermute,lPermuteMinT);
+ InitRA(lnPermute,lPermuteMaxBM);
+ InitRA(lnPermute,lPermuteMinBM);
+ createArray64(lRanOrderp,lRanOrder,lnSubj);
+end; //init permute
+
+initialization
+ {$IFNDEF GUI}
+ NPMmemo:= TStringList.Create;
+ {$ENDIF}
+
+finalization
+{$IFNDEF GUI}
+ NPMmemo.Free;
+{$ENDIF}
+end.
+
diff --git a/npm/upower.pas b/npm/upower.pas
old mode 100644
new mode 100755
index f0626d4..da55d0e
--- a/npm/upower.pas
+++ b/npm/upower.pas
@@ -1,7 +1,7 @@
unit upower;
interface
-uses define_types, statcr, distr, dialogs;
+uses define_types, statcr, distr, dialogsx;
function Sum2Power(lOutImgSum: SingleP; lVolVox,lnTotal,lnDeficit: integer; lBinomial: boolean): boolean;
function Sum2PowerCont(lOutImgSum: SingleP; lVolVox,lnTotal: integer): boolean;
function Sum2PowerBinom(lOutImgSum: SingleP; lVolVox,lnTotal,lnDeficit: integer): boolean;
@@ -78,7 +78,7 @@ begin
if (lnTotal < 2) or (lnDeficit < 1) or (lVolVox < 1) then
exit;
if(lnDeficit >= lnTotal) then begin
- showmessage('Sum2Power error: people with deficit must be less than sample size');
+ ShowMsg('Sum2Power error: people with deficit must be less than sample size');
exit;
end;
getmem(lDensityPowerRA,lnTotal* sizeof(single));
@@ -113,4 +113,4 @@ begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/npm/valformat.pas b/npm/valformat.pas
old mode 100644
new mode 100755
index ed710d8..3de7f47
--- a/npm/valformat.pas
+++ b/npm/valformat.pas
@@ -3,9 +3,10 @@ unit valformat;
interface
uses
{$IFNDEF UNIX} Windows,{Registry,ShlObj,}{$ENDIF}
- Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- Grids, Menus, ToolWin, ComCtrls, Buttons,Clipbrd, StdCtrls,
- Spin,define_types,npmform;
+ //Messages, Graphics, Controls, Forms, Dialogs,
+ SysUtils, Classes,dialogsx,
+ //Grids, Menus, ToolWin, ComCtrls, Buttons,Clipbrd, StdCtrls,Spin, ,npmform
+ define_types;
const
{$IFDEF FPC}
kNaN = -maxint;
@@ -28,7 +29,7 @@ implementation
procedure MsgX (lStr: string);
begin
//output something here
- showmessage(lStr);
+ showmsg(lStr);
end;
@@ -110,7 +111,7 @@ begin
lExt := StrLower(PChar(extractfileext(lFilename)));
if (lExt = kTxtExt) or (lExt = kVALNativeExt) then
else begin
- Showmessage('This version is unable to recognize the extension of the file: '+lFilename);
+ ShowMsg('This version is unable to recognize the extension of the file: '+lFilename);
exit;
end;
lDecimalSep := DecimalSeparator;
@@ -125,7 +126,7 @@ begin
if lExt = kVALNativeExt then begin
ReadlnX(F,lStr);//Version
if not VALNativeSignature(lStr) then begin
- showmessage('This software can not read this file. Perhaps you need to upgrade your software. The first line should read "'+kVALNativeSignatureBase+'x" where "x" is <'+inttostr(kValMaxVers+1));
+ showMsg('This software can not read this file. Perhaps you need to upgrade your software. The first line should read "'+kVALNativeSignatureBase+'x" where "x" is <'+inttostr(kValMaxVers+1));
CloseFile(F);
FileMode := 2; //Set file access to read/write
exit;
@@ -141,7 +142,7 @@ begin
if lCmdStr = '#CritPct' then
lnCritPct := StrToInt(ReadTabStr(lStr,lPos));
end;
- if (length(lStr)> 0) and (lStr[1] = '#') then showmessage(lCmdStr);
+ if (length(lStr)> 0) and (lStr[1] = '#') then showmsg(lCmdStr);
end else begin
lnCritPct := 0;
lDesignUnspecified := true;
@@ -214,7 +215,7 @@ lnCol := MaxC-1;
except
on EConvertError do begin
if not lError then
- showmessage('Empty cells? Error reading VAL file row:'+inttostr(R)+' col:'+inttostr(C)+' - Unable to convert the string '+lNumStr+' to a number');
+ showmsg('Empty cells? Error reading VAL file row:'+inttostr(R)+' col:'+inttostr(C)+' - Unable to convert the string '+lNumStr+' to a number');
lError := true;
lTempFloat := knan;
end;
@@ -297,4 +298,4 @@ end;
end.
-
+
\ No newline at end of file
diff --git a/npm/windowsxp.res b/npm/windowsxp.res
old mode 100644
new mode 100755
diff --git a/npm/xLesionStatThds.pas b/npm/xLesionStatThds.pas
old mode 100644
new mode 100755
diff --git a/npm/xanacom.pas b/npm/xanacom.pas
old mode 100644
new mode 100755
diff --git a/npm/xmontecarlo.pas b/npm/xmontecarlo.pas
old mode 100644
new mode 100755
diff --git a/npm/zconf.inc b/npm/zconf.inc
old mode 100644
new mode 100755
diff --git a/npm/Copy of npm.cfg b/npm_precl/Copy of npm.cfg
old mode 100644
new mode 100755
similarity index 100%
copy from npm/Copy of npm.cfg
copy to npm_precl/Copy of npm.cfg
diff --git a/npm/Copy of prefs.pas b/npm_precl/Copy of prefs.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/Copy of prefs.pas
copy to npm_precl/Copy of prefs.pas
diff --git a/npm/Copy of turbolesion.pas b/npm_precl/Copy of turbolesion.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/Copy of turbolesion.pas
copy to npm_precl/Copy of turbolesion.pas
diff --git a/npm/LesionStatThds.pas b/npm_precl/LesionStatThds.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/LesionStatThds.pas
copy to npm_precl/LesionStatThds.pas
diff --git a/npm/Mat.pas b/npm_precl/Mat.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/Mat.pas
copy to npm_precl/Mat.pas
diff --git a/npm/ReadFloat.dfm b/npm_precl/ReadFloat.dfm
old mode 100644
new mode 100755
similarity index 100%
copy from npm/ReadFloat.dfm
copy to npm_precl/ReadFloat.dfm
diff --git a/npm/ReadFloat.pas b/npm_precl/ReadFloat.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/ReadFloat.pas
copy to npm_precl/ReadFloat.pas
diff --git a/npm/ReadInt.dfm b/npm_precl/ReadInt.dfm
old mode 100644
new mode 100755
similarity index 100%
copy from npm/ReadInt.dfm
copy to npm_precl/ReadInt.dfm
diff --git a/npm/ReadInt.lfm b/npm_precl/ReadInt.lfm
old mode 100644
new mode 100755
similarity index 100%
copy from npm/ReadInt.lfm
copy to npm_precl/ReadInt.lfm
diff --git a/npm/ReadInt.lrs b/npm_precl/ReadInt.lrs
old mode 100644
new mode 100755
similarity index 100%
copy from npm/ReadInt.lrs
copy to npm_precl/ReadInt.lrs
diff --git a/npm/ReadInt.pas b/npm_precl/ReadInt.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/ReadInt.pas
copy to npm_precl/ReadInt.pas
diff --git a/npm/StatThds.pas b/npm_precl/StatThds.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/StatThds.pas
copy to npm_precl/StatThds.pas
diff --git a/npm/StatThdsUtil.pas b/npm_precl/StatThdsUtil.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/StatThdsUtil.pas
copy to npm_precl/StatThdsUtil.pas
diff --git a/npm/Vector.pas b/npm_precl/Vector.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/Vector.pas
copy to npm_precl/Vector.pas
diff --git a/npm/anacom.pas b/npm_precl/anacom.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/anacom.pas
copy to npm_precl/anacom.pas
diff --git a/npm/associate.pas b/npm_precl/associate.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/associate.pas
copy to npm_precl/associate.pas
diff --git a/npm/brunner.pas b/npm_precl/brunner.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/brunner.pas
copy to npm_precl/brunner.pas
diff --git a/npm/design.dfm b/npm_precl/design.dfm
old mode 100644
new mode 100755
similarity index 100%
copy from npm/design.dfm
copy to npm_precl/design.dfm
diff --git a/npm/design.lfm b/npm_precl/design.lfm
old mode 100644
new mode 100755
similarity index 100%
copy from npm/design.lfm
copy to npm_precl/design.lfm
diff --git a/npm/design.lrs b/npm_precl/design.lrs
old mode 100644
new mode 100755
similarity index 100%
copy from npm/design.lrs
copy to npm_precl/design.lrs
diff --git a/npm/design.pas b/npm_precl/design.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/design.pas
copy to npm_precl/design.pas
diff --git a/npm/dice.ico b/npm_precl/dice.ico
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dice.ico
copy to npm_precl/dice.ico
diff --git a/npm/dmath/GraphicsMathLibrary.pas b/npm_precl/dmath/GraphicsMathLibrary.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/GraphicsMathLibrary.pas
copy to npm_precl/dmath/GraphicsMathLibrary.pas
diff --git a/npm/dmath/Matrices.pas b/npm_precl/dmath/Matrices.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/Matrices.pas
copy to npm_precl/dmath/Matrices.pas
diff --git a/npm/dmath/Regress.pas b/npm_precl/dmath/Regress.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/Regress.pas
copy to npm_precl/dmath/Regress.pas
diff --git a/npm/dmath/_clean.bat b/npm_precl/dmath/_clean.bat
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/_clean.bat
copy to npm_precl/dmath/_clean.bat
diff --git a/npm/dmath/eigen.pas b/npm_precl/dmath/eigen.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/eigen.pas
copy to npm_precl/dmath/eigen.pas
diff --git a/npm/dmath/fcomp.pas b/npm_precl/dmath/fcomp.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fcomp.pas
copy to npm_precl/dmath/fcomp.pas
diff --git a/npm/dmath/fitexlin.pas b/npm_precl/dmath/fitexlin.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitexlin.pas
copy to npm_precl/dmath/fitexlin.pas
diff --git a/npm/dmath/fitexpo.pas b/npm_precl/dmath/fitexpo.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitexpo.pas
copy to npm_precl/dmath/fitexpo.pas
diff --git a/npm/dmath/fitfrac.pas b/npm_precl/dmath/fitfrac.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitfrac.pas
copy to npm_precl/dmath/fitfrac.pas
diff --git a/npm/dmath/fithill.pas b/npm_precl/dmath/fithill.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fithill.pas
copy to npm_precl/dmath/fithill.pas
diff --git a/npm/dmath/fitiexpo.pas b/npm_precl/dmath/fitiexpo.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitiexpo.pas
copy to npm_precl/dmath/fitiexpo.pas
diff --git a/npm/dmath/fitlin.pas b/npm_precl/dmath/fitlin.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitlin.pas
copy to npm_precl/dmath/fitlin.pas
diff --git a/npm/dmath/fitlogis.pas b/npm_precl/dmath/fitlogis.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitlogis.pas
copy to npm_precl/dmath/fitlogis.pas
diff --git a/npm/dmath/fitmich.pas b/npm_precl/dmath/fitmich.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitmich.pas
copy to npm_precl/dmath/fitmich.pas
diff --git a/npm/dmath/fitmult.pas b/npm_precl/dmath/fitmult.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitmult.pas
copy to npm_precl/dmath/fitmult.pas
diff --git a/npm/dmath/fitpka.pas b/npm_precl/dmath/fitpka.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitpka.pas
copy to npm_precl/dmath/fitpka.pas
diff --git a/npm/dmath/fitpoly.pas b/npm_precl/dmath/fitpoly.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitpoly.pas
copy to npm_precl/dmath/fitpoly.pas
diff --git a/npm/dmath/fitpower.pas b/npm_precl/dmath/fitpower.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fitpower.pas
copy to npm_precl/dmath/fitpower.pas
diff --git a/npm/dmath/fmath.pas b/npm_precl/dmath/fmath.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fmath.pas
copy to npm_precl/dmath/fmath.pas
diff --git a/npm/dmath/fourier.pas b/npm_precl/dmath/fourier.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/fourier.pas
copy to npm_precl/dmath/fourier.pas
diff --git a/npm/dmath/matcomp.pas b/npm_precl/dmath/matcomp.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/matcomp.pas
copy to npm_precl/dmath/matcomp.pas
diff --git a/npm/dmath/math387.inc b/npm_precl/dmath/math387.inc
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/math387.inc
copy to npm_precl/dmath/math387.inc
diff --git a/npm/dmath/mathp2.inc b/npm_precl/dmath/mathp2.inc
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/mathp2.inc
copy to npm_precl/dmath/mathp2.inc
diff --git a/npm/dmath/mcmc.pas b/npm_precl/dmath/mcmc.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/mcmc.pas
copy to npm_precl/dmath/mcmc.pas
diff --git a/npm/dmath/models.pas b/npm_precl/dmath/models.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/models.pas
copy to npm_precl/dmath/models.pas
diff --git a/npm/dmath/optim.pas b/npm_precl/dmath/optim.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/optim.pas
copy to npm_precl/dmath/optim.pas
diff --git a/npm/dmath/pastring.pas b/npm_precl/dmath/pastring.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/pastring.pas
copy to npm_precl/dmath/pastring.pas
diff --git a/npm/dmath/plot.inc b/npm_precl/dmath/plot.inc
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/plot.inc
copy to npm_precl/dmath/plot.inc
diff --git a/npm/dmath/plot.pas b/npm_precl/dmath/plot.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/plot.pas
copy to npm_precl/dmath/plot.pas
diff --git a/npm/dmath/plotvar.inc b/npm_precl/dmath/plotvar.inc
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/plotvar.inc
copy to npm_precl/dmath/plotvar.inc
diff --git a/npm/dmath/polynom.pas b/npm_precl/dmath/polynom.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/polynom.pas
copy to npm_precl/dmath/polynom.pas
diff --git a/npm/dmath/regmultdelphi.pas b/npm_precl/dmath/regmultdelphi.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/regmultdelphi.pas
copy to npm_precl/dmath/regmultdelphi.pas
diff --git a/npm/dmath/simopt.pas b/npm_precl/dmath/simopt.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/simopt.pas
copy to npm_precl/dmath/simopt.pas
diff --git a/npm/dmath/stat.pas b/npm_precl/dmath/stat.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/stat.pas
copy to npm_precl/dmath/stat.pas
diff --git a/npm/dmath/texplot.pas b/npm_precl/dmath/texplot.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/texplot.pas
copy to npm_precl/dmath/texplot.pas
diff --git a/npm/dmath/winplot.pas b/npm_precl/dmath/winplot.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/dmath/winplot.pas
copy to npm_precl/dmath/winplot.pas
diff --git a/dcm2nii/extrafpc.cfg b/npm_precl/extrafpc.cfg
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/extrafpc.cfg
copy to npm_precl/extrafpc.cfg
diff --git a/npm/filename.pas b/npm_precl/filename.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/filename.pas
copy to npm_precl/filename.pas
diff --git a/npm/firth.pas b/npm_precl/firth.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/firth.pas
copy to npm_precl/firth.pas
diff --git a/npm/firthThds.pas b/npm_precl/firthThds.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/firthThds.pas
copy to npm_precl/firthThds.pas
diff --git a/npm/fpc-res.or b/npm_precl/fpc-res.or
old mode 100644
new mode 100755
similarity index 100%
copy from npm/fpc-res.or
copy to npm_precl/fpc-res.or
diff --git a/npm/fpc-res.res b/npm_precl/fpc-res.res
old mode 100644
new mode 100755
similarity index 100%
copy from npm/fpc-res.res
copy to npm_precl/fpc-res.res
diff --git a/npm/hdr.pas b/npm_precl/hdr.pas
old mode 100644
new mode 100755
similarity index 96%
copy from npm/hdr.pas
copy to npm_precl/hdr.pas
index 37037e6..76701b2
--- a/npm/hdr.pas
+++ b/npm_precl/hdr.pas
@@ -155,7 +155,7 @@ begin
result := false;
lHdrName := Filename4D(lHdrNameIn);
if not NIFTIhdr_LoadHdr(lHdrName,lHdr) then begin
- MainForm.NPMmsg('Unable to load image '+lHdrName);
+ MainForm.NPMmsg('Unable to load image '+lHdrName+' Possible solution: make sure VAL file and images are in the same folder');
exit;
end;
(*lVox := ComputeImageDataBytes8bpp(lHdr);
@@ -210,7 +210,7 @@ begin
lHdrName:= lG[lC-1];
if not CheckVoxelsX(lHdrName, lMaskHdr,lC) then begin
if not fileexists (lHdrName) then
- MainForm.NPMmsg('File not found "'+lHdrName+'"')
+ MainForm.NPMmsg('File not found "'+lHdrName+'". Possible solution: make sure VAL file and images are in the same folder')
else
MainForm.NPMmsg('Problem with "'+lHdrName);
diff --git a/npm/lesion_pattern.pas b/npm_precl/lesion_pattern.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/lesion_pattern.pas
copy to npm_precl/lesion_pattern.pas
diff --git a/npm/montecarlo.pas b/npm_precl/montecarlo.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/montecarlo.pas
copy to npm_precl/montecarlo.pas
diff --git a/npm/nifti_img.pas b/npm_precl/nifti_img.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/nifti_img.pas
copy to npm_precl/nifti_img.pas
diff --git a/npm/npm.app/Contents/Info.plist b/npm_precl/npm.app/Contents/Info.plist
old mode 100644
new mode 100755
similarity index 100%
copy from npm/npm.app/Contents/Info.plist
copy to npm_precl/npm.app/Contents/Info.plist
diff --git a/npm/npm.app/Contents/MacOS/npm b/npm_precl/npm.app/Contents/MacOS/npm
old mode 100644
new mode 100755
similarity index 100%
copy from npm/npm.app/Contents/MacOS/npm
copy to npm_precl/npm.app/Contents/MacOS/npm
diff --git a/dcm2nii/dcm2nii.app/Contents/PkgInfo b/npm_precl/npm.app/Contents/PkgInfo
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/dcm2nii.app/Contents/PkgInfo
copy to npm_precl/npm.app/Contents/PkgInfo
diff --git a/npm/npm.cfg b/npm_precl/npm.cfg
old mode 100644
new mode 100755
similarity index 73%
copy from npm/npm.cfg
copy to npm_precl/npm.cfg
index 22d5940..c599db3
--- a/npm/npm.cfg
+++ b/npm_precl/npm.cfg
@@ -1,4 +1,4 @@
--$A+
+-$A8
-$B-
-$C+
-$D+
@@ -31,7 +31,8 @@
-M
-$M16384,1048576
-K$00400000
--LN"c:\program files\borland\delphi4\Lib"
+-LE"c:\program files (x86)\borland\delphi7\Projects\Bpl"
+-LN"c:\program files (x86)\borland\delphi7\Projects\Bpl"
-U"C:\pas\mricron\common;C:\pas\mricron\fpmath"
-O"C:\pas\mricron\common;C:\pas\mricron\fpmath"
-I"C:\pas\mricron\common;C:\pas\mricron\fpmath"
diff --git a/dcm2nii/dcm2niigui.dof b/npm_precl/npm.dof
old mode 100644
new mode 100755
similarity index 85%
copy from dcm2nii/dcm2niigui.dof
copy to npm_precl/npm.dof
index 97da3dd..7fdd741
--- a/dcm2nii/dcm2niigui.dof
+++ b/npm_precl/npm.dof
@@ -94,7 +94,7 @@ OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
-SearchPath=..\common\;C:\pas\d4\RX\Units\
+SearchPath=C:\pas\mricron\common;C:\pas\mricron\fpmath
Packages=Vcl40;Vclx40;VclSmp40;Qrpt40;Vcldb40;RxCtl4
Conditionals=
DebugSourceDirs=
@@ -110,10 +110,10 @@ ActiveLang=
ProjectLang=
RootDir=
[Version Info]
-IncludeVerInfo=1
+IncludeVerInfo=0
AutoIncBuild=0
-MajorVer=0
-MinorVer=9
+MajorVer=1
+MinorVer=0
Release=0
Build=0
Debug=0
@@ -126,7 +126,7 @@ CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
-FileVersion=0.9.0.0
+FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
@@ -138,7 +138,6 @@ Comments=
Count=1
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
[HistoryLists\hlSearchPath]
-Count=3
-Item0=..\common\;C:\pas\d4\RX\Units\
-Item1=..\common\;C:\pas\d4\RX\Units
-Item2=..\common\
+Count=2
+Item0=C:\pas\mricron\common;C:\pas\mricron\fpmath
+Item1=C:\pas\mricron\common
diff --git a/npm/npm.dpr b/npm_precl/npm.dpr
old mode 100644
new mode 100755
similarity index 100%
copy from npm/npm.dpr
copy to npm_precl/npm.dpr
diff --git a/npm/npm.ini b/npm_precl/npm.ini
old mode 100644
new mode 100755
similarity index 73%
copy from npm/npm.ini
copy to npm_precl/npm.ini
index e3e4fad..f143f52
--- a/npm/npm.ini
+++ b/npm_precl/npm.ini
@@ -6,5 +6,6 @@ ROI=1
[INT]
CacheMB=512
-nPermute=0
+nPermute=4000
nThread=2
+TFCE=0
diff --git a/npm/npm.lpi b/npm_precl/npm.lpi
old mode 100644
new mode 100755
similarity index 70%
copy from npm/npm.lpi
copy to npm_precl/npm.lpi
index 0ba1297..30c8664
--- a/npm/npm.lpi
+++ b/npm_precl/npm.lpi
@@ -1,19 +1,21 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
+ <Version Value="9"/>
<PathDelim Value="\"/>
- <Version Value="7"/>
<General>
<Flags>
<LRSInOutputDirectory Value="False"/>
</Flags>
<MainUnit Value="0"/>
- <TargetFileExt Value=".exe"/>
- <ActiveEditorIndexAtStart Value="2"/>
+ <ActiveWindowIndexAtStart Value="0"/>
</General>
<VersionInfo>
- <ProjectVersion Value=""/>
+ <StringTable ProductVersion=""/>
</VersionInfo>
+ <BuildModes Count="1">
+ <Item1 Name="default" Default="True"/>
+ </BuildModes>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
@@ -31,108 +33,117 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
- <Units Count="55">
+ <Units Count="57">
<Unit0>
<Filename Value="npm.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="npm"/>
- <CursorPos X="8" Y="13"/>
- <TopLine Value="1"/>
<EditorIndex Value="0"/>
- <UsageCount Value="39"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="8" Y="13"/>
+ <UsageCount Value="45"/>
<Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
</Unit0>
<Unit1>
<Filename Value="npmform.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
+ <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="npmform"/>
- <CursorPos X="47" Y="1490"/>
- <TopLine Value="1476"/>
+ <IsVisibleTab Value="True"/>
<EditorIndex Value="4"/>
- <UsageCount Value="39"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="224"/>
+ <CursorPos X="7" Y="250"/>
+ <UsageCount Value="45"/>
<Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
</Unit1>
<Unit2>
<Filename Value="nifti_hdr.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="nifti_hdr"/>
- <CursorPos X="49" Y="368"/>
<TopLine Value="358"/>
- <UsageCount Value="35"/>
+ <CursorPos X="49" Y="368"/>
+ <UsageCount Value="41"/>
</Unit2>
<Unit3>
<Filename Value="define_types.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="define_types"/>
- <CursorPos X="38" Y="959"/>
<TopLine Value="945"/>
- <UsageCount Value="35"/>
+ <CursorPos X="38" Y="959"/>
+ <UsageCount Value="41"/>
</Unit3>
<Unit4>
<Filename Value="GraphicsMathLibrary.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="GraphicsMathLibrary"/>
- <CursorPos X="1" Y="738"/>
<TopLine Value="681"/>
- <UsageCount Value="35"/>
+ <CursorPos X="1" Y="738"/>
+ <UsageCount Value="41"/>
</Unit4>
<Unit5>
<Filename Value="distr.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="distr"/>
- <CursorPos X="1" Y="107"/>
<TopLine Value="99"/>
- <UsageCount Value="35"/>
+ <CursorPos X="1" Y="107"/>
+ <UsageCount Value="41"/>
</Unit5>
<Unit6>
<Filename Value="statcr.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="statcr"/>
- <CursorPos X="34" Y="6"/>
<TopLine Value="1"/>
- <UsageCount Value="35"/>
+ <CursorPos X="34" Y="6"/>
+ <UsageCount Value="41"/>
</Unit6>
<Unit7>
<Filename Value="stats.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="stats"/>
- <CursorPos X="41" Y="370"/>
<TopLine Value="369"/>
- <UsageCount Value="35"/>
+ <CursorPos X="41" Y="370"/>
+ <UsageCount Value="41"/>
</Unit7>
<Unit8>
<Filename Value="brunner.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="brunner"/>
- <CursorPos X="29" Y="517"/>
<TopLine Value="500"/>
- <UsageCount Value="35"/>
+ <CursorPos X="29" Y="517"/>
+ <UsageCount Value="41"/>
</Unit8>
<Unit9>
<Filename Value="StatThdsUtil.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="StatThdsUtil"/>
- <CursorPos X="69" Y="6"/>
<TopLine Value="1"/>
- <UsageCount Value="35"/>
+ <CursorPos X="69" Y="6"/>
+ <UsageCount Value="41"/>
</Unit9>
<Unit10>
<Filename Value="StatThds.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="StatThds"/>
- <CursorPos X="59" Y="478"/>
- <TopLine Value="466"/>
- <UsageCount Value="35"/>
+ <EditorIndex Value="9"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="17"/>
+ <CursorPos X="11" Y="127"/>
+ <UsageCount Value="41"/>
+ <Loaded Value="True"/>
</Unit10>
<Unit11>
<Filename Value="valformat.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="valformat"/>
- <CursorPos X="1" Y="91"/>
<TopLine Value="64"/>
- <UsageCount Value="35"/>
+ <CursorPos X="1" Y="91"/>
+ <UsageCount Value="41"/>
</Unit11>
<Unit12>
<Filename Value="design.pas"/>
@@ -141,11 +152,13 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="design"/>
- <CursorPos X="24" Y="52"/>
- <TopLine Value="37"/>
<EditorIndex Value="3"/>
- <UsageCount Value="34"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="37"/>
+ <CursorPos X="24" Y="52"/>
+ <UsageCount Value="40"/>
<Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
</Unit12>
<Unit13>
<Filename Value="spread.pas"/>
@@ -154,41 +167,43 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="spread"/>
- <CursorPos X="34" Y="591"/>
- <TopLine Value="587"/>
<EditorIndex Value="2"/>
- <UsageCount Value="34"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="557"/>
+ <CursorPos X="1" Y="584"/>
+ <UsageCount Value="40"/>
<Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
</Unit13>
<Unit14>
<Filename Value="gzio2.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="gzio2"/>
- <CursorPos X="22" Y="793"/>
<TopLine Value="774"/>
- <UsageCount Value="35"/>
+ <CursorPos X="22" Y="793"/>
+ <UsageCount Value="41"/>
</Unit14>
<Unit15>
<Filename Value="part.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="part"/>
- <CursorPos X="38" Y="108"/>
<TopLine Value="91"/>
- <UsageCount Value="35"/>
+ <CursorPos X="38" Y="108"/>
+ <UsageCount Value="41"/>
</Unit15>
<Unit16>
<Filename Value="markorder.pas"/>
<UnitName Value="markorder"/>
- <CursorPos X="44" Y="23"/>
<TopLine Value="8"/>
+ <CursorPos X="44" Y="23"/>
<UsageCount Value="10"/>
</Unit16>
<Unit17>
<Filename Value="ztopform.pas"/>
<ComponentName Value="ZForm"/>
<UnitName Value="ztopform"/>
- <CursorPos X="18" Y="23"/>
<TopLine Value="9"/>
+ <CursorPos X="18" Y="23"/>
<UsageCount Value="22"/>
</Unit17>
<Unit18>
@@ -196,22 +211,22 @@
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
- <CursorPos X="40" Y="14"/>
<TopLine Value="19"/>
+ <CursorPos X="40" Y="14"/>
<UsageCount Value="10"/>
</Unit18>
<Unit19>
<Filename Value="nifti_img.pas"/>
<UnitName Value="nifti_img"/>
- <CursorPos X="28" Y="54"/>
<TopLine Value="52"/>
+ <CursorPos X="28" Y="54"/>
<UsageCount Value="11"/>
</Unit19>
<Unit20>
<Filename Value="lesion_pattern.pas"/>
<UnitName Value="lesion_pattern"/>
- <CursorPos X="25" Y="86"/>
<TopLine Value="76"/>
+ <CursorPos X="25" Y="86"/>
<UsageCount Value="10"/>
</Unit20>
<Unit21>
@@ -221,316 +236,409 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="ReadInt"/>
- <CursorPos X="9" Y="50"/>
- <TopLine Value="33"/>
<EditorIndex Value="1"/>
- <UsageCount Value="33"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="33"/>
+ <CursorPos X="9" Y="50"/>
+ <UsageCount Value="39"/>
<Loaded Value="True"/>
+ <LoadedDesigner Value="True"/>
</Unit21>
<Unit22>
<Filename Value="ReadInt.lrs"/>
<IsPartOfProject Value="True"/>
- <CursorPos X="1" Y="3"/>
<TopLine Value="1"/>
- <UsageCount Value="31"/>
+ <CursorPos X="1" Y="3"/>
+ <UsageCount Value="37"/>
</Unit22>
<Unit23>
<Filename Value="LesionStatThds.pas"/>
<UnitName Value="LesionStatThds"/>
- <CursorPos X="16" Y="3"/>
- <TopLine Value="1"/>
- <UsageCount Value="11"/>
+ <EditorIndex Value="8"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="414"/>
+ <CursorPos X="77" Y="439"/>
+ <UsageCount Value="12"/>
+ <Loaded Value="True"/>
</Unit23>
<Unit24>
<Filename Value="power.pas"/>
<UnitName Value="power"/>
- <CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
+ <CursorPos X="1" Y="1"/>
<UsageCount Value="11"/>
</Unit24>
<Unit25>
<Filename Value="Mat.pas"/>
<UnitName Value="Mat"/>
- <CursorPos X="18" Y="239"/>
<TopLine Value="225"/>
+ <CursorPos X="18" Y="239"/>
<UsageCount Value="11"/>
</Unit25>
<Unit26>
<Filename Value="Vector.pas"/>
<UnitName Value="Vector"/>
- <CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
+ <CursorPos X="1" Y="1"/>
<UsageCount Value="10"/>
</Unit26>
<Unit27>
<Filename Value="firth.pas"/>
<UnitName Value="firth"/>
- <CursorPos X="19" Y="383"/>
<TopLine Value="382"/>
+ <CursorPos X="19" Y="383"/>
<UsageCount Value="10"/>
</Unit27>
<Unit28>
<Filename Value="overlap.pas"/>
<UnitName Value="overlap"/>
- <CursorPos X="1" Y="6"/>
<TopLine Value="1"/>
+ <CursorPos X="1" Y="6"/>
<UsageCount Value="10"/>
</Unit28>
<Unit29>
<Filename Value="firthThds.pas"/>
<UnitName Value="firthThds"/>
- <CursorPos X="123" Y="315"/>
<TopLine Value="312"/>
+ <CursorPos X="123" Y="315"/>
<UsageCount Value="10"/>
</Unit29>
<Unit30>
<Filename Value="design.lfm"/>
- <CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
+ <CursorPos X="1" Y="1"/>
<UsageCount Value="10"/>
- <SyntaxHighlighter Value="LFM"/>
+ <DefaultSyntaxHighlighter Value="LFM"/>
</Unit30>
<Unit31>
<Filename Value="options.inc"/>
- <CursorPos X="21" Y="3"/>
<TopLine Value="1"/>
+ <CursorPos X="21" Y="3"/>
<UsageCount Value="11"/>
</Unit31>
<Unit32>
<Filename Value="userdir.pas"/>
<UnitName Value="userdir"/>
- <CursorPos X="64" Y="45"/>
<TopLine Value="1"/>
+ <CursorPos X="64" Y="45"/>
<UsageCount Value="11"/>
</Unit32>
<Unit33>
<Filename Value="..\..\lcl\forms.pp"/>
<UnitName Value="Forms"/>
- <CursorPos X="14" Y="661"/>
<TopLine Value="642"/>
+ <CursorPos X="14" Y="661"/>
<UsageCount Value="11"/>
</Unit33>
<Unit34>
<Filename Value="..\gzio2.pas"/>
<UnitName Value="gzio2"/>
- <CursorPos X="22" Y="635"/>
<TopLine Value="627"/>
+ <CursorPos X="22" Y="635"/>
<UsageCount Value="10"/>
</Unit34>
<Unit35>
<Filename Value="..\..\fpc\2.0.4\source\rtl\objpas\sysutils\finah.inc"/>
- <CursorPos X="22" Y="27"/>
<TopLine Value="17"/>
+ <CursorPos X="22" Y="27"/>
<UsageCount Value="10"/>
</Unit35>
<Unit36>
<Filename Value="..\define_types.pas"/>
<UnitName Value="define_types"/>
- <CursorPos X="31" Y="5"/>
<TopLine Value="1"/>
+ <CursorPos X="31" Y="5"/>
<UsageCount Value="10"/>
</Unit36>
<Unit37>
<Filename Value="..\..\fpc\2.0.4\source\rtl\win32\wininc\messages.inc"/>
- <CursorPos X="6" Y="1201"/>
<TopLine Value="1191"/>
+ <CursorPos X="6" Y="1201"/>
<UsageCount Value="10"/>
</Unit37>
<Unit38>
<Filename Value="regression.pas"/>
<UnitName Value="regression"/>
- <CursorPos X="37" Y="16"/>
- <TopLine Value="1"/>
- <UsageCount Value="12"/>
+ <EditorIndex Value="10"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="725"/>
+ <CursorPos X="37" Y="731"/>
+ <UsageCount Value="14"/>
+ <Loaded Value="True"/>
</Unit38>
<Unit39>
<Filename Value="Regmult.pas"/>
<UnitName Value="RegMult"/>
- <CursorPos X="27" Y="43"/>
<TopLine Value="30"/>
+ <CursorPos X="27" Y="43"/>
<UsageCount Value="10"/>
</Unit39>
<Unit40>
<Filename Value="..\fpmath\regmult.pas"/>
<UnitName Value="regmult"/>
- <CursorPos X="69" Y="45"/>
<TopLine Value="39"/>
+ <CursorPos X="69" Y="45"/>
<UsageCount Value="10"/>
</Unit40>
<Unit41>
<Filename Value="..\common\distr.pas"/>
<UnitName Value="distr"/>
- <CursorPos X="1" Y="308"/>
<TopLine Value="296"/>
+ <CursorPos X="1" Y="308"/>
<UsageCount Value="11"/>
</Unit41>
<Unit42>
<Filename Value="..\common\define_types.pas"/>
<UnitName Value="define_types"/>
- <CursorPos X="40" Y="16"/>
- <TopLine Value="4"/>
- <UsageCount Value="11"/>
+ <EditorIndex Value="11"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="24" Y="21"/>
+ <UsageCount Value="12"/>
+ <Loaded Value="True"/>
</Unit42>
<Unit43>
<Filename Value="hdr.pas"/>
<UnitName Value="hdr"/>
- <CursorPos X="1" Y="3"/>
<TopLine Value="1"/>
+ <CursorPos X="1" Y="3"/>
<UsageCount Value="10"/>
</Unit43>
<Unit44>
<Filename Value="..\common\gzio2.pas"/>
<UnitName Value="gzio2"/>
- <CursorPos X="16" Y="236"/>
<TopLine Value="223"/>
+ <CursorPos X="16" Y="236"/>
<UsageCount Value="10"/>
</Unit44>
<Unit45>
<Filename Value="..\common\nifti_hdr.pas"/>
<UnitName Value="nifti_hdr"/>
- <CursorPos X="1" Y="121"/>
<TopLine Value="119"/>
+ <CursorPos X="1" Y="121"/>
<UsageCount Value="11"/>
</Unit45>
<Unit46>
<Filename Value="..\common\GraphicsMathLibrary.pas"/>
<UnitName Value="GraphicsMathLibrary"/>
- <CursorPos X="17" Y="8"/>
<TopLine Value="1"/>
+ <CursorPos X="17" Y="8"/>
<UsageCount Value="10"/>
</Unit46>
<Unit47>
<Filename Value="..\fpmath\utypes.pas"/>
<UnitName Value="utypes"/>
- <CursorPos X="41" Y="482"/>
<TopLine Value="470"/>
+ <CursorPos X="41" Y="482"/>
<UsageCount Value="12"/>
</Unit47>
<Unit48>
<Filename Value="lesion.pas"/>
<UnitName Value="lesion"/>
- <CursorPos X="64" Y="313"/>
<TopLine Value="299"/>
+ <CursorPos X="64" Y="313"/>
<UsageCount Value="10"/>
</Unit48>
<Unit49>
<Filename Value="anacom.pas"/>
<UnitName Value="anacom"/>
- <CursorPos X="32" Y="593"/>
<TopLine Value="579"/>
+ <CursorPos X="32" Y="593"/>
<UsageCount Value="10"/>
</Unit49>
<Unit50>
<Filename Value="filename.pas"/>
<UnitName Value="filename"/>
- <CursorPos X="6" Y="4"/>
<TopLine Value="1"/>
+ <CursorPos X="6" Y="4"/>
<UsageCount Value="10"/>
</Unit50>
<Unit51>
<Filename Value="montecarlo.pas"/>
<UnitName Value="montecarlo"/>
- <CursorPos X="6" Y="3"/>
+ <EditorIndex Value="7"/>
+ <WindowIndex Value="0"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <CursorPos X="6" Y="3"/>
+ <UsageCount Value="11"/>
+ <Loaded Value="True"/>
</Unit51>
<Unit52>
<Filename Value="roc.pas"/>
<UnitName Value="roc"/>
- <CursorPos X="33" Y="344"/>
<TopLine Value="317"/>
+ <CursorPos X="33" Y="344"/>
<UsageCount Value="10"/>
</Unit52>
<Unit53>
<Filename Value="..\fpmath\types.inc"/>
- <CursorPos X="15" Y="163"/>
- <TopLine Value="163"/>
- <UsageCount Value="12"/>
+ <EditorIndex Value="12"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="112"/>
+ <CursorPos X="3" Y="174"/>
+ <UsageCount Value="13"/>
+ <Loaded Value="True"/>
</Unit53>
<Unit54>
- <Filename Value="..\..\..\Developer\lazarus\lcl\interfaces\carbon\carbonprivatecommon.inc"/>
- <CursorPos X="1" Y="184"/>
+ <Filename Value="C:\Developer\lazarus\lcl\interfaces\carbon\carbonprivatecommon.inc"/>
<TopLine Value="170"/>
+ <CursorPos X="1" Y="184"/>
<UsageCount Value="10"/>
</Unit54>
+ <Unit55>
+ <Filename Value="tfce_clustering.pas"/>
+ <UnitName Value="tfce_clustering"/>
+ <EditorIndex Value="6"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="27" Y="3"/>
+ <UsageCount Value="10"/>
+ <Loaded Value="True"/>
+ </Unit55>
+ <Unit56>
+ <Filename Value="..\..\..\..\..\..\Developer\lazarus\lcl\include\menuitem.inc"/>
+ <EditorIndex Value="5"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1288"/>
+ <CursorPos X="1" Y="1317"/>
+ <UsageCount Value="10"/>
+ <Loaded Value="True"/>
+ </Unit56>
</Units>
- <JumpHistory Count="17" HistoryIndex="16">
+ <JumpHistory Count="30" HistoryIndex="29">
<Position1>
- <Filename Value="npm.lpr"/>
- <Caret Line="7" Column="3" TopLine="1"/>
+ <Filename Value="regression.pas"/>
+ <Caret Line="714" Column="16" TopLine="696"/>
</Position1>
<Position2>
- <Filename Value="npm.lpr"/>
- <Caret Line="27" Column="30" TopLine="1"/>
+ <Filename Value="regression.pas"/>
+ <Caret Line="454" Column="25" TopLine="428"/>
</Position2>
<Position3>
- <Filename Value="npm.lpr"/>
- <Caret Line="26" Column="1" TopLine="1"/>
+ <Filename Value="regression.pas"/>
+ <Caret Line="663" Column="24" TopLine="470"/>
</Position3>
<Position4>
<Filename Value="npmform.pas"/>
- <Caret Line="2147" Column="16" TopLine="2137"/>
+ <Caret Line="94" Column="7" TopLine="75"/>
</Position4>
<Position5>
<Filename Value="npmform.pas"/>
- <Caret Line="39" Column="54" TopLine="31"/>
+ <Caret Line="99" Column="11" TopLine="80"/>
</Position5>
<Position6>
- <Filename Value="npmform.pas"/>
- <Caret Line="108" Column="22" TopLine="79"/>
+ <Filename Value="tfce_clustering.pas"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
</Position6>
<Position7>
- <Filename Value="npmform.pas"/>
- <Caret Line="1678" Column="32" TopLine="1649"/>
+ <Filename Value="spread.pas"/>
+ <Caret Line="591" Column="34" TopLine="587"/>
</Position7>
<Position8>
<Filename Value="npmform.pas"/>
- <Caret Line="1729" Column="63" TopLine="1700"/>
+ <Caret Line="2" Column="1" TopLine="1"/>
</Position8>
<Position9>
<Filename Value="npmform.pas"/>
- <Caret Line="56" Column="204" TopLine="52"/>
+ <Caret Line="1521" Column="28" TopLine="1502"/>
</Position9>
<Position10>
- <Filename Value="npmform.pas"/>
- <Caret Line="108" Column="28" TopLine="52"/>
+ <Filename Value="spread.pas"/>
+ <Caret Line="584" Column="3" TopLine="557"/>
</Position10>
<Position11>
<Filename Value="npmform.pas"/>
- <Caret Line="1678" Column="1" TopLine="1675"/>
+ <Caret Line="1516" Column="14" TopLine="1502"/>
</Position11>
<Position12>
<Filename Value="npmform.pas"/>
- <Caret Line="2089" Column="19" TopLine="2032"/>
+ <Caret Line="1521" Column="17" TopLine="1502"/>
</Position12>
<Position13>
<Filename Value="npmform.pas"/>
- <Caret Line="2091" Column="57" TopLine="2072"/>
+ <Caret Line="1518" Column="20" TopLine="1502"/>
</Position13>
<Position14>
- <Filename Value="npm.lpr"/>
- <Caret Line="26" Column="1" TopLine="3"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="37" Column="40" TopLine="13"/>
</Position14>
<Position15>
<Filename Value="npmform.pas"/>
- <Caret Line="1494" Column="7" TopLine="1482"/>
+ <Caret Line="25" Column="22" TopLine="1"/>
</Position15>
<Position16>
<Filename Value="npmform.pas"/>
- <Caret Line="3" Column="109" TopLine="1"/>
+ <Caret Line="30" Column="28" TopLine="1"/>
</Position16>
<Position17>
<Filename Value="npmform.pas"/>
- <Caret Line="111" Column="21" TopLine="103"/>
+ <Caret Line="89" Column="30" TopLine="43"/>
</Position17>
+ <Position18>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="18" Column="79" TopLine="1"/>
+ </Position18>
+ <Position19>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="183" Column="43" TopLine="156"/>
+ </Position19>
+ <Position20>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="1434" Column="1" TopLine="1429"/>
+ </Position20>
+ <Position21>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="1511" Column="8" TopLine="1476"/>
+ </Position21>
+ <Position22>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="5" Column="152" TopLine="1"/>
+ </Position22>
+ <Position23>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="144" Column="23" TopLine="98"/>
+ </Position23>
+ <Position24>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="32" Column="5" TopLine="18"/>
+ </Position24>
+ <Position25>
+ <Filename Value="regression.pas"/>
+ <Caret Line="671" Column="129" TopLine="661"/>
+ </Position25>
+ <Position26>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="3" Column="170" TopLine="1"/>
+ </Position26>
+ <Position27>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="145" Column="22" TopLine="99"/>
+ </Position27>
+ <Position28>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="147" Column="26" TopLine="121"/>
+ </Position28>
+ <Position29>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="239" Column="40" TopLine="205"/>
+ </Position29>
+ <Position30>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="241" Column="29" TopLine="214"/>
+ </Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
- <Version Value="8"/>
+ <Version Value="9"/>
<PathDelim Value="\"/>
<SearchPaths>
- <OtherUnitFiles Value="..\fpmath\;..\common\"/>
+ <OtherUnitFiles Value="..\fpmath;..\common"/>
</SearchPaths>
+ <Parsing>
+ <SyntaxOptions>
+ <UseAnsiStrings Value="False"/>
+ </SyntaxOptions>
+ </Parsing>
<Linking>
<Debugging>
<UseLineInfoUnit Value="False"/>
@@ -545,9 +653,9 @@
</Options>
</Linking>
<Other>
- <ConfigFile>
- <CustomConfigFile Value="True"/>
- </ConfigFile>
+ <CompilerMessages>
+ <UseMsgFile Value="True"/>
+ </CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
diff --git a/npm/npm.lpr b/npm_precl/npm.lpr
old mode 100644
new mode 100755
similarity index 100%
copy from npm/npm.lpr
copy to npm_precl/npm.lpr
diff --git a/npm_precl/npm.or b/npm_precl/npm.or
new file mode 100755
index 0000000..4a3628d
Binary files /dev/null and b/npm_precl/npm.or differ
diff --git a/npm/npm.res b/npm_precl/npm.res
old mode 100644
new mode 100755
similarity index 100%
copy from npm/npm.res
copy to npm_precl/npm.res
diff --git a/npm/npmform.dfm b/npm_precl/npmform.dfm
old mode 100644
new mode 100755
similarity index 93%
copy from npm/npmform.dfm
copy to npm_precl/npmform.dfm
index 1cffcf9..8f15e6e
Binary files a/npm/npmform.dfm and b/npm_precl/npmform.dfm differ
diff --git a/npm/npmform.lfm b/npm_precl/npmform.lfm
old mode 100644
new mode 100755
similarity index 91%
copy from npm/npmform.lfm
copy to npm_precl/npmform.lfm
index e66d0cb..fc916b1
--- a/npm/npmform.lfm
+++ b/npm_precl/npmform.lfm
@@ -1,21 +1,21 @@
object MainForm: TMainForm
- Left = 714
+ Left = 517
Height = 418
- Top = 60
+ Top = 321
Width = 542
ActiveControl = Memo1
Caption = 'Non-Parametric Mapping'
- ClientHeight = 399
+ ClientHeight = 418
ClientWidth = 542
Menu = MainMenu1
OnClose = FormClose
OnCreate = FormCreate
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '0.9.29'
+ LCLVersion = '0.9.30.2'
object Memo1: TMemo
Left = 0
- Height = 374
+ Height = 393
Top = 0
Width = 542
Align = alClient
@@ -25,7 +25,7 @@ object MainForm: TMainForm
object Panel1: TPanel
Left = 0
Height = 25
- Top = 374
+ Top = 393
Width = 542
Align = alBottom
ClientHeight = 25
@@ -68,7 +68,7 @@ object MainForm: TMainForm
ShortCut = 16450
OnClick = LesionBtnClick
end
- object Binaryimagescontinuousgroupsvlsm1: TMenuItem
+ object Binaryimagescontinuousgroupsfast1: TMenuItem
Tag = 1
Caption = 'Binary images, continuous grooups (vlsm)'
ShortCut = 16460
@@ -99,11 +99,11 @@ object MainForm: TMainForm
Caption = 'Paired Measures T-test'
OnClick = PairedTMenuClick
end
- object MenuItem1: TMenuItem
+ object MultipleRegress: TMenuItem
Caption = 'Multiple WLS Regression'
OnClick = MultipleRegressClick
end
- object MenuItem2: TMenuItem
+ object SingleRegress: TMenuItem
Caption = 'Single WLS Regression'
OnClick = SingleRegressClick
end
@@ -270,9 +270,14 @@ object MainForm: TMainForm
Caption = 'Count lesion overlaps'
OnClick = Countlesionoverlaps1Click
end
+ object FCE1: TMenuItem
+ Caption = 'TFCE'
+ OnClick = FCE1Click
+ end
end
object Help1: TMenuItem
Caption = 'Help'
+ Visible = False
object About1: TMenuItem
Caption = 'About'
OnClick = About1Click
@@ -289,4 +294,4 @@ object MainForm: TMainForm
left = 8
top = 72
end
-end
+end
\ No newline at end of file
diff --git a/npm_precl/npmform.lrs b/npm_precl/npmform.lrs
new file mode 100755
index 0000000..f2d8f12
--- /dev/null
+++ b/npm_precl/npmform.lrs
@@ -0,0 +1,86 @@
+{ This is an automatically generated lazarus resource file }
+
+LazarusResources.Add('TMainForm','FORMDATA',[
+ 'TPF0'#9'TMainForm'#8'MainForm'#4'Left'#3#5#2#6'Height'#3#162#1#3'Top'#3'A'#1
+ +#5'Width'#3#30#2#13'ActiveControl'#7#5'Memo1'#7'Caption'#6#22'Non-Parametric'
+ +' Mapping'#12'ClientHeight'#3#162#1#11'ClientWidth'#3#30#2#4'Menu'#7#9'MainM'
+ +'enu1'#7'OnClose'#7#9'FormClose'#8'OnCreate'#7#10'FormCreate'#6'OnShow'#7#8
+ +'FormShow'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#8'0.9.30.2'#0#5
+ +'TMemo'#5'Memo1'#4'Left'#2#0#6'Height'#3#137#1#3'Top'#2#0#5'Width'#3#30#2#5
+ +'Align'#7#8'alClient'#10'ScrollBars'#7#10'ssAutoBoth'#8'TabOrder'#2#0#0#0#6
+ +'TPanel'#6'Panel1'#4'Left'#2#0#6'Height'#2#25#3'Top'#3#137#1#5'Width'#3#30#2
+ +#5'Align'#7#8'alBottom'#12'ClientHeight'#2#25#11'ClientWidth'#3#30#2#8'TabOr'
+ +'der'#2#1#0#12'TProgressBar'#12'ProgressBar1'#4'Left'#2#1#6'Height'#2#23#3'T'
+ +'op'#2#1#5'Width'#3#28#2#5'Align'#7#8'alClient'#8'TabOrder'#2#0#0#0#0#9'TMai'
+ +'nMenu'#9'MainMenu1'#4'left'#2#8#3'top'#2#8#0#9'TMenuItem'#5'File1'#7'Captio'
+ +'n'#6#4'File'#0#9'TMenuItem'#9'SaveText1'#7'Caption'#6#12'Save text...'#7'On'
+ +'Click'#7#14'Savetext1Click'#0#0#9'TMenuItem'#5'Exit1'#7'Caption'#6#4'Exit'#7
+ +'OnClick'#7#10'Exit1Click'#0#0#0#9'TMenuItem'#5'Edit1'#7'Caption'#6#4'Edit'#0
+ +#9'TMenuItem'#5'Copy1'#7'Caption'#6#4'Copy'#7'OnClick'#7#10'Copy1Click'#0#0#0
+ +#9'TMenuItem'#5'VLSM1'#7'Caption'#6#4'VLSM'#0#9'TMenuItem'#24'BinomialAnalys'
+ +'islesions1'#7'Caption'#6'''Binary images, binary groups (lesions) '#8'Short'
+ +'Cut'#3'B@'#7'OnClick'#7#14'LesionBtnClick'#0#0#9'TMenuItem!Binaryimagescont'
+ +'inuousgroupsfast1'#3'Tag'#2#1#7'Caption'#6'(Binary images, continuous groou'
+ +'ps (vlsm)'#8'ShortCut'#3'L@'#7'OnClick'#7#14'LesionBtnClick'#0#0#9'TMenuIte'
+ +'m'#28'PenalizedLogisticRegerssion1'#7'Caption'#6#31'Binary images, multiple'
+ +' factors'#7'OnClick'#7'!PenalizedLogisticRegerssion1Click'#0#0#9'TMenuItem'
+ +#12'ROIanalysis1'#7'Caption'#6#12'ROI analysis'#7'OnClick'#7#17'ROIanalysis1'
+ +'Click'#0#0#9'TMenuItem'#7'Design1'#7'Caption'#6#9'Design...'#8'ShortCut'#3
+ +'D@'#7'OnClick'#7#12'Design1Click'#0#0#0#9'TMenuItem'#4'VBM1'#7'Caption'#6#3
+ +'VBM'#0#9'TMenuItem'#22'ContinuousanalysisVBM1'#7'Caption'#6'&Continuous ima'
+ +'ges, binary groups (VBM)'#8'ShortCut'#3'V@'#7'OnClick'#7#8'NPMclick'#0#0#9
+ +'TMenuItem'#11'PairedTMenu'#7'Caption'#6#22'Paired Measures T-test'#7'OnClic'
+ +'k'#7#16'PairedTMenuClick'#0#0#9'TMenuItem'#15'MultipleRegress'#7'Caption'#6
+ +#23'Multiple WLS Regression'#7'OnClick'#7#20'MultipleRegressClick'#0#0#9'TMe'
+ +'nuItem'#13'SingleRegress'#7'Caption'#6#21'Single WLS Regression'#7'OnClick'
+ +#7#18'SingleRegressClick'#0#0#9'TMenuItem'#9'MenuItem3'#7'Caption'#6#22'Dual'
+ +' image correlation'#7'OnClick'#7#26'DualImageCorrelation1Click'#0#0#0#9'TMe'
+ +'nuItem'#8'Options1'#7'Caption'#6#7'Options'#0#9'TMenuItem'#13'Permutations1'
+ +#7'Caption'#6#12'Permutations'#0#9'TMenuItem'#2'N0'#9'AutoCheck'#9#7'Caption'
+ +#6#4'None'#7'Checked'#9#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'r'
+ +'adiomenuclick'#0#0#9'TMenuItem'#5'N1000'#3'Tag'#3#232#3#9'AutoCheck'#9#7'Ca'
+ +'ption'#6#4'1000'#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiome'
+ +'nuclick'#0#0#9'TMenuItem'#5'N2000'#3'Tag'#3#208#7#9'AutoCheck'#9#7'Caption'
+ +#6#4'2000'#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'
+ +#0#0#9'TMenuItem'#5'N3000'#3'Tag'#3#184#11#9'AutoCheck'#9#7'Caption'#6#4'300'
+ +'0'#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'#0#0#9
+ +'TMenuItem'#5'N4000'#3'Tag'#3#160#15#9'AutoCheck'#9#7'Caption'#6#4'4000'#10
+ +'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'#0#0#0#9'TMe'
+ +'nuItem'#6'Tests1'#7'Caption'#6#5'Tests'#0#9'TMenuItem'#9'ttestmenu'#7'Capti'
+ +'on'#6#6't-test'#7'OnClick'#7#13'testmenuclick'#0#0#9'TMenuItem'#6'BMmenu'#7
+ +'Caption'#6#14'Brunner Munzel'#7'Checked'#9#7'OnClick'#7#13'testmenuclick'#0
+ +#0#0#9'TMenuItem'#8'Threads1'#7'Caption'#6#7'Threads'#0#9'TMenuItem'#2'T1'#9
+ +'AutoCheck'#9#7'Caption'#6#1'1'#7'Checked'#9#10'GroupIndex'#3#131#0#9'RadioI'
+ +'tem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'#2'T2'#9'AutoCheck'#9#7
+ +'Caption'#6#1'2'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threa'
+ +'dChange'#0#0#9'TMenuItem'#2'T3'#9'AutoCheck'#9#7'Caption'#6#1'3'#10'GroupIn'
+ +'dex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'#2
+ +'T4'#9'AutoCheck'#9#7'Caption'#6#1'4'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7
+ +'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'#2'T7'#9'AutoCheck'#9#7'Caption'
+ +#6#1'7'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0
+ +#0#9'TMenuItem'#2'T8'#9'AutoCheck'#9#7'Caption'#6#1'8'#10'GroupIndex'#3#131#0
+ +#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMenuItem'#3'T15'#9'Auto'
+ +'Check'#9#7'Caption'#6#2'15'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'
+ +#7#12'threadChange'#0#0#9'TMenuItem'#3'T16'#9'AutoCheck'#9#7'Caption'#6#2'16'
+ +#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#0#0
+ +#9'TMenuItem'#10'Utilities1'#7'Caption'#6#9'Utilities'#0#9'TMenuItem'#9'niin'
+ +'iigz1'#7'Caption'#6#14'nii -> .nii.gz'#7'OnClick'#7#14'niiniigz1Click'#0#0#9
+ ,'TMenuItem'#9'Variance1'#7'Caption'#6#14'Variance image'#7'OnClick'#7#14'Var'
+ +'iance1Click'#0#0#9'TMenuItem'#14'Makemeanimage2'#3'Tag'#2#1#7'Caption'#6#19
+ +'Make binarized mean'#7'OnClick'#7#19'Makemeanimage1Click'#0#0#9'TMenuItem'
+ +#14'Makemeanimage1'#7'Caption'#6#21'Make mean/StDev image'#7'OnClick'#7#19'M'
+ +'akemeanimage1Click'#0#0#9'TMenuItem'#21'SingleSubjectZScores1'#7'Caption'#6
+ +#22'Single Subject Z-Score'#7'OnClick'#7#26'SingleSubjectZScores1Click'#0#0#9
+ +'TMenuItem'#24'IntensitynormalizationA1'#3'Tag'#2#1#7'Caption'#6#25'Intensit'
+ +'y normalization A'#7'OnClick'#7#13'Balance1Click'#0#0#9'TMenuItem'#8'Balanc'
+ +'e1'#7'Caption'#6#25'Intensity normalization B'#7'OnClick'#7#13'Balance1Clic'
+ +'k'#0#0#9'TMenuItem PhysiologicalArtifactCorrection1'#7'Caption'#6#24'Physio'
+ +'logical Correction'#7'OnClick'#7'%PhysiologicalArtifactCorrection1Click'#0#0
+ +#9'TMenuItem'#20'Countlesionoverlaps1'#7'Caption'#6#21'Count lesion overlaps'
+ +#7'OnClick'#7#25'Countlesionoverlaps1Click'#0#0#9'TMenuItem'#4'FCE1'#7'Capti'
+ +'on'#6#4'TFCE'#7'OnClick'#7#9'FCE1Click'#0#0#0#9'TMenuItem'#5'Help1'#7'Capti'
+ +'on'#6#4'Help'#7'Visible'#8#0#9'TMenuItem'#6'About1'#7'Caption'#6#5'About'#7
+ +'OnClick'#7#11'About1Click'#0#0#0#0#11'TSaveDialog'#10'SaveHdrDlg'#11'Filter'
+ +'Index'#2#0#4'left'#2#8#3'top'#2'('#0#0#11'TOpenDialog'#10'OpenHdrDlg'#11'Fi'
+ +'lterIndex'#2#0#4'left'#2#8#3'top'#2'H'#0#0#0
+]);
\ No newline at end of file
diff --git a/npm/npmform.pas b/npm_precl/npmform.pas
old mode 100644
new mode 100755
similarity index 95%
copy from npm/npmform.pas
copy to npm_precl/npmform.pas
index 4218201..97cdc15
--- a/npm/npmform.pas
+++ b/npm_precl/npmform.pas
@@ -7,7 +7,7 @@ uses
part,StatThds,statcr,StatThdsUtil,Brunner,DISTR,nifti_img,
Messages, Classes, Graphics, Controls, Forms, Dialogs,
Menus, ComCtrls, ExtCtrls, StdCtrls,
-overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr,
+overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr,tfce_clustering,
{$IFDEF FPC} LResources,gzio2,
{$ELSE} gziod,associate,{$ENDIF} //must be in search path, e.g. C:\pas\mricron\npm\math
@@ -27,8 +27,12 @@ type
{ TMainForm }
TMainForm = class(TForm)
+ Binaryimagescontinuousgroupsfast1: TMenuItem;
Memo1: TMemo;
+
Design1: TMenuItem;
+ FCE1: TMenuItem;
+ MultipleRegress: TMenuItem;
SaveText1: TMenuItem;
ROIanalysis1: TMenuItem;
OpenHdrDlg: TOpenDialog;
@@ -62,6 +66,7 @@ type
PenalizedLogisticRegerssion1: TMenuItem;
Permutations1: TMenuItem;
PhysiologicalArtifactCorrection1: TMenuItem;
+ SingleRegress: TMenuItem;
SingleSubjectZScores1: TMenuItem;
T1: TMenuItem;
T15: TMenuItem;
@@ -83,7 +88,7 @@ type
Masked1: TMenuItem;
MaskedintensitynormalizationA1: TMenuItem;
MaskedintensitynormalizationB1: TMenuItem;
- Binaryimagescontinuousgroupsfast1: TMenuItem;
+ //Binaryimagescontinuousgroupsfast1: TMenuItem;
Binarizeimages1: TMenuItem;
Resliceimagetoneworientationandboundingbox1: TMenuItem;
Setnonseroto1001: TMenuItem;
@@ -91,6 +96,7 @@ type
MonteCarloSimulation1: TMenuItem;
Subtract1: TMenuItem;
LogPtoZ1: TMenuItem;
+ //FCE1: TMenuItem;
function GetKVers: string;
function GetValX (var lnSubj, lnFactors: integer; var lSymptomRA: singleP; var lImageNames: TStrings; var lCrit: integer; {lBinomial : boolean;} var lPredictorList: TStringList):boolean;
function ThreshMap(lThresh: single; lVolVox: integer;lOutImg: singleP): integer;
@@ -158,6 +164,7 @@ type
procedure MonteCarloSimulation1Click(Sender: TObject);
procedure Subtract1Click(Sender: TObject);
procedure LogPtoZ1Click(Sender: TObject);
+ procedure FCE1Click(Sender: TObject);
private
{ Private declarations }
public
@@ -179,6 +186,7 @@ const
var
gNULP: boolean = true;
gROI : boolean = false;
+gTFCE: integer;
function TMainForm.GetKVers: string;
begin
result := kVers +'; Threads used = '+inttostr(gnCPUThreads );
@@ -192,8 +200,7 @@ var
begin
MainForm.Memo1.Lines.add(lStr);
lOutname:='c:\dx.txt';
- if fileexists(lOutname) then
- begin { open a text file }
+ if fileexists(lOutname) then begin { open a text file }
AssignFile(f, lOutname);
Append(f);
Writeln(f, lStr);
@@ -225,8 +232,22 @@ end;
procedure TMainForm.MsgSave(lFilename: string);
+var
+ i: integer;
+ f: textfile;
begin
- MainForm.Memo1.Lines.SaveToFile(lFilename);
+ if (Memo1.Lines.Count < 1) then exit;
+ if fileexists(lFilename) then begin
+ AssignFile(f, lFilename);
+ {$I-}
+ append(f);
+ {$I+}
+ if IOResult= 0 then
+ for i:= 0 to Memo1.Lines.Count- 1 do
+ WriteLn(f, Memo1.Lines[i]);
+ CloseFile(f);
+ end else
+ MainForm.Memo1.Lines.SaveToFile(lFilename);
end;
procedure TMainForm.ThreadDone(Sender: TObject);
@@ -1422,8 +1443,9 @@ end; *)
procedure TMainForm.Copy1Click(Sender: TObject);
begin
- Memo1.SelectAll;
- Memo1.CopyToClipBoard;
+ Memo1.SelectAll;
+ Memo1.CopyToClipboard;
+
end;
procedure TMainForm.testmenuclick(Sender: TObject);
@@ -1461,6 +1483,7 @@ begin
BMmenu.checked := IniBool(lIniFile,'computebm',false);
gNULP := IniBool(lIniFile,'countlesionpatterns',false);
gROI := IniBool(lIniFile,'ROI',false);
+ gTFCE := IniInt(lIniFile,'TFCE',0);
kPlankMB := IniInt(lIniFile,'CacheMB',512);
WritePermute(IniInt(lIniFile,'nPermute',0));
@@ -1487,6 +1510,7 @@ begin
//lIniFile.WriteString('BOOL', 'computewelch',Bool2Char(welchmenu.checked));
lIniFile.WriteString('BOOL', 'computebm',Bool2Char(BMmenu.checked));
+ lIniFile.WriteString('INT', 'TFCE',inttostr(gTFCE));
lIniFile.WriteString('INT', 'CacheMB',inttostr(kPlankMB));
lIniFile.WriteString('INT', 'nPermute',inttostr(ReadPermute));
lIniFile.WriteString('INT', 'nThread',inttostr(ReadThread));
@@ -1499,11 +1523,23 @@ procedure TMainForm.FormCreate(Sender: TObject);
begin
{$IFDEF Darwin}
File1.visible := false;//for OSX, exit is in the application's menu
- Edit1.visible := false;//clipboard note yet working for OSX
+ //Edit1.visible := false;//clipboard note yet working for OSX
{$ENDIF}
{$IFDEF FPC}
Application.ShowButtonGlyphs := sbgNever;
{$ENDIF}
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+ Copy1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ BinomialAnalysislesions1.ShortCut := ShortCut(Word('B'), [ssMeta]);
+ Binaryimagescontinuousgroupsfast1.ShortCut := ShortCut(Word('L'), [ssMeta]);
+ Design1.ShortCut := ShortCut(Word('D'), [ssMeta]);
+ ContinuousanalysisVBM1.ShortCut := ShortCut(Word('V'), [ssMeta]);
+ MultipleRegress.ShortCut := ShortCut(Word('R'), [ssMeta]);
+ Makemeanimage1.ShortCut := ShortCut(Word('M'), [ssMeta]);
+ About1.ShortCut := ShortCut(Word('A'), [ssMeta]);
+ {$ENDIF}//Carbon
+ {$ENDIF}//Darwin
gnCPUThreads := GetLogicalCpuCount;
(*if (ssShift in KeyDataToShiftState(vk_Shift)) then begin
case MessageDlg('Shift key down during launch: do you want to reset the default preferences?', mtConfirmation,
@@ -1515,7 +1551,7 @@ begin
ReadIniFile;
WriteThread(gnCPUThreads);
ComputePlankSize;
- ROIanalysis1.visible := gROI;
+ // ROIanalysis1.visible := gROI;
{$IFDEF compileANACOM}
AnaCOMmenu.visible := gROI;
{$ENDIF}
@@ -1707,6 +1743,62 @@ else
ProgressBar1.Position := 0;
end;
+function ApplyTFCE (lImageName: string): boolean;
+var
+ lImg: SingleP;
+ lHdr: TMRIcroHdr;
+ lVolVox: integer;
+ maxTFCE, maxNegTFCE: single;
+ lOutNameMod: string;
+begin
+ result := false;
+ if not NIFTIhdr_LoadHdr(lImageName,lHdr) then begin
+ showmessage('Error reading '+lImageName);
+ exit;
+ end;
+ lVolVox := lHdr.NIFTIhdr.dim[1]*lHdr.NIFTIhdr.dim[2]* lHdr.NIFTIhdr.dim[3];
+ if (lVolVox < 1) then exit;
+ getmem(lImg,lVolVox*sizeof(single));
+ if not LoadImg(lHdr.ImgFileName, lImg, 1, lVolVox,round(lHdr.NIFTIhdr.vox_offset),1,lHdr.NIFTIhdr.datatype,lVolVox) then begin
+ Msg('Unable to load ' +lHdr.ImgFileName);
+ exit;
+ end;
+ //lHdr.NIFTIhdr.scl_slope := 1; lHdr.NIFTIhdr.scl_inter := 0;
+ doTFCEbothPolarities (lHdr.NIFTIhdr, lImg, 6 {NumConn}, 2.0 {H}, 0.5 { E}, 0, 0,0,0 ,maxTFCE, maxNegTFCE);
+
+ lOutNameMod := ChangeFilePrefixExt(lImageName,'i','.hdr');
+ Msg('Creating ' +lOutNameMod);
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lHdr.NIFTIhdr,true,not IsNifTiMagic(lHdr.NIFTIhdr),true,lImg,1);
+
+ freemem(lImg);
+
+
+end;
+
+procedure TMainForm.FCE1Click(Sender: TObject);
+var
+ lFilename: string;
+ lPos: Integer;
+ lHdr: TMRIcroHdr;
+begin
+ MsgClear;
+ Msg(GetKVers);
+ if not OpenDialogExecute('Select images for TFCE',true,false,kImgFilter) then begin
+ showmessage('NPM aborted: file selection failed.');
+ exit;
+ end; //if not selected
+ if OpenHdrDlg.Files.Count < 1 then
+ exit;
+ for lPos := 1 to OpenHdrDlg.Files.Count do begin
+ lFilename := OpenHdrDlg.Files[lPos-1];
+ //TFCE(lFilename,1,false);
+ //ClusterTFCE (lHdr, 666, 2);
+ ApplyTFCE(lFilename);
+ //Binarize (var lImageName:String; lNonZeroVal: integer; lZeroThresh: boolean): boolean;
+ end;
+ Msg('Done');
+end;
+
procedure TMainForm.Makemeanimage1Click(Sender: TObject);
label
666;
@@ -2898,6 +2990,8 @@ var
lMaskHdr: TMRIcroHdr;
X : PMatrix;
begin
+
+
{$IFDEF FPC}
showmessage('Regression routines not extensively tested: you may want to use the Windows compilation.');
{$ENDIF}
@@ -2944,7 +3038,8 @@ begin
end;
lOutName := lMaskName;
if not SaveHdrName ('Base Statistical Map', lOutName) then exit;
- ARegressNPMAnalyze(lImageNames,lMaskHdr,X,lnFactors,lPredictorList,lOutName);
+ ARegressNPMAnalyze(lImageNames,lMaskHdr,X,lnFactors,lPredictorList,lOutName,0,0);
+
DelMatrix(X, lnFactors, lnSubj);
666:
lImageNames.Free;
@@ -2965,6 +3060,7 @@ var
lMaskHdr: TMRIcroHdr;
X,X1 : PMatrix;
begin
+
{$IFDEF FPC}
showmessage('Regression routines not extensively tested: you may want to use the Windows compilation.');
{$ENDIF}
@@ -3003,7 +3099,6 @@ begin
{$ENDIF}
lTemp4D := CreateDecompressed4D(lImageNames);
-
lImageNames1:= TStringList.Create;
for lCol := 1 to lnFactors do begin
lPredictorList1.Clear;
@@ -3028,11 +3123,11 @@ begin
Memo1.Lines.Add('Mask = '+lMaskname);
Memo1.Lines.Add('Total voxels = '+inttostr(lMaskVoxels));
Memo1.Lines.Add('Number of observations = '+inttostr(lnSubj1));
-
MainForm.Memo1.Lines.Add('Image,'+ lPredictorList1.Strings[0]);
for lRow := 1 to lnSubj1 do
MainForm.Memo1.Lines.Add(lImageNames1[lRow-1]+','+floattostr(X1^[1]^[lRow]) ) ;
- ARegressNPMAnalyze(lImageNames1,lMaskHdr,X1,1,lPredictorList1,lOutName);
+ ARegressNPMAnalyze(lImageNames1,lMaskHdr,X1,1,lPredictorList1,lOutName, ReadPermute,gTFCE);
+ //PermuteRegressNPMAnalyze (lImageNames1,lMaskHdr,X1,1,lPredictorList1,lOutName);
DelMatrix(X1, 1, lnSubj1);
end;
lImageNames1.Free;
@@ -4142,6 +4237,8 @@ begin
end;
{$IFDEF UNIX}
+
+
initialization
{$I npmform.lrs}
{$ELSE} //not unix: windows
@@ -4156,4 +4253,4 @@ finalization
{$ENDIF} //Windows
end.
-
+
\ No newline at end of file
diff --git a/npm/anacom.pas b/npm_precl/old/anacom.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/anacom.pas
copy to npm_precl/old/anacom.pas
diff --git a/npm/old/lesion.pas b/npm_precl/old/lesion.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/old/lesion.pas
copy to npm_precl/old/lesion.pas
diff --git a/npm/old/montecarlo.pas b/npm_precl/old/montecarlo.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/old/montecarlo.pas
copy to npm_precl/old/montecarlo.pas
diff --git a/npm/options.inc b/npm_precl/options.inc
old mode 100644
new mode 100755
similarity index 100%
copy from npm/options.inc
copy to npm_precl/options.inc
diff --git a/npm/overlap.pas b/npm_precl/overlap.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/overlap.pas
copy to npm_precl/overlap.pas
diff --git a/npm/part.pas b/npm_precl/part.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/part.pas
copy to npm_precl/part.pas
diff --git a/npm/prefs.pas b/npm_precl/prefs.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/prefs.pas
copy to npm_precl/prefs.pas
diff --git a/npm/regression.pas b/npm_precl/regression.pas
old mode 100644
new mode 100755
similarity index 80%
copy from npm/regression.pas
copy to npm_precl/regression.pas
index 2b24f71..4fcc6b3
--- a/npm/regression.pas
+++ b/npm_precl/regression.pas
@@ -8,10 +8,10 @@ uses
{$IFDEF FPC} utypes,regmult,{$ELSE}
utypes,regmult,
{$ENDIF}define_types,Classes,nifti_hdr,sysutils,nifti_img,
- StatThdsUtil,Forms,Distr,Dialogs,npmform;
+ StatThdsUtil,Forms,Distr,Dialogs,npmform, tfce_clustering;
function GetValReg (var lnSubj,lnFactors: integer; var X : PMatrix; var lImageNames: TStrings; var lPredictorList: TStringList): boolean;
-function ARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string): boolean;
+function ARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string; lnPermute, TFCEconn: integer): boolean;
function Regress2NPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; lOutname: string; var lXadditional: PMatrix; lnAdditionalFactors: integer ): boolean;
function TtoR(t,df: double): double;
@@ -418,7 +418,8 @@ end;
{$DEFINE NoThread}
-function ARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string): boolean;
+function InnerARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string; lSaveData: boolean; var lMinZ,lMaxZ: double; var lMaxNegTFCEZ, lMaxTFCEZ:single; TFCEconn: integer): boolean;
+//TFCEmode 0 = no TFCE, 1 = only report min/maxTFCE, 2 = save TFCE map to disk
{$IFNDEF Thread}
const
kMaxFact = 80;
@@ -453,13 +454,15 @@ var
{$ENDIF}
begin
+
+
lnObservations := lImages.Count;
lDF := lnObservations-lnFactors-1;
if lDF < 1 then begin
showmessage('Regress2NPMAnalyze: DF must be >0 (DF=[Num-Factors-1]) Num='+inttostr(lnObservations)+' Factors='+inttostr(lnFactors) );
exit;
end;
- MainForm.NPMmsg('Analysis began = ' +TimeToStr(Now));
+ if (lSaveData) then MainForm.NPMmsg('Analysis began = ' +TimeToStr(Now));
lTotalMemory := 0;
lVolVox := lMaskHdr.NIFTIhdr.dim[1]*lMaskHdr.NIFTIhdr.dim[2]* lMaskHdr.NIFTIhdr.dim[3];
if (lVolVox < 1) then goto 667;
@@ -474,6 +477,7 @@ begin
MainForm.NPMmsg('Unable to load mask ' +lMaskHdr.ImgFileName);
goto 667;
end;
+
//next find start and end of mask
lPos := 0;
repeat
@@ -489,14 +493,14 @@ begin
MainForm.NPMmsg('Mask appears empty' +lMaskHdr.ImgFileName);
goto 667;
end;
- MainForm.NPMmsg('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
+ if (lSaveData) then MainForm.NPMmsg('Mask has voxels from '+inttostr(lMinMask)+'..'+inttostr(lMaxMask));
lVoxPerPlank := kPlankSz div lnObservations div sizeof(single) ;
if (lVoxPerPlank = 0) then goto 667; //no data
lTotalMemory := ((lMaxMask+1)-lMinMask) * lnObservations;
if (lTotalMemory = 0) then goto 667; //no data
lnPlanks := trunc(lTotalMemory/(lVoxPerPlank*lnObservations) ) + 1;
- MainForm.NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lnObservations)));
- MainForm.NPMmsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
+ if (lSaveData) then MainForm.NPMmsg('Memory planks = ' +Floattostr(lTotalMemory/(lVoxPerPlank*lnObservations)));
+ if (lSaveData) then MainForm.NPMmsg('Max voxels per Plank = ' +Floattostr(lVoxPerPlank));
if (lnPlanks = 1) then
getmem(lPlankImg,lTotalMemory* sizeof(single)) //assumes 4bpp
else
@@ -524,7 +528,7 @@ begin
lnVoxTested := 0;
{$ENDIF}
for lPlank := 1 to lnPlanks do begin
- MainForm.NPMmsg('Computing plank = ' +Inttostr(lPlank));
+ if (lSaveData) then MainForm.NPMmsg('Computing plank = ' +Inttostr(lPlank));
MainForm.Refresh;
lEndVox := lEndVox + lVoxPerPlank;
if lEndVox > lMaxMask then begin
@@ -580,7 +584,7 @@ begin
lVar := true;
end;
lOutImgMn^[lPos2Offset] := lSum/lnObservations;
- if {lPos2Offset = 762287 }lVar then begin
+ if lVar then begin
MultipleRegression (lnObservations,lnFactors, X, lObs, lZra);
//if {lZra^[0] < -5.548} lPos2Offset = 762287 then
// ReportRegression (lPos2Offset,lnObservations,lnFactors, X, lObs, lZra );
@@ -597,6 +601,19 @@ begin
{$IFDEF Thread}
lnVoxTested := SumThreadDataLite(gnCPUThreads);
{$ENDIF}
+ //FACTOR 1 MinMax
+ lFact := 1;
+ lMinZ := lOutImgR[lFact]^[1];
+ for lPos := 1 to lVolVox do
+ if (lOutImgR[lFact]^[lPos] < lMinZ) then lMinZ :=lOutImgR[lFact]^[lPos];
+ lMinZ := TtoZ (lMinZ,lDF);
+ lMaxZ := lOutImgR[lFact]^[1];
+ for lPos := 1 to lVolVox do
+ if (lOutImgR[lFact]^[lPos] > lMaxZ) then lMaxZ :=lOutImgR[lFact]^[lPos];
+ lMaxZ := TtoZ (lMaxZ,lDF);
+ //MainForm.NPMmsg('Factor1MinMax ' +floattostr(lMinZ)+' '+floattostr(lMaxZ));
+
+ if (lSaveData) then begin
//next report findings
MainForm.NPMmsg('Voxels tested = ' +Inttostr(lnVoxTested));
MainForm.reportBonferroni('Std',lnVoxTested);
@@ -608,6 +625,9 @@ begin
//savedata
MakeHdr (lMaskHdr.NIFTIhdr,lStatHdr);
+
+
+
//save mean
lOutNameMod := ChangeFilePostfixExt(lOutName,'Mean'+lRunName,'.hdr');
if not FileExistsEX(lOutNameMod) then
@@ -636,19 +656,40 @@ begin
lOutImgR[lFact]^[lPos] := TtoZ (lOutImgR[lFact]^[lPos],lDF);
MainForm.reportFDR ('wls'+lFactName, lVolVox, lnVoxTested, lOutImgR[lFact]);
lOutNameMod := ChangeFilePostfixExt(lOutName, 'wls'+lFactName,'.hdr');
- NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgR[lFact],1);
- freemem(lOutImgR[lFact]);
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgR[lFact],1);
+ if (lFact = 1) and (TFCEconn > 0) then begin //TFCE
+ //lMinZ := lOutImgR[lFact]^[1];
+
+ MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,lDF,0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
+ doTFCEbothPolarities (lStatHdr, lOutImgR[lFact], TFCEconn {NumConn}, 2.0{H}, 0.5 {E}, 0, lMaxZ/100, 0, lMinZ/100, lMaxTFCEZ, lMaxNegTFCEZ);
+ lOutNameMod := ChangeFilePostfixExt(lOutName, 'tfce'+lFactName,'.hdr');
+ NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgR[lFact],1);
+ end; //TFCE
+
end;//if..else intercept and lnFactors = 1
end;//for each statfactor
+ end; //if lSaveData
+
+
+ if (not (lSaveData)) and (TFCEconn > 0) and ((lMaxTFCEZ <> 0) or (lMaxNegTFCEZ <> 0)) then begin
+ //lMinZ := lOutImgR[lFact]^[1];
+ lFact := 1;
+ MakeStatHdr (lMaskHdr.NIFTIhdr,lStatHdr,-6, 6,lDF,0,lnVoxTested,kNIFTI_INTENT_ZSCORE,inttostr(lnVoxTested) );
+ doTFCEbothPolarities (lStatHdr, lOutImgR[lFact], TFCEconn {NumConn}, 2.0{H}, 0.5 {E}, 0, lMaxTFCEZ, 0, lMaxNegTFCEZ, lMaxTFCEZ, lMaxNegTFCEZ)
+
+ end; //xxx
//next: close images
+ for lFact := 1 to (lnStatFact) do
+ freemem(lOutImgR[lFact]);
+
//Freemem(lZp);
freemem(lOutImgMn);
//freemem(lObsp);
freemem(lMaskImg);
freemem(lPlankImg);
- MainForm.NPMmsg('Analysis finished = ' +TimeToStr(Now));
- lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes'+lRunName,'.txt');
- MainForm.MsgSave(lOutNameMod);
+
+ //lOutNameMod := ChangeFilePostfixExt(lOutName,'Notes'+lRunName,'.txt');
+ //MainForm.MsgSave(lOutNameMod);
MainForm.ProgressBar1.Position := 0;
exit;
667: //you only get here if you aborted ... free memory and report error
@@ -658,6 +699,77 @@ exit;
MainForm.ProgressBar1.Position := 0;
end;
+procedure PermuteMatrix(var Src, Dest: PMatrix; lnSubj: integer); //assumes only one column/factor!!!
+var
+ lRow,lPos: integer;
+ lSwap: double;
+begin
+ for lRow := 1 to lnSubj do
+ Dest^[1]^[lRow] := Src^[1]^[lRow];
+ for lRow := lnSubj downto 1 do begin
+ lPos := random(lRow)+1;
+ lSwap := Dest^[1]^[lRow];
+ Dest^[1]^[lRow] := Dest^[1]^[lPos];
+ Dest^[1]^[lPos] := lSwap;
+ end;
+
+end;
+
+function ARegressNPMAnalyze (var lImages: TStrings; var lMaskHdr: TMRIcroHdr; var X: PMatrix; lnFactors: integer; var lPredictorList: TStringList; lOutname: string; lnPermute, TFCEconn: integer ): boolean;
+label
+ 777;
+var
+ //SaveData: boolean; var
+ lMaxTFCEZ, lMaxNegTFCEZ: single;
+ lMinZ,lMaxZ,lTFCEdh,lNegTFCEdh:double;
+ Xp : PMatrix;
+ lp,lnSubj,lRow : integer;
+ lPermuteMaxZ, lPermuteMinZ,lPermuteMaxTFCEZ, lPermuteMinTFCEZ: singleP;
+begin
+ InnerARegressNPMAnalyze (lImages, lMaskHdr, X, lnFactors, lPredictorList, lOutname, TRUE,lMinZ,lMaxZ, lMaxNegTFCEZ, lMaxTFCEZ, TFCEconn );
+ if lnFactors > 1 then goto 777;
+ if (lnPermute < 1) then goto 777;
+ //MainForm.NPMmsg('0 ObservedzMinMax ' +floattostr(lMinZ)+' '+floattostr(lMaxZ));
+ MainForm.NPMmsg('OBSERVED Factor1 zMin zMax zMinTFCE zMaxTFCE ' +floattostr(lMinZ)+' '+floattostr(lMaxZ) +' ' +floattostr(lMaxNegTFCEZ)+' '+floattostr(lMaxTFCEZ));
+
+ lnSubj := lImages.Count;
+ DimMatrix(Xp, lnFactors, lnSubj);
+ randomize;
+ getmem(lPermuteMaxZ,lnPermute* sizeof(single));
+ getmem(lPermuteMinZ,lnPermute* sizeof(single));
+ getmem(lPermuteMaxTFCEZ,lnPermute* sizeof(single));
+ getmem(lPermuteMinTFCEZ,lnPermute* sizeof(single));
+ lTFCEdh := lMaxZ / 100;
+ lNegTFCEdh := abs(lMinZ) / 100;
+ for lp := 1 to lnPermute do begin
+ //for lRow := 1 to lnSubj do
+ // Xp^[1]^[lRow] := X^[1]^[lRow];
+ lMaxNegTFCEZ := lNegTFCEdh;
+ lMaxTFCEZ := lTFCEdh;
+ PermuteMatrix(X,Xp,lnSubj);
+
+ InnerARegressNPMAnalyze (lImages, lMaskHdr, Xp, lnFactors, lPredictorList, lOutname, FALSE,lMinZ,lMaxZ,lMaxNegTFCEZ, lMaxTFCEZ, TFCEconn);
+ MainForm.NPMmsg(inttostr(lp)+' Factor1 zMin zMax zMinTFCE zMaxTFCE ' +floattostr(lMinZ)+' '+floattostr(lMaxZ) +' ' +floattostr(lMaxNegTFCEZ)+' '+floattostr(lMaxTFCEZ));
+ lPermuteMaxZ^[lp] := lMaxZ;
+ lPermuteMinZ^[lp] := lMinZ;
+ lPermuteMaxTFCEZ^[lp] := lMaxTFCEZ;
+ lPermuteMinTFCEZ^[lp] := lMaxNegTFCEZ;
+ end;
+ DelMatrix(Xp, lnFactors, lnSubj);
+ MainForm.reportPermute ('Permutation', lnPermute, lPermuteMaxZ, lPermuteMinZ);
+ MainForm.reportPermute ('TFCEPermutation', lnPermute, lPermuteMaxTFCEZ, lPermuteMinTFCEZ);
+ Freemem(lPermuteMaxZ);
+ Freemem(lPermuteMinZ);
+ Freemem(lPermuteMaxTFCEZ);
+ Freemem(lPermuteMinTFCEZ);
+ 777:
+ MainForm.NPMmsg('Analysis finished = ' +TimeToStr(Now));
+ MainForm.MsgSave( ChangeFilePostfixExt(lOutName,'Notes','.txt'));
+
+end;
+
+
+
function GetValReg (var lnSubj,lnFactors: integer; var X : PMatrix; var lImageNames: TStrings; var lPredictorList: TStringList): boolean;
var
lVALFilename,lTemplateName: string;
@@ -668,6 +780,7 @@ var
lInP: Pointer;
begin
result := false;
+
lnSubj := 0;
if not MainForm.OpenDialogExecute('Select MRIcron VAL file',false,false,'MRIcron VAL (*.val)|*.val') then begin
showmessage('NPM aborted: VAL file selection failed.');
@@ -706,4 +819,4 @@ begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/npm/results.niiNotesseverity.txt b/npm_precl/results.niiNotesseverity.txt
old mode 100644
new mode 100755
similarity index 100%
copy from npm/results.niiNotesseverity.txt
copy to npm_precl/results.niiNotesseverity.txt
diff --git a/npm/roc.pas b/npm_precl/roc.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/roc.pas
copy to npm_precl/roc.pas
diff --git a/npm/spread.dfm b/npm_precl/spread.dfm
old mode 100644
new mode 100755
similarity index 79%
copy from npm/spread.dfm
copy to npm_precl/spread.dfm
index de192fa..f7aaee9
Binary files a/npm/spread.dfm and b/npm_precl/spread.dfm differ
diff --git a/npm/spread.lfm b/npm_precl/spread.lfm
old mode 100644
new mode 100755
similarity index 97%
copy from npm/spread.lfm
copy to npm_precl/spread.lfm
index 2f04966..224dbf7
--- a/npm/spread.lfm
+++ b/npm_precl/spread.lfm
@@ -5,7 +5,7 @@ object SpreadForm: TSpreadForm
Width = 326
ActiveControl = DataGrid
Caption = 'Voxelwise Analysis of Lesions'
- ClientHeight = 513
+ ClientHeight = 538
ClientWidth = 326
Font.Name = 'MS Sans Serif'
Menu = MainMenu1
@@ -13,10 +13,10 @@ object SpreadForm: TSpreadForm
OnCreate = FormCreate
OnResize = FormResize
Position = poScreenCenter
- LCLVersion = '0.9.28.2'
+ LCLVersion = '0.9.30.2'
object DataGrid: TStringGrid
Left = 0
- Height = 467
+ Height = 498
Top = 25
Width = 326
Align = alClient
@@ -45,7 +45,6 @@ object SpreadForm: TSpreadForm
Top = 0
Width = 120
Caption = 'Design'
- Color = clBtnFace
Glyph.Data = {
76010000424D7601000000000000760000002800000020000000100000000100
0400000000000001000000000000000000001000000010000000000000000000
@@ -68,8 +67,8 @@ object SpreadForm: TSpreadForm
end
object StatusBar1: TStatusBar
Left = 0
- Height = 21
- Top = 492
+ Height = 15
+ Top = 523
Width = 326
Panels = <
item
diff --git a/npm_precl/spread.lrs b/npm_precl/spread.lrs
new file mode 100755
index 0000000..cf9ecb9
--- /dev/null
+++ b/npm_precl/spread.lrs
@@ -0,0 +1,66 @@
+{ This is an automatically generated lazarus resource file }
+
+LazarusResources.Add('TSpreadForm','FORMDATA',[
+ 'TPF0'#11'TSpreadForm'#10'SpreadForm'#4'Left'#3#145#1#6'Height'#3#26#2#3'Top'
+ +#3#183#0#5'Width'#3'F'#1#13'ActiveControl'#7#8'DataGrid'#7'Caption'#6#29'Vox'
+ +'elwise Analysis of Lesions'#12'ClientHeight'#3#26#2#11'ClientWidth'#3'F'#1#9
+ +'Font.Name'#6#13'MS Sans Serif'#4'Menu'#7#9'MainMenu1'#7'OnClose'#7#9'FormCl'
+ +'ose'#8'OnCreate'#7#10'FormCreate'#8'OnResize'#7#10'FormResize'#8'Position'#7
+ +#14'poScreenCenter'#10'LCLVersion'#6#8'0.9.30.2'#0#11'TStringGrid'#8'DataGri'
+ +'d'#4'Left'#2#0#6'Height'#3#242#1#3'Top'#2#25#5'Width'#3'F'#1#5'Align'#7#8'a'
+ +'lClient'#9'FixedRows'#2#2#7'Options'#11#15'goFixedVertLine'#10'goVertLine'
+ +#10'goHorzLine'#13'goRangeSelect'#19'goDrawFocusSelected'#6'goTabs'#15'goThu'
+ +'mbTracking'#0#8'RowCount'#2#12#8'TabOrder'#2#0#14'TitleFont.Name'#6#13'MS S'
+ +'ans Serif'#10'OnDrawCell'#7#16'DataGridDrawCell'#10'OnKeyPress'#7#16'DataGr'
+ +'idKeyPress'#11'OnMouseDown'#7#17'DataGridMouseDown'#11'OnMouseMove'#7#17'Da'
+ +'taGridMouseMove'#12'OnSelectCell'#7#18'DataGridSelectCell'#0#0#8'TToolBar'#8
+ +'ToolBar1'#4'Left'#2#0#6'Height'#2#25#3'Top'#2#0#5'Width'#3'F'#1#11'EdgeBord'
+ +'ers'#11#0#8'TabOrder'#2#1#0#12'TSpeedButton'#9'DesignBtn'#4'Left'#2#1#6'Hei'
+ +'ght'#2#22#4'Hint'#6#5'ANOVA'#3'Top'#2#0#5'Width'#2'x'#7'Caption'#6#6'Design'
+ +#10'Glyph.Data'#10'z'#1#0#0'v'#1#0#0'BMv'#1#0#0#0#0#0#0'v'#0#0#0'('#0#0#0' '
+ +#0#0#0#16#0#0#0#1#0#4#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#0#0#16#0#0#0#16#0#0#0#0#0
+ +#0#0#0#0#128#0#0#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#127
+ +#127#127#0#191#191#191#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255
+ +#0#255#255#0#0#255#255#255#0'3s3s3s3s3'#127'?'#127'?'#127'?'#127'3sssssss?'
+ +#127#127#127#127#127#127#127'w'#0#0#0#0#0#0#0'wwwwwwww3'#3'33<3333'#127#255
+ +'37'#243'3?7'#9#147'3<33'#153'7ws'#243'7'#243'3w3'#3'93<393?'#127#247#255#247
+ +#255#247#255'w'#7'w'#151'|w'#151'wwwwwwwww3'#3'3'#147'<3'#147'33'#127'3s'#247
+ +#243's37'#3'39<9337'#127'377'#247'333'#3'33'#153#147'33?'#127#255#255'w'#127
+ +#255#255'w'#7'ww|wwwwwwwwwww3'#3'33<3'#3'33'#127'337'#255#127#243'7'#3'33<'#0
+ +#0'<7'#127'337ww73'#3'33<3'#3'3?'#127#255#255#247#255#127#255'w'#7'wwwwwwwww'
+ +'wwwww3333333333333333'#9'NumGlyphs'#2#2#7'OnClick'#7#14'DesignBtnClick'#8'S'
+ +'howHint'#9#14'ParentShowHint'#8#0#0#0#10'TStatusBar'#10'StatusBar1'#4'Left'
+ +#2#0#6'Height'#2#15#3'Top'#3#11#2#5'Width'#3'F'#1#6'Panels'#14#1#5'Width'#3
+ +#140#0#0#1#5'Width'#2'2'#0#0#11'SimplePanel'#8#0#0#9'TMainMenu'#9'MainMenu1'
+ +#4'left'#2'l'#3'top'#2','#0#9'TMenuItem'#5'File1'#7'Caption'#6#5'&File'#0#9
+ +'TMenuItem'#4'New1'#7'Caption'#6#6'New...'#8'ShortCut'#3'N@'#7'OnClick'#7#11
+ +'NewBtnClick'#0#0#9'TMenuItem'#5'Open1'#7'Caption'#6#7'Open...'#8'ShortCut'#3
+ +'O@'#7'OnClick'#7#12'OpenBtnClick'#0#0#9'TMenuItem'#5'Save1'#7'Caption'#6#4
+ +'Save'#8'ShortCut'#3'S@'#7'OnClick'#7#12'SaveBtnClick'#0#0#9'TMenuItem'#5'Qu'
+ +'it1'#7'Caption'#6#12'Close window'#8'ShortCut'#3'W@'#7'OnClick'#7#10'Quit1C'
+ +'lick'#0#0#0#9'TMenuItem'#5'Edit1'#7'Caption'#6#4'Edit'#0#9'TMenuItem'#5'Cop'
+ +'y1'#7'Caption'#6#4'Copy'#8'ShortCut'#3'C@'#7'OnClick'#7#10'Copy1Click'#0#0#9
+ +'TMenuItem'#6'Paste1'#7'Caption'#6#5'Paste'#8'ShortCut'#3'V@'#7'OnClick'#7#11
+ +'Paste1Click'#0#0#9'TMenuItem'#10'Selectall1'#7'Caption'#6#16'Select all cel'
+ +'ls'#8'ShortCut'#3'A@'#7'OnClick'#7#15'Selectall1Click'#0#0#9'TMenuItem'#14
+ +'Clearallcells1'#7'Caption'#6#18'Clear all cells...'#7'OnClick'#7#19'Clearal'
+ +'lcells1Click'#0#0#9'TMenuItem'#15'DescriptiveMenu'#7'Caption'#6#12'Descript'
+ +'ives'#7'OnClick'#7#16'DescriptiveClick'#0#0#0#9'TMenuItem'#4'View'#7'Captio'
+ +'n'#6#4'View'#0#9'TMenuItem'#5'Font1'#7'Caption'#6#4'Font'#0#9'TMenuItem'#3
+ +'N81'#3'Tag'#2#8#7'Caption'#6#1'8'#7'Checked'#9#10'GroupIndex'#2'o'#9'RadioI'
+ +'tem'#9#7'OnClick'#7#14'FontSizeChange'#0#0#9'TMenuItem'#4'N101'#3'Tag'#2#10
+ +#7'Caption'#6#2'10'#10'GroupIndex'#2'o'#9'RadioItem'#9#7'OnClick'#7#14'FontS'
+ +'izeChange'#0#0#9'TMenuItem'#4'N121'#3'Tag'#2#12#7'Caption'#6#2'12'#10'Group'
+ +'Index'#2'o'#9'RadioItem'#9#7'OnClick'#7#14'FontSizeChange'#0#0#9'TMenuItem'
+ +#4'N141'#3'Tag'#2#14#7'Caption'#6#2'14'#10'GroupIndex'#2'o'#9'RadioItem'#9#7
+ +'OnClick'#7#14'FontSizeChange'#0#0#0#9'TMenuItem'#7'Design1'#7'Caption'#6#6
+ +'Design'#8'ShortCut'#3'D@'#7'OnClick'#7#14'DesignBtnClick'#0#0#0#9'TMenuItem'
+ +#5'Help1'#7'Caption'#6#5'&Help'#0#9'TMenuItem'#18'Aboutthissoftware1'#7'Capt'
+ +'ion'#6#20'&About this software'#7'OnClick'#7#23'Aboutthissoftware1Click'#0#0
+ +#0#0#11'TOpenDialog'#11'OpenDialog1'#10'DefaultExt'#6#4'.val'#6'Filter'#6'<N'
+ +'ative [val]|.val|Tab delimited text [txt]|.txt|All files|.*'#11'FilterIndex'
+ +#2#0#4'left'#2'$'#3'top'#2','#0#0#11'TSaveDialog'#11'SaveDialog1'#10'Default'
+ +'Ext'#6#4'.val'#6'Filter'#6'8Native format [val]|*.val|Tab delimited text [t'
+ +'xt]|*.txt'#11'FilterIndex'#2#0#7'Options'#11#17'ofOverwritePrompt'#14'ofHid'
+ +'eReadOnly'#0#4'left'#2'J'#3'top'#2','#0#0#0
+]);
\ No newline at end of file
diff --git a/npm/spread.pas b/npm_precl/spread.pas
old mode 100644
new mode 100755
similarity index 94%
copy from npm/spread.pas
copy to npm_precl/spread.pas
index c087182..0873ed9
--- a/npm/spread.pas
+++ b/npm_precl/spread.pas
@@ -570,6 +570,20 @@ begin
DataGrid.ColCount := 9;
DataGrid.RowCount := 15;
FormResize(nil);
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+
+New1.ShortCut := ShortCut(Word('N'), [ssMeta]);
+ Open1.ShortCut := ShortCut(Word('O'), [ssMeta]);
+ Save1.ShortCut := ShortCut(Word('S'), [ssMeta]);
+ Quit1.ShortCut := ShortCut(Word('W'), [ssMeta]);
+ Copy1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ Paste1.ShortCut := ShortCut(Word('V'), [ssMeta]);
+ Selectall1.ShortCut := ShortCut(Word('A'), [ssMeta]);
+ DescriptiveMenu.ShortCut := ShortCut(Word('L'), [ssMeta]);
+
+ {$ENDIF}//Carbon
+ {$ENDIF}//Darwin
end;
procedure TSpreadForm.DataGridMouseDown(Sender: TObject; Button: TMouseButton;
@@ -688,7 +702,11 @@ begin
C := StartC;
while( length( S ) > 0 ) do begin
// Extract next line...
+ {$IFDEF UNIX}
+ Dummy := pos( #13, S + #13 ) ;
+ {$ELSE}
Dummy := pos( #13#10, S + #13#10 ) ;
+ {$ENDIF}
Line := copy( S, 1, Dummy - 1 ) ;
if (Dummy+1) < length(S) then //last line may not have eol
S := copy( S, Dummy + 1, length( S ) )
@@ -1015,4 +1033,4 @@ initialization
{$I spread.lrs}
{$ENDIF}
-end.
+end.
\ No newline at end of file
diff --git a/npm/statcr.pas b/npm_precl/statcr.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/statcr.pas
copy to npm_precl/statcr.pas
diff --git a/npm/stats.pas b/npm_precl/stats.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/stats.pas
copy to npm_precl/stats.pas
diff --git a/npm_precl/tfce_clustering.7z b/npm_precl/tfce_clustering.7z
new file mode 100755
index 0000000..0287bcc
Binary files /dev/null and b/npm_precl/tfce_clustering.7z differ
diff --git a/npm_precl/tfce_clustering.pas b/npm_precl/tfce_clustering.pas
new file mode 100755
index 0000000..2e4f2b7
--- /dev/null
+++ b/npm_precl/tfce_clustering.pas
@@ -0,0 +1,273 @@
+unit tfce_clustering;
+//USED by stats to select only regions with a given number of connected/contiguous voxels
+{$IFDEF FPC} {$mode delphi}{$H+} {$ENDIF}
+interface
+uses
+{$IFNDEF UNIX} Windows,
+ {$ELSE}
+ LCLType, LCLintf,
+ {$ENDIF}
+define_types,dialogs,SysUtils,nifti_hdr,nifti_img, math;
+
+//procedure FindClusters (lMultiBuf: SingleP; lXdim, lYDim, lZDim, lThreshClusterSz: integer; lMinNeg, lMinPos: single);
+
+//function ClusterTFCE (var lHdr: TMRIcroHdr; lThreshClusterSz: integer; lThresh: double ): boolean;
+
+function doTFCE (var lHdr: TNIFTIhdr; lImg: SingleP; NumConn: integer; H, E, minT, deltaT: single ): boolean;
+//mimics FSL's function "TFCE" in newimagefns.h
+
+function doTFCEbothPolarities (var lHdr: TNIFTIhdr; lImg: SingleP; NumConn: integer; H, E, minT, deltaT, minNegT, NegdeltaT: single; var maxTFCE, maxNegTFCE: single): boolean;
+//both polarities computes TFCE for both positive and negative values
+
+implementation
+uses
+npmform;
+
+procedure countClusterSize (lX,lY,lZ, lnumConnIn: integer; var lClusterBuff: LongIntP);
+//input CountImg is volume X*Y*Z where voxels are either 0 or 1
+// output: CountImg voxels report number of connected neighbors
+const
+ lClusterSign = 1; //input CountImg has this value set to 1
+ lClusterFillValue = -1; //impossible cluster size - used to denote actively growing cluster
+var
+ lQHead,lV,lXY, lXYZ,lClusterSz, lQTail,lnumConn,lI,lNeighbor: integer;
+ lQra: LongIntP;
+ ConnOffset : ARRAY [1..26] of integer;
+procedure InitConn;
+begin
+ //first 6 share face
+ ConnOffset[1] := -1;//L
+ ConnOffset[2] := 1; //R
+ ConnOffset[3] := -lX; //A
+ ConnOffset[4] := lX; //P
+ ConnOffset[5] := -lXY;//I
+ ConnOffset[6] := lXY;//S
+ if lnumConnIn < 7 then begin
+ lnumConn := 6;
+ exit;
+ end;
+ //share edge
+ //..check plane above
+ ConnOffset[7] := (lXY-1); //left
+ ConnOffset[8] := (lXY+1); //right
+ ConnOffset[9] := (lXY-lX); //up
+ ConnOffset[10] := (lXY+lX); //down
+ //..check plane below
+ ConnOffset[11] := (-lXY-1); //left
+ ConnOffset[12] := (-lXY+1); //right
+ ConnOffset[13] := (-lXY-lX); //up
+ ConnOffset[14] := (-lXY+lX); //down
+ //..check diagonals of current plane
+ ConnOffset[15] := (-lX-1); //up, left
+ ConnOffset[16] := (-lX+1); //up, right
+ ConnOffset[17] := (+lX-1); //down, left
+ ConnOffset[18] := (+lX+1); //down, right
+ if lnumConnIn < 19 then begin
+ lnumConn := 18;
+ exit;
+ end;
+ //share corner
+ //..check plane above
+ ConnOffset[19] := (lXY-1-lX); //left
+ ConnOffset[20] := (lXY-1+lX); //right
+ ConnOffset[21] := (lXY+1-lX); //up
+ ConnOffset[22] := (lXY+1+lX); //down
+ //..check plane BELOW
+ ConnOffset[23] := (-lXY-1-lX); //left
+ ConnOffset[24] := (-lXY-1+lX); //right
+ ConnOffset[25] := (-lXY+1-lX); //up
+ ConnOffset[26] := (-lXY+1+lX); //down
+ lnumConn := 26;
+end; //InitConn
+begin
+ lXY := lX * lY;
+ lXYZ := lX*lY*lZ;
+ InitConn;
+ if lXYZ < 1 then exit;
+ GetMem(lQra,lXYZ * sizeof(longint) );
+ //check every voxel to see if it is isolated
+ for lV := 1 to lXYZ do begin
+ if (lClusterBuff^[lV]=lClusterSign) then begin //new cluster detected
+ lClusterSz := 1;
+ lQHead := 1;
+ lQTail := 1;
+ lQra^[lQTail] := lV;
+ lClusterBuff^[lV] := lClusterFillValue;
+ while (lQHead >= lQTail) do begin
+ //RetirePixel: lQTail incremented once, lQHead is incremented 0..nummConn
+ for lI := 1 to lnumConn do begin
+ lNeighbor := lQra^[lQTail]+ConnOffset[lI];
+ if (lClusterBuff^[lNeighbor]=lClusterSign) then begin//add item
+ inc(lQHead);
+ inc(lClusterSz);
+ lClusterBuff^[lNeighbor] := lClusterFillValue;
+ lQra^[lQHead] := lNeighbor;
+ end; //if new item detected
+ end; //for each connector
+ inc(lQTail); //done with this pixel
+ end; //while items in Queue
+ for lI := lV to lXYZ do
+ if (lClusterBuff^[lI]=lClusterFillValue) then
+ lClusterBuff^[lI] := lClusterSz;
+ end; //new item found
+ end; //for each voxel
+ freemem(lQra);
+end;
+
+procedure ZeroFaces (var lHdr: TNIFTIhdr; lImg: SingleP );
+var
+ lV,lX,lY,lZ,lZi,lYi,lXi: integer;
+begin
+ lX := lHdr.Dim[1];
+ lY := lHdr.Dim[2];
+ lZ := lHdr.Dim[3];
+ if (lX < 3) or (lY < 3) or (lZ < 3) then exit;
+ for lV := 1 to (lX*lY) do lImg[lV] := 0; //bottom slice
+ for lV := ((lX*lY*lZ)-(lX*lY)) to (lX*lY*lZ) do lImg[lV] := 0; //top slice
+ //left side
+ lV := 1;
+ for lZi := 1 to lZ do begin
+ for lYi := 1 to lY do begin
+ lImg[lV] := 0;
+ lV := lV+lX;
+ end;
+ end;
+ //right side
+ lV := lX;
+ for lZi := 1 to lZ do begin
+ for lYi := 1 to lY do begin
+ lImg[lV] := 0;
+ lV := lV+lX;
+ end;
+ end;
+ //anterior
+ for lZi := 1 to lZ do begin
+ lV := (lZi-1) * lX*lY;
+ for lXi := 1 to lX do begin
+ lV := lV+1;
+ lImg[lV] := 0;
+ end;
+ end;
+ //posterior
+ for lZi := 1 to lZ do begin
+ lV := (lZi-1) * lX*lY;
+ lV := lV + ((lY-1) *lX);
+ for lXi := 1 to lX do begin
+ lV := lV+1;
+ lImg[lV] := 0;
+ end;
+ end;
+end;
+
+
+function doTFCEbothPolarities (var lHdr: TNIFTIhdr; lImg: SingleP; NumConn: integer; H, E, minT, deltaT, minNegT, NegdeltaT: single; var maxTFCE, maxNegTFCE: single): boolean;
+var
+ lV,lXYZ,lX,lY,lZ: integer;
+
+ lNegImg: SingleP;
+
+begin
+ result := false;
+ lX := lHdr.Dim[1];
+ lY := lHdr.Dim[2];
+ lZ := lHdr.Dim[3];
+ lXYZ := lX*lY*lZ;
+ if lXYZ < 1 then exit;
+ getmem(lNegImg,lXYZ*sizeof(single));
+ for lV := 1 to lXYZ do
+ lNegImg[lV] := -lImg[lV];
+
+
+ doTFCE (lHdr, lImg, NumConn, H, E, minT, deltaT);
+ maxTFCE :=lImg[lV];
+ for lV := 1 to lXYZ do
+ if (maxTFCE < lImg[lV]) then
+ maxTFCE:= lImg[lV];
+
+
+ doTFCE (lHdr, lNegImg, NumConn, H, E, abs(minNegT), abs(NegdeltaT));
+ maxNegTFCE :=lImg[lV];
+ for lV := 1 to lXYZ do
+ if (maxNegTFCE < lNegImg[lV]) then
+ maxNegTFCE:= lNegImg[lV];
+ maxNegTFCE := -maxNegTFCE;
+
+ for lV := 1 to lXYZ do begin
+ if (lNegImg[lV] > 0) then
+ lImg[lV] := -lNegImg[lV];
+ end;
+
+ freemem(lNegImg);
+end;
+
+
+
+function doTFCE (var lHdr: TNIFTIhdr; lImg: SingleP; NumConn: integer; H, E, minT, deltaT: single ): boolean;
+const
+ kSteps = 100;
+label
+ 777;
+var
+ lV,lXYZ,lX,lY,lZ: integer;
+ maxval, lThresh, ThreshPowerHxdh, dh: single;
+ lThreshImg: SingleP;
+ lCountImg: LongIntP;
+ lStartTime: DWord;
+begin
+ lX := lHdr.Dim[1];
+ lY := lHdr.Dim[2];
+ lZ := lHdr.Dim[3];
+ lStartTime := GetTickCount;
+ result := false;//assume failure
+ lXYZ := lX*lY*lZ;
+ if lXYZ < 1 then exit;
+ //E := 0.5; //0.5
+ //H := 2;//2
+ getmem(lThreshImg,lXYZ*sizeof(single));
+ getmem(lCountImg,lXYZ*sizeof(longint));
+ ZeroFaces (lHdr, lImg );
+ maxval := lImg[1];
+ for lV := 1 to lXYZ do begin
+ lThreshImg[lV] := lImg[lV];
+ if lImg[lV] > maxval then maxval := lImg[lV];
+ lImg[lV] := 0; //initialize sum map to zero
+ end;
+
+ if (maxval <= 0) then goto 777;
+ if (maxval < minT) then goto 777;
+ if (deltaT = 0) then
+ dh := (maxval-minT) / kSteps
+ else
+ dh := deltaT;
+ MainForm.NPMmsg('max = '+floattostr(maxval)+' deltaT = '+floattostr(dh));
+ lThresh := minT+dh;
+ while lThresh < maxval do begin
+
+
+ for lV := 1 to lXYZ do begin
+ if (lThreshImg[lV] <= lThresh) then
+ lCountImg[lV] := 0
+ else
+ lCountImg[lV] := 1;
+ end;
+ countClusterSize (lX,lY,lZ,NumConn, lCountImg);
+ ThreshPowerHxdh := power(lThresh,H)*dh;
+ for lV := 1 to lXYZ do
+ if (lCountImg[lV] > 0) then
+ lImg[lV] := lImg[lV] + (exp(E*ln(lCountImg[lV])) * ThreshPowerHxdh); //faster than power
+ (*for lV := 1 to lXYZ do
+ if (lCountImg[lV] > 0) then
+ lImg[lV] := lImg[lV] + (power(lCountImg[lV],E) * ThreshPowerHxdh); *)
+ lThresh := lThresh + dh;
+ end;
+777:
+ MainForm.NPMmsg('Time = '+inttostr(GetTickCount - lStartTime));
+ freemem(lCountImg);
+ freemem(lThreshImg);
+ result := true; //report success!
+end;
+
+
+
+
+end.
\ No newline at end of file
diff --git a/npm_precl/tfce_clustering.zip b/npm_precl/tfce_clustering.zip
new file mode 100755
index 0000000..c22aed6
Binary files /dev/null and b/npm_precl/tfce_clustering.zip differ
diff --git a/npm/turbolesion.pas b/npm_precl/turbolesion.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/turbolesion.pas
copy to npm_precl/turbolesion.pas
diff --git a/npm/upower.pas b/npm_precl/upower.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/upower.pas
copy to npm_precl/upower.pas
diff --git a/npm/valformat.pas b/npm_precl/valformat.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/valformat.pas
copy to npm_precl/valformat.pas
diff --git a/dcm2nii/windowsxp.res b/npm_precl/windowsxp.res
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/windowsxp.res
copy to npm_precl/windowsxp.res
diff --git a/npm/xLesionStatThds.pas b/npm_precl/xLesionStatThds.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/xLesionStatThds.pas
copy to npm_precl/xLesionStatThds.pas
diff --git a/npm/xanacom.pas b/npm_precl/xanacom.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/xanacom.pas
copy to npm_precl/xanacom.pas
diff --git a/npm/xmontecarlo.pas b/npm_precl/xmontecarlo.pas
old mode 100644
new mode 100755
similarity index 100%
copy from npm/xmontecarlo.pas
copy to npm_precl/xmontecarlo.pas
diff --git a/dcm2nii/zconf.inc b/npm_precl/zconf.inc
old mode 100644
new mode 100755
similarity index 100%
copy from dcm2nii/zconf.inc
copy to npm_precl/zconf.inc
diff --git a/ortho_reorient.pas b/ortho_reorient.pas
old mode 100644
new mode 100755
index 3f73437..27a741a
--- a/ortho_reorient.pas
+++ b/ortho_reorient.pas
@@ -252,9 +252,9 @@ var
lOutName: string;
lResidualMat: TMatrix;
lInMinX,lInMinY,lInMinZ,lOutMinX,lOutMinY,lOutMinZ,
- dx, dy, dz, QFac: single;
- lStartX,lStartY,lStartZ,
- lZ,lY,lX,lB,
+ dx, dy, dz: single; //, QFac
+ //lStartY,lStartZ,
+ lStartX,lZ,lY,lX,lB,
lOutZ,lOutY,
lXInc, lYInc, lZInc,lBPP,lVol,lnVol: integer;
lInPos,lVolBytes,lOutPos,lInOffset: integer;
@@ -448,4 +448,4 @@ begin
result := true;
end;//ReorientCore
-end.
+end.
\ No newline at end of file
diff --git a/otsuml.pas b/otsuml.pas
old mode 100644
new mode 100755
diff --git a/periplot.pas b/periplot.pas
old mode 100644
new mode 100755
diff --git a/perisettings.lfm b/perisettings.lfm
old mode 100644
new mode 100755
diff --git a/perisettings.lrs b/perisettings.lrs
old mode 100644
new mode 100755
diff --git a/perisettings.pas b/perisettings.pas
old mode 100644
new mode 100755
diff --git a/periutils.pas b/periutils.pas
old mode 100644
new mode 100755
diff --git a/prefs.lfm b/prefs.lfm
old mode 100644
new mode 100755
index 1d7ebb7..8f9851a
--- a/prefs.lfm
+++ b/prefs.lfm
@@ -1,7 +1,7 @@
object PrefForm: TPrefForm
- Left = 876
+ Left = 932
Height = 456
- Top = 139
+ Top = 200
Width = 393
ActiveControl = ResliceCheck
BorderIcons = [biSystemMenu]
@@ -16,7 +16,7 @@ object PrefForm: TPrefForm
OnCreate = FormCreate
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '0.9.29'
+ LCLVersion = '1.0.2.0'
object GroupBox1: TGroupBox
Left = 8
Height = 280
@@ -107,34 +107,26 @@ object PrefForm: TPrefForm
end
object GroupBox2: TGroupBox
Left = 8
- Height = 80
+ Height = 64
Top = 296
Width = 368
Caption = 'Drawing'
- ClientHeight = 62
+ ClientHeight = 46
ClientWidth = 364
TabOrder = 1
- object DrawCheck: TCheckBox
- Left = 15
- Height = 17
- Top = 9
- Width = 168
- Caption = 'Show drawing menus and tools'
- TabOrder = 0
- end
object ThinPenCheck: TCheckBox
Left = 15
Height = 17
- Top = 32
+ Top = 16
Width = 61
Caption = 'Thin Pen'
- TabOrder = 1
+ TabOrder = 0
end
end
object OKBtn: TButton
Left = 296
Height = 25
- Top = 389
+ Top = 416
Width = 75
BorderSpacing.InnerBorder = 4
Caption = 'OK'
@@ -144,7 +136,7 @@ object PrefForm: TPrefForm
object CancelBtn: TButton
Left = 192
Height = 25
- Top = 389
+ Top = 416
Width = 75
BorderSpacing.InnerBorder = 4
Caption = 'Cancel'
diff --git a/prefs.lrs b/prefs.lrs
old mode 100644
new mode 100755
index bafbac1..4d6541b
--- a/prefs.lrs
+++ b/prefs.lrs
@@ -1,13 +1,13 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TPrefForm','FORMDATA',[
- 'TPF0'#9'TPrefForm'#8'PrefForm'#4'Left'#3'l'#3#6'Height'#3#200#1#3'Top'#3#139
+ 'TPF0'#9'TPrefForm'#8'PrefForm'#4'Left'#3#164#3#6'Height'#3#200#1#3'Top'#3#200
+#0#5'Width'#3#137#1#13'ActiveControl'#7#12'ResliceCheck'#11'BorderIcons'#11
+#12'biSystemMenu'#0#11'BorderStyle'#7#8'bsDialog'#7'Caption'#6#11'Preference'
+'s'#12'ClientHeight'#3#200#1#11'ClientWidth'#3#137#1#21'Constraints.MaxHeigh'
+'t'#3#200#1#20'Constraints.MaxWidth'#3#137#1#21'Constraints.MinHeight'#3#200
+#1#20'Constraints.MinWidth'#3#137#1#8'OnCreate'#7#10'FormCreate'#6'OnShow'#7
- +#8'FormShow'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#6'0.9.29'#0#9
+ +#8'FormShow'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#7'1.0.2.0'#0#9
+'TGroupBox'#9'GroupBox1'#4'Left'#2#8#6'Height'#3#24#1#3'Top'#2#8#5'Width'#3
+'p'#1#7'Caption'#6#13'Image Display'#12'ClientHeight'#3#6#1#11'ClientWidth'#3
+'l'#1#8'TabOrder'#2#0#0#6'TLabel'#6'Label1'#4'Left'#2'x'#6'Height'#2#14#3'To'
@@ -28,18 +28,16 @@ LazarusResources.Add('TPrefForm','FORMDATA',[
+#0#7'Caption'#6'"Rotate to nearest orthogonal angle'#8'TabOrder'#2#4#7'Visib'
+'le'#8#0#0#9'TCheckBox'#14'SingleRowCheck'#4'Left'#2#15#6'Height'#2#17#3'Top'
+#3#208#0#5'Width'#3#134#0#7'Caption'#6#26'All slices on a single row'#8'TabO'
- +'rder'#2#5#0#0#0#9'TGroupBox'#9'GroupBox2'#4'Left'#2#8#6'Height'#2'P'#3'Top'
- +#3'('#1#5'Width'#3'p'#1#7'Caption'#6#7'Drawing'#12'ClientHeight'#2'>'#11'Cli'
- +'entWidth'#3'l'#1#8'TabOrder'#2#1#0#9'TCheckBox'#9'DrawCheck'#4'Left'#2#15#6
- +'Height'#2#17#3'Top'#2#9#5'Width'#3#168#0#7'Caption'#6#28'Show drawing menus'
- +' and tools'#8'TabOrder'#2#0#0#0#9'TCheckBox'#12'ThinPenCheck'#4'Left'#2#15#6
- +'Height'#2#17#3'Top'#2' '#5'Width'#2'='#7'Caption'#6#8'Thin Pen'#8'TabOrder'
- +#2#1#0#0#0#7'TButton'#5'OKBtn'#4'Left'#3'('#1#6'Height'#2#25#3'Top'#3#133#1#5
- +'Width'#2'K'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#2'OK'#7'OnClick'
- +#7#10'OKBtnClick'#8'TabOrder'#2#2#0#0#7'TButton'#9'CancelBtn'#4'Left'#3#192#0
- +#6'Height'#2#25#3'Top'#3#133#1#5'Width'#2'K'#25'BorderSpacing.InnerBorder'#2
- +#4#7'Caption'#6#6'Cancel'#7'OnClick'#7#14'CancelBtnClick'#8'TabOrder'#2#3#0#0
- +#7'TButton'#7'XBarClr'#4'Left'#2#26#6'Height'#2#25#3'Top'#3#197#0#5'Width'#3
- +#178#0#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#22'Choose Cross-Bar Co'
- +'lor'#7'OnClick'#7#12'XBarClrClick'#8'TabOrder'#2#4#0#0#0
+ +'rder'#2#5#0#0#0#9'TGroupBox'#9'GroupBox2'#4'Left'#2#8#6'Height'#2'@'#3'Top'
+ +#3'('#1#5'Width'#3'p'#1#7'Caption'#6#7'Drawing'#12'ClientHeight'#2'.'#11'Cli'
+ +'entWidth'#3'l'#1#8'TabOrder'#2#1#0#9'TCheckBox'#12'ThinPenCheck'#4'Left'#2
+ +#15#6'Height'#2#17#3'Top'#2#16#5'Width'#2'='#7'Caption'#6#8'Thin Pen'#8'TabO'
+ +'rder'#2#0#0#0#0#7'TButton'#5'OKBtn'#4'Left'#3'('#1#6'Height'#2#25#3'Top'#3
+ +#160#1#5'Width'#2'K'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#2'OK'#7
+ +'OnClick'#7#10'OKBtnClick'#8'TabOrder'#2#2#0#0#7'TButton'#9'CancelBtn'#4'Lef'
+ +'t'#3#192#0#6'Height'#2#25#3'Top'#3#160#1#5'Width'#2'K'#25'BorderSpacing.Inn'
+ +'erBorder'#2#4#7'Caption'#6#6'Cancel'#7'OnClick'#7#14'CancelBtnClick'#8'TabO'
+ +'rder'#2#3#0#0#7'TButton'#7'XBarClr'#4'Left'#2#26#6'Height'#2#25#3'Top'#3#197
+ +#0#5'Width'#3#178#0#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#22'Choose'
+ +' Cross-Bar Color'#7'OnClick'#7#12'XBarClrClick'#8'TabOrder'#2#4#0#0#0
]);
diff --git a/prefs.pas b/prefs.pas
old mode 100644
new mode 100755
index ff0fc21..3a8f441
--- a/prefs.pas
+++ b/prefs.pas
@@ -25,11 +25,10 @@ type
Label3: TLabel;
ResliceCheck: TCheckBox;
GroupBox1: TGroupBox;
- DrawCheck: TCheckBox;
MaxDimEdit: TSpinEdit;
ThreadEdit: TSpinEdit;
SigDigEdit: TSpinEdit;
- procedure CancelBtnClick(Sender: TObject);
+ procedure CancelBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure OKBtnClick(Sender: TObject);
@@ -52,11 +51,11 @@ implementation
procedure TPrefForm.CancelBtnClick(Sender: TObject);
begin
Close;
-end;
-
-procedure TPrefForm.FormCreate(Sender: TObject);
-begin
-
+end;
+
+procedure TPrefForm.FormCreate(Sender: TObject);
+begin
+
end;
procedure TPrefForm.FormShow(Sender: TObject);
@@ -66,7 +65,7 @@ begin
OrthoCheck.checked := gBGImg.OrthoReslice;
MaxDimEdit.value := gBGImg.MaxDim;
ThreadEdit.value := gnCPUThreads;
- DrawCheck.checked := ImgForm.ToolPanel.Visible;
+ //DrawCheck.checked := ImgForm.ToolPanel.Visible;
ThinPenCheck.Checked := gBGImg.ThinPen;
SigDigEdit.value := gBGImg.SigDig;
SingleRowCheck.checked := gBGImg.SingleRow;
@@ -78,8 +77,8 @@ begin
gBGImg.OrthoReslice := OrthoCheck.checked;
gBGImg.MaxDim := MaxDimEdit.value;
gnCPUThreads := ThreadEdit.value;
- ImgForm.ToolPanel.Visible := DrawCheck.checked;
- ImgForm.DrawMenu.Visible := DrawCheck.checked;
+ //ImgForm.ToolPanel.Visible := DrawCheck.checked;
+ //ImgForm.DrawMenu.Visible := DrawCheck.checked;
gBGImg.ThinPen := ThinPenCheck.Checked;
gBGImg.SigDig := SigDigEdit.value;
if gBGImg.SingleRow <> SingleRowCheck.Checked then begin
diff --git a/render.lfm b/render.lfm
old mode 100644
new mode 100755
diff --git a/render.lrs b/render.lrs
old mode 100644
new mode 100755
diff --git a/render.pas b/render.pas
old mode 100644
new mode 100755
diff --git a/render/a0e90.ini b/render/a0e90.ini
old mode 100644
new mode 100755
diff --git a/render/cut.ini b/render/cut.ini
old mode 100644
new mode 100755
diff --git a/render/default.ini b/render/default.ini
old mode 100644
new mode 100755
diff --git a/render_composite.pas b/render_composite.pas
old mode 100644
new mode 100755
diff --git a/rendernothreads.pas b/rendernothreads.pas
old mode 100644
new mode 100755
diff --git a/reorient.dfm b/reorient.dfm
old mode 100644
new mode 100755
diff --git a/reorient.pas b/reorient.pas
old mode 100644
new mode 100755
diff --git a/reslice_fsl.pas b/reslice_fsl.pas
old mode 100644
new mode 100755
diff --git a/reslice_img.pas b/reslice_img.pas
old mode 100644
new mode 100755
index 6a42368..d58c216
--- a/reslice_img.pas
+++ b/reslice_img.pas
@@ -458,7 +458,8 @@ end else begin //if trilinear, else nearest neighbor
lZo := round(lXz^[lXi]+lYz+lZz+lMat.matrix[3][4]);
//need to test Xreal as -0.01 truncates to zero
if (lXo >= 0) and (lYo >= 0{1}) and (lZo >= 0{1}) and
- (lXo < (lXs -1)) and (lYo < (lYs -1) ) and (lZo < (lZs))
+ (lXo < (lXs)) and (lYo < (lYs) ) and (lZo < (lZs))
+ //2012 removed -1 for nearest neighbor (lXo < (lXs -1)) and (lYo < (lYs -1) ) and (lZo < (lZs))
then begin
lOverlap := true;
inc(lXo);//images incremented from 1 not 0
diff --git a/rgb/lazrgbgraphics.lpk b/rgb/lazrgbgraphics.lpk
old mode 100644
new mode 100755
diff --git a/rgb/lazrgbgraphics.pas b/rgb/lazrgbgraphics.pas
old mode 100644
new mode 100755
diff --git a/rgb/rgbcarbonroutines.pas b/rgb/rgbcarbonroutines.pas
old mode 100644
new mode 100755
diff --git a/rgb/rgbgraphics.pas b/rgb/rgbgraphics.pas
old mode 100644
new mode 100755
diff --git a/rgb/rgbgtkroutines.pas b/rgb/rgbgtkroutines.pas
old mode 100644
new mode 100755
diff --git a/rgb/rgbqtroutines.pas b/rgb/rgbqtroutines.pas
old mode 100644
new mode 100755
diff --git a/rgb/rgbroutines.pas b/rgb/rgbroutines.pas
old mode 100644
new mode 100755
diff --git a/rgb/rgbtypes.pas b/rgb/rgbtypes.pas
old mode 100644
new mode 100755
diff --git a/rgb/rgbutils.pas b/rgb/rgbutils.pas
old mode 100644
new mode 100755
diff --git a/rgb/rgbwinroutines.pas b/rgb/rgbwinroutines.pas
old mode 100644
new mode 100755
diff --git a/stat.pas b/stat.pas
old mode 100644
new mode 100755
diff --git a/statclustertable.pas b/statclustertable.pas
old mode 100644
new mode 100755
diff --git a/templates/aal.nii.gz b/templates/aal.nii.gz
old mode 100644
new mode 100755
diff --git a/templates/aal.nii.lut b/templates/aal.nii.lut
old mode 100644
new mode 100755
diff --git a/templates/aal.nii.txt b/templates/aal.nii.txt
old mode 100644
new mode 100755
diff --git a/templates/brodmann.nii.gz b/templates/brodmann.nii.gz
old mode 100644
new mode 100755
diff --git a/templates/brodmann.nii.lut b/templates/brodmann.nii.lut
old mode 100644
new mode 100755
diff --git a/templates/ch2bet.nii.gz b/templates/ch2bet.nii.gz
old mode 100644
new mode 100755
diff --git a/Text.lfm b/text.lfm
old mode 100644
new mode 100755
similarity index 86%
rename from Text.lfm
rename to text.lfm
index b2d43f9..21b3eb3
--- a/Text.lfm
+++ b/text.lfm
@@ -7,15 +7,16 @@ object TextForm: TTextForm
VertScrollBar.Page = 459
ActiveControl = MemoT
Caption = 'Descriptive Statistics'
- ClientHeight = 461
+ ClientHeight = 480
ClientWidth = 696
Font.Height = -11
Font.Name = 'MS Sans Serif'
Menu = MainMenu1
- LCLVersion = '0.9.29'
+ OnCreate = FormCreate
+ LCLVersion = '0.9.30.2'
object MemoT: TMemo
Left = 0
- Height = 461
+ Height = 480
Top = 0
Width = 696
Align = alClient
@@ -44,4 +45,4 @@ object TextForm: TTextForm
end
end
end
-end
+end
\ No newline at end of file
diff --git a/text.pas b/text.pas
old mode 100644
new mode 100755
index 06a1e58..794d1b4
--- a/text.pas
+++ b/text.pas
@@ -10,6 +10,9 @@ uses
Menus, StdCtrls,Define_Types;
type
+
+ { TTextForm }
+
TTextForm = class(TForm)
MainMenu1: TMainMenu;
File1: TMenuItem;
@@ -20,6 +23,7 @@ type
MemoT: TMemo;
procedure Closewindow1Click(Sender: TObject);
procedure Copy2Click(Sender: TObject);
+ procedure FormCreate(Sender: TObject);
procedure Save1Click(Sender: TObject);
private
{ Private declarations }
@@ -52,6 +56,17 @@ begin
MemoT.CopyToClipboard;
end;
+procedure TTextForm.FormCreate(Sender: TObject);
+begin
+ {$IFDEF Darwin}
+ {$IFNDEF LCLgtk} //only for Carbon compile
+ Copy2.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ Save1.ShortCut := ShortCut(Word('S'), [ssMeta]);
+ Closewindow1.ShortCut := ShortCut(Word('W'), [ssMeta]);
+ {$ENDIF}
+ {$ENDIF}
+end;
+
procedure TTextForm.Save1Click(Sender: TObject);
begin
ImgForm.SaveDialog1.Filename := parsefilename(gMRIcroOverlay[kBGOverlayNum].HdrFilename);
@@ -73,4 +88,4 @@ initialization
{$ENDIF}
-end.
+end.
\ No newline at end of file
diff --git a/voismooth.lfm b/voismooth.lfm
old mode 100644
new mode 100755
diff --git a/voismooth.lrs b/voismooth.lrs
old mode 100644
new mode 100755
diff --git a/voismooth.pas b/voismooth.pas
old mode 100644
new mode 100755
diff --git a/wgraphics.pas b/wgraphics.pas
old mode 100644
new mode 100755
diff --git a/winmemmap.pas b/winmemmap.pas
old mode 100644
new mode 100755
diff --git a/winres.res b/winres.res
old mode 100644
new mode 100755
diff --git a/xclip.bat b/xclip.bat
old mode 100644
new mode 100755
diff --git a/xcut.bat b/xcut.bat
old mode 100644
new mode 100755
diff --git a/xfmri.bat b/xfmri.bat
old mode 100644
new mode 100755
diff --git a/xfmri2.bat b/xfmri2.bat
old mode 100644
new mode 100755
diff --git a/xfmri3.bat b/xfmri3.bat
old mode 100644
new mode 100755
diff --git a/yokesharemem.pas b/yokesharemem.pas
old mode 100644
new mode 100755
diff --git a/zconf.inc b/zconf.inc
old mode 100644
new mode 100755
--
Alioth's /git/debian-med/git-commit-notice on /srv/git.debian.org/git/debian-med/mricron.git
More information about the debian-med-commit
mailing list