[med-svn] [mricron] 01/05: Imported Upstream version 0.20140303.1~dfsg.1
Michael Hanke
mih at moszumanska.debian.org
Fri Oct 3 09:09:48 UTC 2014
This is an automated email from the git hooks/post-receive script.
mih pushed a commit to branch master
in repository mricron.
commit f48c45f034d6939630073aa7a4ff380d4652806b
Author: Michael Hanke <michael.hanke at gmail.com>
Date: Mon Apr 14 09:52:53 2014 +0200
Imported Upstream version 0.20140303.1~dfsg.1
---
ROIfilt.pas | 4 +-
_macscriptintel.bat | 8 +
common/define_types.pas | 51 +-
common/dialogsx.pas | 9 +
common/dicomhdr.pas | 29 +-
common/gzio2.pas | 284 ++++++-
common/gziod.pas | 50 +-
common/nifti_foreign.pas | 1285 +++++++++++++++++++++++++++++++
common/nifti_hdr.pas | 540 +++----------
common/nifti_types.pas | 166 ++++
crop.pas | 4 +-
dcm2nii/convert.pas | 156 +++-
dcm2nii/csaread.pas | 172 ++++-
dcm2nii/dcm2nii.lpi | 211 +++--
dcm2nii/dcm2niigui.cfg | 8 +-
dcm2nii/dcm2niigui.dof | 11 +-
dcm2nii/dcm2niigui.ini | 5 +-
dcm2nii/dcm2niigui.lpi | 331 ++++----
dcm2nii/dicomcompat.pas | 39 +-
dcm2nii/dicomtypes.pas | 67 +-
dcm2nii/filename.pas | 2 +-
dcm2nii/gui.dfm | Bin 2463 -> 2463 bytes
dcm2nii/gui.pas | 11 +-
dcm2nii/nifti_form.lfm | 27 +-
dcm2nii/nifti_form.lrs | 115 +--
dcm2nii/niftiutil.pas | 381 ++++-----
dcm2nii/nii_3dto4d.pas | 16 +-
dcm2nii/nii_4dto3d.pas | 19 +-
dcm2nii/nii_asl.pas | 48 +-
dcm2nii/nii_crop.pas | 88 +--
dcm2nii/nii_math.pas | 22 +-
dcm2nii/nii_orient.pas | 15 +-
dcm2nii/nii_reslice.pas | 13 +-
dcm2nii/paramstrs.pas | 5 +
dcm2nii/parconvert.pas | 2 +-
dcm2nii/pref_form.lfm | 92 ++-
dcm2nii/pref_form.lrs | 99 +--
dcm2nii/pref_form.pas | 5 +
dcm2nii/prefs.pas | 5 +-
drop.patch | 75 ++
drop_patch.txt | 1620 +++++++++++++++++++++++++++++++++++++++
imgutil.pas | 4 +-
mricron.ini | 19 +-
mricron.lpi | 511 ++++++------
mricron.lpr | 2 +-
nifti_hdr_view.lfm | 180 ++---
nifti_hdr_view.lrs | 236 +++---
nifti_hdr_view.pas | 25 +-
nifti_img.pas | 246 ++++--
nifti_img_view.lfm | 60 +-
nifti_img_view.lrs | 332 ++++----
nifti_img_view.pas | 377 +++++----
nii_label.pas | 257 +++++++
npm/MeanFLU.nii.gz | Bin 0 -> 291497 bytes
npm/Notes.txt | 52 ++
npm/hdr.pas | 19 +-
npm/nifti_img.pas | 2 +-
npm/npm.app/Contents/Info.plist | 0
npm/npm.app/Contents/MacOS/npm | 0
npm/npm.app/Contents/PkgInfo | 0
npm/npm.cfg | 8 +-
npm/npm.dof | 9 +-
npm/npm.dsk | 184 -----
npm/npm.lpi | 267 ++++---
npm/npmform.dfm | Bin 5083 -> 5082 bytes
npm/npmform.lfm | 19 +-
npm/npmform.lrs | 150 ++--
npm/npmform.pas | 84 +-
npm/regression.pas | 9 +-
npm/stats.pas | 1 -
npm/tfce_clustering.pas | 2 +-
npm/turbolesion.pas | 2 +-
npm/unpm.pas | 17 +-
npm/wlsFLU.nii.gz | Bin 0 -> 293632 bytes
ortho_reorient.pas | 2 +-
render_composite.pas | 4 +-
reslice_img.pas | 4 +-
statclustertable.pas | 41 +-
templates/aal.nii.txt | 117 ---
79 files changed, 6533 insertions(+), 2799 deletions(-)
diff --git a/ROIfilt.pas b/ROIfilt.pas
index e859bcd..dfe9d90 100755
--- a/ROIfilt.pas
+++ b/ROIfilt.pas
@@ -10,7 +10,7 @@ uses
{$ENDIF}
{$IFNDEF Unix} Windows,{$ENDIF}
Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, Buttons,define_types, nifti_hdr;
+ StdCtrls, Buttons,define_types, nifti_hdr, nifti_types;
type
TFilterROIform = class(TForm)
@@ -180,4 +180,4 @@ initialization
{$I ROIfilt.lrs}
{$ENDIF}
-end.
+end.
\ No newline at end of file
diff --git a/_macscriptintel.bat b/_macscriptintel.bat
index 9b2f8f9..bde8a1f 100755
--- a/_macscriptintel.bat
+++ b/_macscriptintel.bat
@@ -6,6 +6,8 @@ mv ./dcm2nii/dcm2nii ../distro/dcm2nii64
lazbuild ./dcm2nii/dcm2nii.lpr
cp ./dcm2nii/dcm2nii ../distro/intel/dcm2nii
+#assume we will not lipo PPC versions...
+cp ./dcm2nii/dcm2nii ../distro/dcm2nii
./_xclean.bat
cp ./common/gui.inc ./common/isgui.inc
@@ -17,3 +19,9 @@ lazbuild ./dcm2nii/dcm2niigui.lpr --ws=carbon
cp ./mricron ../distro/intel/mricron
cp ./npm/npm ../distro/intel/npm
cp ./dcm2nii/dcm2niigui ../distro/intel/dcm2niigui
+
+#assume we will not lipo PPC versions...
+cp ./dcm2nii/dcm2nii ../distro/dcm2nii
+cp ./mricron ../distro/mricron.app/contents/MacOS/mricron
+cp ./npm/npm ../distro/npm.app/contents/MacOS/npm
+cp ./dcm2nii/dcm2niigui ../distro/dcm2niigui.app/contents/MacOS/dcm2niigui
diff --git a/common/define_types.pas b/common/define_types.pas
index a24a8e0..5ba7b5f 100755
--- a/common/define_types.pas
+++ b/common/define_types.pas
@@ -18,23 +18,28 @@ interface
SysUtils,classes,IniFiles,
{$IFDEF GUI} forms,userdir, dialogs{$ELSE}dialogsx{$ENDIF};
const
- kMRIcronVersDate = '28 August 2013';
+ kMRIcronVersDate = '3/3/2014';
{$ifdef CPU32}
- kMRIcronVers = kMRIcronVersDate+' 32bit';
+ kMRIcronVers = kMRIcronVersDate+' 32bit BSD License';
{$ELSE}
- kMRIcronVers = kMRIcronVersDate+' 64bit';
+ kMRIcronVers = kMRIcronVersDate+' 64bit BSD License';
{$ENDIF}
NaN : double = 1/0;
kMagicDouble : double = -111666222;
kTxtFilter = 'Text (*.txt)|*.txt;*.csv|Comma Separated (*.csv)|*.csv';
- kNIIFilter = 'NIfTI (*.nii)|*.nii';
kAnyFilter = 'Anything (*)|*';
kAnaHdrFilter = 'Analyze Header (*.hdr)|*.hdr';
- kImgPlusVOIFilter = 'NIfTI/Analyze/VOI|*.hdr;*.nii;*.nii.gz;*.voi|NIfTI/Analyze Header (*.hdr;*.nii)|*.hdr;*.nii;*.nii.gz|Volume of interest (*.voi)|*.voi';
- kImgFilter = 'NIfTI/Analyze Header (*.hdr;*.nii)|*.hdr;*.nii;*.nii.gz|Volume of interest (*.voi)|*.voi';
- kImgFilterPlusAny = 'NIfTI/Analyze Header (*.hdr;*.nii)|*.hdr;*.nii;*.nii.gz|Volume of interest (*.voi)|*.voi|Any file (*.*)|*.*';
+ //kNIIFilter = 'NIfTI (*.nii)|*.nii';
+ //kImgPlusVOIFilter = 'NIfTI/Analyze/VOI|*.hdr;*.nii;*.nii.gz;*.voi|NIfTI/Analyze Header (*.hdr;*.nii)|*.hdr;*.nii;*.nii.gz|Volume of interest (*.voi)|*.voi';
+ //kImgFilter = 'NIfTI/Analyze Header (*.hdr;*.nii)|*.hdr;*.nii;*.nii.gz|Volume of interest (*.voi)|*.voi';
+ //kImgFilterPlusAny = 'NIfTI/Analyze Header (*.hdr;*.nii)|*.hdr;*.nii;*.nii.gz|Volume of interest (*.voi)|*.voi|Any file (*.*)|*.*';
+
+ kNIIFilter = 'Neuroimaging (*.nii)|*.hdr;*.nii;*.nii.gz;*.voi;*.HEAD;*.mgh;*.mgz;*.mha;*.mhd;*.nhdr;*.nrrd';
+ kImgFilter = 'Neuroimaging|*.hdr;*.nii;*.nii.gz;*.HEAD;*.mgh;*.mgz;*.mha;*.mhd;*.nhdr;*.nrrd|Volume of interest (*.voi)|*.voi';
+ kImgPlusVOIFilter = 'Neuroimaging/VOI|*.hdr;*.nii;*.nii.gz;*.voi;*.HEAD;*.mgh;*.mgz;*.mha;*.mhd;*.nhdr;*.nrrd|NIfTI/Analyze Header (*.hdr;*.nii)|*.hdr;*.nii;*.nii.gz|Volume of interest (*.voi)|*.voi';
+ kImgFilterPlusAny = 'Neuroimaging/VOI|*.hdr;*.nii;*.nii.gz;*.voi;*.HEAD;*.mgh;*.mgz;*.mha;*.mhd;*.nhdr;*.nrrd|NIfTI/Analyze Header (*.hdr;*.nii)|*.hdr;*.nii;*.nii.gz|Volume of interest (*.voi)|*.voi|Anything (*.*)|*.*';
kHistoBins = 256;//numbers of bins for histogram/image balance
PixelCountMax = 32768;
kTab = chr(9);
@@ -54,6 +59,7 @@ const
{$ENDIF}
type
+ TStrRA = Array of String;
TPSPlot = RECORD //peristimulus plot
TRSec,BinWidthSec: single;
nNegBins,nPosBins,SPMDefaultsStatsFmriT,SPMDefaultsStatsFmriT0: integer;
@@ -159,7 +165,7 @@ procedure pswap4r ( var s:single); //procedure to endian-swap 32-bit integer
function swap64r(s : double):double;
function specialdouble (d:double): boolean;
function RealToStr(lR: double {was extended}; lDec: integer): string;
-function UpCaseExt(lFileName: string): string;
+function UpCaseExt(lFileName: string): string;//file.brik.gz->BRIK.GZ, file.nii.gz -> NII.GZ
function ExtGZ (lFilename: string): boolean;
procedure swap4(var s : LongInt);
procedure Xswap4r ( var s:single);
@@ -391,6 +397,15 @@ var
begin
result := false;
lExt := UpCaseExt(lStr);
+ if (lExt = '.MGH') or (lExt = '.MGZ') then
+ result := true;
+ if (lExt = '.MHA') or (lExt = '.MHD') then
+ result := true;
+ if (lExt = '.HEAD') then
+ result := true;
+ if (lExt = '.NRRD') then
+ result := true;
+
if (lExt = '.NII') or (lExt = '.NII.GZ') then
result := true;
if (lExt = '.HDR') and (FSize(ChangeFileExt(lStr,'.img'))> 0) then
@@ -1020,8 +1035,10 @@ begin
lI := length(lFileName) - 6;
if li < 1 then exit;
l2ndExt := upcase(lFileName[lI])+upcase(lFileName[lI+1])+upcase(lFileName[li+2])+upcase(lFileName[li+3]);
- if l2ndExt = '.NII' then
- result := '.NII.GZ'
+ if (l2ndExt = '.NII')then
+ result := l2ndExt+lExt
+ else if (l2ndExt = 'BRIK') and (lI > 1) and (lFileName[lI-1] = '.') then
+ result := '.BRIK'+lExt;
end;
function ExtGZ (lFilename: string): boolean;
@@ -1243,6 +1260,18 @@ end;
function ParseFileName (lFilewExt:String): string;
var
+ lExt: string;
+ i: integer;
+begin
+ lExt := UpCaseExt(lFilewExt);
+ if (length(lExt) < 1) or (length(lExt) >= length(lFilewExt)) then exit;
+ result := '';
+ for i := 1 to (length(lFilewExt)-length(lExt)) do
+ result := result + lFilewExt[i];
+end;
+
+(*function ParseFileName (lFilewExt:String): string;
+var
lLen,lInc: integer;
lName: String;
begin
@@ -1264,7 +1293,7 @@ begin
else
lName := lFilewExt; //no extension
ParseFileName := lName;
-end;
+end; *)
Function {TMainForm.}FileExistsEX(Name: String): Boolean;
var
diff --git a/common/dialogsx.pas b/common/dialogsx.pas
index d7db548..c9f9354 100755
--- a/common/dialogsx.pas
+++ b/common/dialogsx.pas
@@ -18,6 +18,9 @@ function MsgDlg(const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons
function GetInt(lStr: string; lMin,lDefault,lMax: integer): integer;
procedure MyReadLn;//no GUI: waits for user
function GetStr(lPrompt: string): string;
+
+
+ {$IFNDEF GUI}procedure ShowMessage (lStr: string); {$ENDIF}
//procedure vx (a,b,c,d: double);
const
@@ -36,6 +39,12 @@ begin
{$ENDIF}
end;
+{$IFNDEF GUI}procedure ShowMessage (lStr: string);
+begin
+writeln(lStr) ;
+end;
+
+{$ENDIF}
procedure vx (a,b,c,d: double); //vx used to help debugging - reports number values
begin
diff --git a/common/dicomhdr.pas b/common/dicomhdr.pas
index 81e454d..99ca461 100755
--- a/common/dicomhdr.pas
+++ b/common/dicomhdr.pas
@@ -4,16 +4,16 @@ unit dicomhdr;
interface
uses
{$IFNDEF FPC}Controls, {$ENDIF}
- SysUtils,define_types,classes,nifti_hdr,GraphicsMathLibrary;
+ SysUtils,define_types,classes,nifti_hdr,GraphicsMathLibrary, nifti_types;
function NIFTIhdr_LoadDCM (var lFilename: string; var lHdr: TMRIcroHdr): boolean;
type
kDICOMStr = String[32];
- DICOMdata = record
- XYZdim: array [1..4] of integer;
- XYZori: array [1..3] of integer;
- XYZmm: array [1..3] of double;
- Orient: array [1..6] of double;
+ DICOMdata = record
+ XYZdim: array [1..4] of integer;
+ XYZori: array [1..3] of integer;
+ XYZmm: array [1..3] of double;
+ Orient: array [1..6] of double;
Float,file4D: boolean;
PatientPosX,PatientPosY,PatientPosZ,AngulationAP,AngulationFH,AngulationRL: double;
TE, TR,IntenScale,IntenIntercept,location{,DTIv1,DTIv2,DTIv3}: single;
@@ -26,11 +26,11 @@ end;
implementation
-uses dialogs;
+uses dialogsx;
procedure Msg(lStr: string);
begin
- Showmessage(lStr);
+ ShowMsg(lStr);
end;
procedure clear_dicom_data (var lDicomdata:Dicomdata);
@@ -153,7 +153,6 @@ begin
lFStr := lFStr + lStr[lP]
else if (lFStr <> '') then begin
inc(lnF);
- //if lnFloats = 6 then showmessage(lFStr);
try
lFloatRA[lnF] := strtofloat(lFStr);
except on EConvertError do
@@ -215,7 +214,6 @@ begin
lLength := ReadInt4;
exit;
end;
-
if (vr = 'UN') {2/2008} or (vr = 'OB') or (vr = 'OW') or (vr = 'SQ') then begin {explicit VR with 32-bit length}
lPos := lPos + 4; {skip 2 byte string and 2 reserved bytes = 4 bytes = 2 words}
lLength := ReadInt4;//Ord4(buf[lPos]) + $100 * (buf[lPos+1] + $100 * (buf[lPos+2] + $100 * buf[lPos+3]))
@@ -295,8 +293,6 @@ begin
else
result := GetByte(lPos)+(GetByte(lPos+1) shl 8)+(GetByte(lPos+2) shl 16)+(GetByte(lPos+3) shl 24);; //byte order??
end; //function DCMint
-
-
var
lTempStr,lStr: string;
lOffset,lTemp,lGroupElement,lLength,lEchoNum,lnVol: integer;
@@ -371,7 +367,6 @@ begin //function fast_read_dicom_data
if lStr = 'MOSAIC' then
lDicomData.SiemensMosaicX := 2; //we need to read numaris for details...
end;
-
kStudyDate: lDicomData.StudyDate := DCMStr(lLength);
kStudyTime : lDicomData.StudyTime := DCMStr(lLength);
kPatientName : lDicomData.PatientName := DCMStr(lLength);
@@ -424,11 +419,9 @@ begin //function fast_read_dicom_data
lDicomData.SeriesNum := lDicomData.SeriesNum + 100;
if (lDICOMData.SlicesPer3DVol > 0) and (lnVol > 1) and (lDicomdata.XYZdim[3] > 1) and (lDicomData.SlicesPer3DVol > 0)and ((lDicomdata.XYZdim[3] mod lDicomData.SlicesPer3DVol) = 0) then
lDICOMdata.File4D := true;
-
if not lBufferError then
result := true;
FreeMem(lByteRA);
-
if result then begin
lHdr.HdrFileName:= lFilename;
lHdr.ImgFileName:= lFilename;
@@ -445,7 +438,6 @@ begin //function fast_read_dicom_data
else begin
Msg('Unsupported DICOM bit-depth : +inttostr(lDicomData.Allocbits_per_pixel.');
result := false;
-
end;
end;
lHdr.NIFTIhdr.vox_offset := lDicomData.ImageStart;
@@ -454,7 +446,6 @@ begin //function fast_read_dicom_data
lHdr.NIFTIhdr.pixdim[2] := lDicomdata.XYZmm[2];
lHdr.NIFTIhdr.pixdim[3] := lDicomdata.XYZmm[3];
NIFTIhdr_SetIdentityMatrix(lHdr);
-
lHdr.NIFTIhdr.dim[1] := lDicomdata.XYZdim[1];
lHdr.NIFTIhdr.dim[2] := lDicomdata.XYZdim[2];
lHdr.NIFTIhdr.dim[3] := lDicomdata.XYZdim[3];
@@ -470,11 +461,9 @@ begin //function fast_read_dicom_data
lHdr.NIFTIhdr.srow_x[0] := lHdr.NIFTIhdr.pixdim[1];
lHdr.NIFTIhdr.srow_y[1] := lHdr.NIFTIhdr.pixdim[2];
lHdr.NIFTIhdr.srow_z[2] := lHdr.NIFTIhdr.pixdim[3];
-
lHdr.NIFTIhdr.srow_x[3] := (lHdr.NIFTIhdr.dim[1] /2)*-lHdr.NIFTIhdr.pixdim[1];
lHdr.NIFTIhdr.srow_y[3] := (lHdr.NIFTIhdr.dim[2] /2)*-lHdr.NIFTIhdr.pixdim[2];
lHdr.NIFTIhdr.srow_z[3] := (lHdr.NIFTIhdr.dim[3] /2)*-lHdr.NIFTIhdr.pixdim[3];
- //fx(lHdr.NIFTIhdr.srow_z[3],lOri[3]);
lHdr.Mat:= Matrix3D(
lHdr.NIFTIhdr.srow_x[0],lHdr.NIFTIhdr.srow_x[1],lHdr.NIFTIhdr.srow_x[2],lHdr.NIFTIhdr.srow_x[3], // 3D "graphics" matrix
lHdr.NIFTIhdr.srow_y[0],lHdr.NIFTIhdr.srow_y[1],lHdr.NIFTIhdr.srow_y[2],lHdr.NIFTIhdr.srow_y[3], // 3D "graphics" matrix
@@ -495,4 +484,4 @@ begin //function fast_read_dicom_data
end; //function NIFTIhdr_LoadDCM
-end.
+end.
\ No newline at end of file
diff --git a/common/gzio2.pas b/common/gzio2.pas
index 9a31d96..58a2cf6 100755
--- a/common/gzio2.pas
+++ b/common/gzio2.pas
@@ -32,9 +32,12 @@ 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: int64); //unzip
+procedure UnGZip2 (var lInFname: string; var lBuf: ByteP; lOffset,lMaxSz,Skip: int64); //unzip after skipping a few bytes
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;
+function gzopen (path:string; mode:string) : gzFile; overload;
+function gzopen (path:string; mode:string; skip: integer) : gzFile; overload;
+
function gzread (f:gzFile; buf:pointer; len:cardinal) : integer;
function gzgetc (f:gzfile) : integer;
function gzgets (f:gzfile; buf:Pchar; len:integer) : Pchar;
@@ -104,11 +107,64 @@ end;
type gz_streamp = ^gz_stream;
-function destroy (var s:gz_streamp) : integer; forward;
+function zdestroy (var s:gz_streamp) : integer; forward;
procedure check_header(s:gz_streamp); forward;
+procedure UnGZip2 (var lInFname: string; var lBuf: ByteP; lOffset,lMaxSz,Skip: int64); //unzip
+const
+BUFLEN = 16384;
+var
+ infile : gzFile;
+ lFname : ansistring;
+ lbufsz,len,lI,written : int64;
+ buf : packed array [0..BUFLEN-1] of byte; { Global uses BSS instead of stack }
+begin
+ lFName := lInFName;
+ infile := gzopen (lFName, 'r',Skip);
+ written := 0;
+ if lOffset > 0 then begin
+ Len := lOffset div BUFLEN;
+ if Len > 0 then begin
+ lI := 1;
+ while (lI <= Len) do begin
+ gzread (infile, @buf, BUFLEN {1388});
+ inc(lI);
+ end;
+ end;
-procedure UnGZip (var lInFname: string; var lBuf: ByteP; lOffset,lMaxSz: int64); //unzip
+ Len := lOffset mod BUFLEN;
+ gzread (infile, @buf, Len);
+ end;
+ lbufsz := BUFLEN;
+ if lMaxSz < BUFLEN then
+ lbufsz := lMaxSz;
+ while true do begin
+ len := gzread (infile, @buf, lbufsz);
+ if (len < 0) then begin
+ break
+ end;
+ if (len = 0)
+ then break;
+ if (Written+len) > lMaxSz then begin
+ if Written < lMaxSz then
+ Move(buf,lbuf^[Written+1],lMaxSz-Written); //cr2007
+ break;
+ end;
+ Move(buf,lbuf^[Written+1],len);
+ Written := Written + len;
+ end; {WHILE}
+ gzclose (infile);
+ //filemode := 2;
+end;
+
+procedure UnGZip (var lInFname: string; var lBuf: ByteP; lOffset,lMaxSz: int64);
+begin
+ UnGZip2 ( lInFname, lBuf, lOffset,lMaxSz,0);
+
+end;
+
+
+(*procedure UnGZip (var lInFname: string; var lBuf: ByteP; lOffset,lMaxSz: int64); //unzip
const
BUFLEN = 16384;
var
@@ -161,7 +217,7 @@ begin
end; {WHILE}
gzclose (infile);
//filemode := 2;
-end;
+end; *)
procedure UnGZipCore (var infile : gzFile; var lBuf: ByteP; lReadBytes: integer; lWrite: boolean);
@@ -560,7 +616,7 @@ begin
//if (s^.mode='w') then begin path := path+'.gz'; end;
s^.path := path; { limit to 255 chars }
if (s^.mode=chr(0)) then begin
- destroyS(s);
+ zdestroyS(s);
result := gzFile(Z_NULL);
exit;
end;
@@ -577,7 +633,7 @@ begin
s^.stream.next_out := s^.outbuf;
{$ENDIF}
if (err <> Z_OK) or (s^.outbuf = Z_NULL) then begin
- destroyS(s);
+ zdestroyS(s);
result := gzFile(Z_NULL);
exit;
end;
@@ -591,7 +647,7 @@ begin
{ windowBits is passed < 0 to tell that there is no zlib header }
if (err <> Z_OK) or (s^.inbuf = Z_NULL) then begin
- destroyS(s);
+ zdestroyS(s);
result := gzFile(Z_NULL);
exit;
end;
@@ -618,7 +674,7 @@ begin
{$endif}
{$IFDEF IOCheck} {$I+} {$ENDIF}
if (IOResult <> 0) then begin
- destroyS(s);
+ zdestroyS(s);
result := gzFile(Z_NULL);
exit;
end;
@@ -683,8 +739,163 @@ end; *)
(zlib error is Z_MEM_ERROR).
============================================================================}
+function gzopen (path:string; mode:string; skip: integer) : gzFile;
+
+var
+
+ i : cardinal;
+ err : integer;
+ level : integer; { compression level }
+ strategy : integer; { compression strategy }
+ s : gz_streamp;
+{$ifdef UNIX}
+ info: stat;
+{$else}
+ attr: word;
+{$endif}
+
+{$IFNDEF NO_DEFLATE}
+ gzheader : array [0..9] of byte;
+{$ENDIF}
+
+begin
+
+ if (path='') or (mode='') then begin
+ gzopen := nil;
+ exit;
+ end;
+
+ GetMem (s,sizeof(gz_stream));
+ if not Assigned (s) then begin
+ gzopen := nil;
+ exit;
+ end;
+
+ level := Z_DEFAULT_COMPRESSION;
+ strategy := Z_DEFAULT_STRATEGY;
+
+ s^.stream.next_in := nil;
+ s^.stream.next_out := nil;
+ s^.stream.avail_in := 0;
+ s^.stream.avail_out := 0;
+ s^.z_err := Z_OK;
+ s^.z_eof := false;
+ s^.inbuf := nil;
+ s^.outbuf := nil;
+ s^.crc := crc32(0, nil, 0);
+ //s^.msg := '';
+ s^.transparent := false;
+
+ s^.zpath := path; { limit to 255 chars }
+
+ s^.mode := chr(0);
+ for i:=1 to Length(mode) do begin
+ case mode[i] of
+ 'r' : s^.mode := 'r';
+ 'w' : s^.mode := 'w';
+ '0'..'9' : level := Ord(mode[i])-Ord('0');
+ 'f' : strategy := Z_FILTERED;
+ 'h' : strategy := Z_HUFFMAN_ONLY;
+ end;
+ end;
+ if (s^.mode=chr(0)) then begin
+ zdestroy(s);
+ gzopen := gzFile(nil);
+ exit;
+ end;
+
+ if (s^.mode='w') then begin
+{$IFDEF NO_DEFLATE}
+ err := Z_STREAM_ERROR;
+{$ELSE}
+ err := deflateInit2 (s^.stream, level, Z_DEFLATED, -MAX_WBITS,
+ DEF_MEM_LEVEL, strategy);
+ { windowBits is passed < 0 to suppress zlib header }
+
+ GetMem (s^.outbuf, Z_BUFSIZE);
+ s^.stream.next_out := s^.outbuf;
+{$ENDIF}
+ if (err <> Z_OK) or (s^.outbuf = nil) then begin
+ zdestroy(s);
+ gzopen := gzFile(nil);
+ exit;
+ end;
+ end
+
+ else begin
+ GetMem (s^.inbuf, Z_BUFSIZE);
+ s^.stream.next_in := s^.inbuf;
+
+ err := inflateInit2_ (s^.stream, -MAX_WBITS, ZLIB_VERSION, sizeof(z_stream));
+ { windowBits is passed < 0 to tell that there is no zlib header }
+
+ if (err <> Z_OK) or (s^.inbuf = nil) then begin
+ zdestroy(s);
+ gzopen := gzFile(nil);
+ exit;
+ end;
+ end;
+
+ s^.stream.avail_out := Z_BUFSIZE;
+ //showmessage(s^.path+' '+inttostr(length(path)));
+ {$IFOPT I+} {$I-} {$define IOcheck} {$ENDIF}
+ //11/11/07 Assign (s^.gzfile, s^.path);
+ Assign (s^.gzfile, path);
+ {$ifdef unix}
+ if (fpstat(s^.zpath,info)<0) and (s^.mode='w') then
+ ReWrite (s^.gzfile,1)
+ else begin
+ Reset (s^.gzfile,1);
+ if skip > 0 then Seek(s^.gzfile,skip);
+ end;
+ {$else}
+ GetFAttr(s^.gzfile, Attr);
+ if (DosError <> 0) and (s^.mode='w') then
+ ReWrite (s^.gzfile,1)
+ else begin
+ Reset (s^.gzfile,1);
+ if skip > 0 then Seek(s^.gzfile,skip);
+ end;
+ {$endif}
+ {$IFDEF IOCheck} {$I+} {$ENDIF}
+
+ if (IOResult <> 0) then begin
+ zdestroy(s);
+ gzopen := gzFile(nil);
+ exit;
+ end;
+
+ if (s^.mode = 'w') then begin { Write a very simple .gz header }
+{$IFNDEF NO_DEFLATE}
+ gzheader [0] := gz_magic [0];
+ gzheader [1] := gz_magic [1];
+ gzheader [2] := Z_DEFLATED; { method }
+ gzheader [3] := 0; { flags }
+ gzheader [4] := 0; { time[0] }
+ gzheader [5] := 0; { time[1] }
+ gzheader [6] := 0; { time[2] }
+ gzheader [7] := 0; { time[3] }
+ gzheader [8] := 0; { xflags }
+ gzheader [9] := 0; { OS code = MS-DOS }
+ blockwrite (s^.gzfile, gzheader, 10);
+ s^.startpos := longint(10);
+{$ENDIF}
+ end
+ else begin
+ check_header(s); { skip the .gz header }
+ s^.startpos := FilePos(s^.gzfile) - s^.stream.avail_in;
+ end;
+
+ gzopen := gzFile(s);
+end;
function gzopen (path:string; mode:string) : gzFile;
+begin
+ result := gzopen(path,mode,0);
+
+end;
+
+(*2015 function gzopen (path:string; mode:string) : gzFile;
var
@@ -743,7 +954,7 @@ begin
end;
end;
if (s^.mode=chr(0)) then begin
- destroy(s);
+ zdestroy(s);
gzopen := gzFile(nil);
exit;
end;
@@ -760,7 +971,7 @@ begin
s^.stream.next_out := s^.outbuf;
{$ENDIF}
if (err <> Z_OK) or (s^.outbuf = nil) then begin
- destroy(s);
+ zdestroy(s);
gzopen := gzFile(nil);
exit;
end;
@@ -774,7 +985,7 @@ begin
{ windowBits is passed < 0 to tell that there is no zlib header }
if (err <> Z_OK) or (s^.inbuf = nil) then begin
- destroy(s);
+ zdestroy(s);
gzopen := gzFile(nil);
exit;
end;
@@ -799,7 +1010,7 @@ begin
{$endif}
{$IFDEF IOCheck} {$I+} {$ENDIF}
if (IOResult <> 0) then begin
- destroy(s);
+ zdestroy(s);
gzopen := gzFile(nil);
exit;
end;
@@ -826,7 +1037,7 @@ begin
end;
gzopen := gzFile(s);
-end;
+end; *)
{ GZSETPARAMS ===============================================================
@@ -957,6 +1168,8 @@ end;
============================================================================}
procedure check_header (s:gz_streamp);
+const
+ z_magic : array[0..1] of byte = ($78, $9C); //.z files simply have an abreviated header
var
@@ -964,13 +1177,14 @@ var
flags : integer; { flags byte }
len : cardinal;
c : integer;
-
+ cx: array[0..1] of integer;
begin
{ Check the gzip magic header }
for len := 0 to 1 do begin
c := get_byte(s);
- if (c <> gz_magic[len]) then begin
+ cx[len] := c;
+ if (c <> gz_magic[len]) and (c <> z_magic[len]) then begin
if (len <> 0) then begin
Inc(s^.stream.avail_in);
Dec(s^.stream.next_in);
@@ -985,7 +1199,12 @@ begin
exit;
end;
end;
-
+ if (cx[0] = z_magic[0]) and (cx[1] = z_magic[1]) then begin
+ //method := Z_DEFLATED;
+ //flags := 0; //none
+ s^.z_err := Z_OK;
+ exit;
+ end;
method := get_byte(s);
flags := get_byte(s);
if (method <> Z_DEFLATED) or ((flags and RESERVED) <> 0) then begin
@@ -1034,27 +1253,30 @@ end;
============================================================================}
-function destroy (var s:gz_streamp) : integer;
+function zdestroy (var s:gz_streamp) : integer;
begin
- destroy := Z_OK;
+ result := Z_OK;
if not Assigned (s) then begin
- destroy := Z_STREAM_ERROR;
+ result := Z_STREAM_ERROR;
exit;
end;
if (s^.stream.state <> nil) then begin
+
if (s^.mode = 'w') then begin
-{$IFDEF NO_DEFLATE}
- destroy := Z_STREAM_ERROR;
-{$ELSE}
- destroy := deflateEnd(s^.stream);
-{$ENDIF}
+ {$IFDEF NO_DEFLATE}
+ result := Z_STREAM_ERROR;
+ {$ELSE}
+ //showMsg('1666');
+ result := deflateEnd(s^.stream);
+ //showMsg('3666');
+ {$ENDIF}
end
else if (s^.mode = 'r') then begin
- destroy := inflateEnd(s^.stream);
+ result := inflateEnd(s^.stream);
end;
end;
@@ -1062,10 +1284,10 @@ begin
{$I-}
close(s^.gzfile);
{$I+}
- if (IOResult <> 0) then destroy := Z_ERRNO;
+ if (IOResult <> 0) then result := Z_ERRNO;
end;
- if (s^.z_err < 0) then destroy := s^.z_err;
+ if (s^.z_err < 0) then result := s^.z_err;
if Assigned (s^.inbuf) then
FreeMem(s^.inbuf, Z_BUFSIZE);
@@ -1708,17 +1930,16 @@ begin
exit;
{$ELSE}
err := do_flush (f, Z_FINISH);
+
if (err <> Z_OK) then begin
- gzclose := destroy (gz_streamp(f));
+ gzclose := zdestroy (gz_streamp(f));
exit;
end;
-
putLong (s^.gzfile, s^.crc);
putLong (s^.gzfile, s^.stream.total_in);
{$ENDIF}
end;
-
- gzclose := destroy (gz_streamp(f));
+ gzclose := zdestroy (gz_streamp(f));
end;
@@ -1802,6 +2023,7 @@ begin
errorcode := 0;
lensize := 0;
lInPos := 1;
+
while true do begin
len := (lInSize-lInPos)+1;
if len > Z_BUFSIZE then
diff --git a/common/gziod.pas b/common/gziod.pas
index a0456ac..1e3effb 100755
--- a/common/gziod.pas
+++ b/common/gziod.pas
@@ -3,6 +3,7 @@ interface
uses define_types,gzio,Windows,sysutils;
+procedure UnGZip2 (var lFname: string; var lBuf: ByteP{}; lOffset,lMaxSz: integer; Skip: int64); //unzip
procedure UnGZip (var lFname: string; var lBuf: ByteP{}; lOffset,lMaxSz: integer); //unzip
procedure UnGZipCore (var infile : gzFile; var lBuf: ByteP; lReadBytes: integer; lWrite: boolean);
function Gunzip (var FFileSource,FFileDestination: string): integer;
@@ -269,8 +270,7 @@ begin
Move(buf,lbuf[Written+1],len);
end; //ungzipCore
-procedure UnGZip (var lFname: string; var lBuf: ByteP{}; lOffset,lMaxSz: integer); //unzip
-//1417z- offset
+procedure UnGZip2 (var lFname: string; var lBuf: ByteP; lOffset,lMaxSz: integer; Skip: int64);
const
BUFLEN = 16384;
var
@@ -279,7 +279,7 @@ var
written : integer;
buf : packed array [0..BUFLEN-1] of byte; { Global uses BSS instead of stack }
begin
- infile := gzopenZ (lFName, 'r', 0);
+ infile := gzopenZskip (lFName, 'r', 0, Skip);
written := 0;
if lOffset > 0 then begin
Len := lOffset div BUFLEN;
@@ -310,6 +310,50 @@ begin
gzclose (infile);
end;
+procedure UnGZip (var lFname: string; var lBuf: ByteP; lOffset,lMaxSz: integer);
+begin
+ UnGZip2 (lFname, lBuf, lOffset,lMaxSz,0);
+end;
+(*procedure UnGZip (var lFname: string; var lBuf: ByteP; lOffset,lMaxSz: integer);
+const
+BUFLEN = 16384;
+var
+ infile : gzFile;
+ lbufsz,len,lI : integer;
+ written : integer;
+ buf : packed array [0..BUFLEN-1] of byte; { Global uses BSS instead of stack }
+begin
+ infile := gzopenZ (lFName, 'r', 0);
+ 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});
+ Len := lOffset mod BUFLEN;
+ gzread (infile, @buf, Len);
+ end;
+ lbufsz := BUFLEN;
+ if lMaxSz < BUFLEN then
+ lbufsz := lMaxSz;
+ while true do begin
+ len := gzread (infile, @buf, lbufsz);
+ if (len < 0) then begin
+ break
+ end;
+ if (len = 0)
+ then break;
+ if (Written+len) > lMaxSz then begin
+ if Written < lMaxSz then
+ Move(buf,lbuf[Written+1],lMaxSz-Written); //cr2007
+ break;
+ end;
+ Move(buf,lbuf[Written+1],len);
+ Written := Written + len;
+ end; {WHILE}
+ gzclose (infile);
+end;*)
+
procedure UnGZipFile (var lFname,lOUtname: string); //unzip
//1417z- offset
const
diff --git a/common/nifti_foreign.pas b/common/nifti_foreign.pas
new file mode 100755
index 0000000..1913822
--- /dev/null
+++ b/common/nifti_foreign.pas
@@ -0,0 +1,1285 @@
+unit nifti_foreign;
+
+interface
+{$H+}
+{$Include isgui.inc}
+
+uses
+{$IFNDEF FPC}
+ gziod,
+{$ELSE}
+ gzio2,
+{$ENDIF}
+{$IFDEF GUI}
+ dialogs,
+{$ELSE}
+ dialogsx,
+{$ENDIF}
+ nifti_types, define_types, sysutils, classes, StrUtils;//2015! dialogsx
+
+function readForeignHeader (var lFilename: string; var lHdr: TNIFTIhdr; var gzBytes: int64; var swapEndian: boolean): boolean;
+procedure NII_Clear (var lHdr: TNIFTIHdr);
+procedure NII_SetIdentityMatrix (var lHdr: TNIFTIHdr); //create neutral rotation matrix
+
+implementation
+
+Type
+ mat44 = array [0..3, 0..3] of Single;
+ vect4 = array [0..3] of Single;
+ mat33 = array [0..2, 0..2] of Single;
+ vect3 = array [0..2] of Single;
+ ivect3 = array [0..2] of integer;
+
+{$IFDEF GUI}
+procedure ShowMsg(s: string);
+begin
+ Showmessage(s);
+end;
+{$ENDIF}
+
+procedure fromMatrix (m: mat44; var r11,r12,r13,r21,r22,r23,r31,r32,r33: double);
+begin
+ r11 := m[0,0];
+ r12 := m[0,1];
+ r13 := m[0,2];
+ r21 := m[1,0];
+ r22 := m[1,1];
+ r23 := m[1,2];
+ r31 := m[2,0];
+ r32 := m[2,1];
+ r33 := m[2,2];
+end;
+
+function Matrix2D (r11,r12,r13,r21,r22,r23,r31,r32,r33: double): mat33;
+begin
+ result[0,0] := r11;
+ result[0,1] := r12;
+ result[0,2] := r13;
+ result[1,0] := r21;
+ result[1,1] := r22;
+ result[1,2] := r23;
+ result[2,0] := r31;
+ result[2,1] := r32;
+ result[2,2] := r33;
+end;
+
+function nifti_mat33_determ( R: mat33 ):double; //* determinant of 3x3 matrix */
+begin
+ result := r[0,0]*r[1,1]*r[2,2]
+ -r[0,0]*r[2,1]*r[1,2]
+ -r[1,0]*r[0,1]*r[2,2]
+ +r[1,0]*r[2,1]*r[0,2]
+ +r[2,0]*r[0,1]*r[1,2]
+ -r[2,0]*r[1,1]*r[0,2] ;
+end;
+
+function nifti_mat33_rownorm( A: mat33 ): single; // max row norm of 3x3 matrix
+var
+ r1,r2,r3: single ;
+begin
+ r1 := abs(A[0,0])+abs(A[0,1])+abs(A[0,2]);
+ r2 := abs(A[1,0])+abs(A[1,1])+abs(A[1,2]);
+ r3 := abs(A[2,0])+abs(A[2,1])+abs(A[2,2]);
+ if( r1 < r2 ) then r1 := r2 ;
+ if( r1 < r3 ) then r1 := r3 ;
+ result := r1 ;
+end;
+
+procedure fromMatrix33 (m: mat33; var r11,r12,r13,r21,r22,r23,r31,r32,r33: double);
+begin
+ r11 := m[0,0];
+ r12 := m[0,1];
+ r13 := m[0,2];
+ r21 := m[1,0];
+ r22 := m[1,1];
+ r23 := m[1,2];
+ r31 := m[2,0];
+ r32 := m[2,1];
+ r33 := m[2,2];
+end;
+
+function nifti_mat33_inverse( R: mat33 ): mat33; //* inverse of 3x3 matrix */
+var
+ r11,r12,r13,r21,r22,r23,r31,r32,r33 , deti: double ;
+begin
+ FromMatrix33(R,r11,r12,r13,r21,r22,r23,r31,r32,r33);
+ deti := r11*r22*r33-r11*r32*r23-r21*r12*r33
+ +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
+ if( deti <> 0.0 ) then deti := 1.0 / deti ;
+ result[0,0] := deti*( r22*r33-r32*r23) ;
+ result[0,1] := deti*(-r12*r33+r32*r13) ;
+ result[0,2] := deti*( r12*r23-r22*r13) ;
+ result[1,0] := deti*(-r21*r33+r31*r23) ;
+ result[1,1] := deti*( r11*r33-r31*r13) ;
+ result[1,2] := deti*(-r11*r23+r21*r13) ;
+ result[2,0] := deti*( r21*r32-r31*r22) ;
+ result[2,1] := deti*(-r11*r32+r31*r12) ;
+ result[2,2] := deti*( r11*r22-r21*r12) ;
+end;
+
+function nifti_mat33_colnorm( A: mat33 ): single; //* max column norm of 3x3 matrix */
+var
+ r1,r2,r3: single ;
+begin
+ r1 := abs(A[0,0])+abs(A[1,0])+abs(A[2,0]) ;
+ r2 := abs(A[0,1])+abs(A[1,1])+abs(A[2,1]) ;
+ r3 := abs(A[0,2])+abs(A[1,2])+abs(A[2,2]) ;
+ if( r1 < r2 ) then r1 := r2 ;
+ if( r1 < r3 ) then r1 := r3 ;
+ result := r1 ;
+end;
+
+function nifti_mat33_polar( A: mat33 ): mat33;
+var
+ k:integer;
+ X , Y , Z: mat33 ;
+ dif,alp,bet,gam,gmi : single;
+begin
+ dif := 1;
+ k := 0;
+ X := A ;
+ gam := nifti_mat33_determ(X) ;
+ while( gam = 0.0 )do begin //perturb matrix
+ gam := 0.00001 * ( 0.001 + nifti_mat33_rownorm(X) ) ;
+ X[0,0] := X[0,0]+gam ;
+ X[1,1] := X[1,1]+gam ;
+ X[2,2] := X[2,2] +gam ;
+ gam := nifti_mat33_determ(X) ;
+ end;
+ while true do begin
+ Y := nifti_mat33_inverse(X) ;
+ if( dif > 0.3 )then begin // far from convergence
+ alp := sqrt( nifti_mat33_rownorm(X) * nifti_mat33_colnorm(X) ) ;
+ bet := sqrt( nifti_mat33_rownorm(Y) * nifti_mat33_colnorm(Y) ) ;
+ gam := sqrt( bet / alp ) ;
+ gmi := 1.0 / gam ;
+ end else begin
+ gam := 1.0;
+ gmi := 1.0 ; //close to convergence
+ end;
+ Z[0,0] := 0.5 * ( gam*X[0,0] + gmi*Y[0,0] ) ;
+ Z[0,1] := 0.5 * ( gam*X[0,1] + gmi*Y[1,0] ) ;
+ Z[0,2] := 0.5 * ( gam*X[0,2] + gmi*Y[2,0] ) ;
+ Z[1,0] := 0.5 * ( gam*X[1,0] + gmi*Y[0,1] ) ;
+ Z[1,1] := 0.5 * ( gam*X[1,1] + gmi*Y[1,1] ) ;
+ Z[1,2] := 0.5 * ( gam*X[1,2] + gmi*Y[2,1] ) ;
+ Z[2,0] := 0.5 * ( gam*X[2,0] + gmi*Y[0,2] ) ;
+ Z[2,1] := 0.5 * ( gam*X[2,1] + gmi*Y[1,2] ) ;
+ Z[2,2] := 0.5 * ( gam*X[2,2] + gmi*Y[2,2] ) ;
+ dif := abs(Z[0,0]-X[0,0])+abs(Z[0,1]-X[0,1])+abs(Z[0,2]-X[0,2])
+ +abs(Z[1,0]-X[1,0])+abs(Z[1,1]-X[1,1])+abs(Z[1,2]-X[1,2])
+ +abs(Z[2,0]-X[2,0])+abs(Z[2,1]-X[2,1])+abs(Z[2,2]-X[2,2]);
+ k := k+1 ;
+ if( k > 100) or (dif < 3.e-6 ) then begin
+ result := Z;
+ break ; //convergence or exhaustion
+ end;
+ X := Z ;
+ end;
+ result := Z ;
+end;
+
+procedure nifti_mat44_to_quatern( lR :mat44;
+ var qb, qc, qd,
+ qx, qy, qz,
+ dx, dy, dz, qfac : single);
+var
+ r11,r12,r13 , r21,r22,r23 , r31,r32,r33, xd,yd,zd , a,b,c,d : double;
+ P,Q: mat33; //3x3
+begin
+ // offset outputs are read write out of input matrix
+ qx := lR[0,3];
+ qy := lR[1,3];
+ qz := lR[2,3];
+ //load 3x3 matrix into local variables
+ fromMatrix(lR,r11,r12,r13,r21,r22,r23,r31,r32,r33);
+ //compute lengths of each column; these determine grid spacings
+ xd := sqrt( r11*r11 + r21*r21 + r31*r31 ) ;
+ yd := sqrt( r12*r12 + r22*r22 + r32*r32 ) ;
+ zd := sqrt( r13*r13 + r23*r23 + r33*r33 ) ;
+ //if a column length is zero, patch the trouble
+ if( xd = 0.0 )then begin r11 := 1.0 ; r21 := 0; r31 := 0.0 ; xd := 1.0 ; end;
+ if( yd = 0.0 )then begin r22 := 1.0 ; r12 := 0; r32 := 0.0 ; yd := 1.0 ; end;
+ if( zd = 0.0 )then begin r33 := 1.0 ; r13 := 0; r23 := 0.0 ; zd := 1.0 ; end;
+ //assign the output lengths
+ dx := xd;
+ dy := yd;
+ dz := zd;
+ //normalize the columns
+ r11 := r11/xd ; r21 := r21/xd ; r31 := r31/xd ;
+ r12 := r12/yd ; r22 := r22/yd ; r32 := r32/yd ;
+ r13 := r13/zd ; r23 := r23/zd ; r33 := r33/zd ;
+ { At this point, the matrix has normal columns, but we have to allow
+ for the fact that the hideous user may not have given us a matrix
+ with orthogonal columns. So, now find the orthogonal matrix closest
+ to the current matrix.
+ One reason for using the polar decomposition to get this
+ orthogonal matrix, rather than just directly orthogonalizing
+ the columns, is so that inputting the inverse matrix to R
+ will result in the inverse orthogonal matrix at this point.
+ If we just orthogonalized the columns, this wouldn't necessarily hold.}
+ Q := Matrix2D (r11,r12,r13, // 2D "graphics" matrix
+ r21,r22,r23,
+ r31,r32,r33);
+ P := nifti_mat33_polar(Q) ; //P is orthog matrix closest to Q
+ FromMatrix33(P,r11,r12,r13,r21,r22,r23,r31,r32,r33);
+{ [ r11 r12 r13 ]
+ at this point, the matrix [ r21 r22 r23 ] is orthogonal
+ [ r31 r32 r33 ]
+ compute the determinant to determine if it is proper}
+
+ zd := r11*r22*r33-r11*r32*r23-r21*r12*r33
+ +r21*r32*r13+r31*r12*r23-r31*r22*r13 ; //should be -1 or 1
+
+ if( zd > 0 )then begin // proper
+ qfac := 1.0 ;
+ end else begin //improper ==> flip 3rd column
+ qfac := -1.0 ;
+ r13 := -r13 ; r23 := -r23 ; r33 := -r33 ;
+ end;
+ // now, compute quaternion parameters
+ a := r11 + r22 + r33 + 1.0;
+ if( a > 0.5 ) then begin //simplest case
+ a := 0.5 * sqrt(a) ;
+ b := 0.25 * (r32-r23) / a ;
+ c := 0.25 * (r13-r31) / a ;
+ d := 0.25 * (r21-r12) / a ;
+ end else begin //trickier case
+ xd := 1.0 + r11 - (r22+r33) ;// 4*b*b
+ yd := 1.0 + r22 - (r11+r33) ;// 4*c*c
+ zd := 1.0 + r33 - (r11+r22) ;// 4*d*d
+ if( xd > 1.0 ) then begin
+ b := 0.5 * sqrt(xd) ;
+ c := 0.25* (r12+r21) / b ;
+ d := 0.25* (r13+r31) / b ;
+ a := 0.25* (r32-r23) / b ;
+ end else if( yd > 1.0 ) then begin
+ c := 0.5 * sqrt(yd) ;
+ b := 0.25* (r12+r21) / c ;
+ d := 0.25* (r23+r32) / c ;
+ a := 0.25* (r13-r31) / c ;
+ end else begin
+ d := 0.5 * sqrt(zd) ;
+ b := 0.25* (r13+r31) / d ;
+ c := 0.25* (r23+r32) / d ;
+ a := 0.25* (r21-r12) / d ;
+ end;
+ if( a < 0.0 )then begin b:=-b ; c:=-c ; d:=-d; {a:=-a; this is not used} end;
+ end;
+ qb := b ;
+ qc := c ;
+ qd := d ;
+end;
+
+
+procedure NII_SetIdentityMatrix (var lHdr: TNIFTIHdr); //create neutral rotation matrix
+var lInc: integer;
+begin
+ with lHdr do begin
+ for lInc := 0 to 3 do
+ srow_x[lInc] := 0;
+ for lInc := 0 to 3 do
+ srow_y[lInc] := 0;
+ for lInc := 0 to 3 do
+ srow_z[lInc] := 0;
+ for lInc := 1 to 16 do
+ intent_name[lInc] := chr(0);
+ //next: create identity matrix: if code is switched on there will not be a problem
+ srow_x[0] := 1;
+ srow_y[1] := 1;
+ srow_z[2] := 1;
+ end;
+end; //proc NIFTIhdr_IdentityMatrix
+
+procedure NII_Clear (var lHdr: TNIFTIHdr);
+var
+ lInc: integer;
+begin
+ with lHdr do begin
+ HdrSz := sizeof(TNIFTIhdr);
+ for lInc := 1 to 10 do
+ Data_Type[lInc] := chr(0);
+ for lInc := 1 to 18 do
+ db_name[lInc] := chr(0);
+ extents:=0;
+ session_error:= 0;
+ regular:='r'{chr(0)};
+ dim_info:=(0);
+ dim[0] := 4;
+ for lInc := 1 to 7 do
+ dim[lInc] := 0;
+ intent_p1 := 0;
+ intent_p2 := 0;
+ intent_p3 := 0;
+ intent_code:=0;
+ datatype:=0 ;
+ bitpix:=0;
+ slice_start:=0;
+ for lInc := 1 to 7 do
+ pixdim[linc]:= 1.0;
+ vox_offset:= 0.0;
+ scl_slope := 1.0;
+ scl_inter:= 0.0;
+ slice_end:= 0;
+ slice_code := 0;
+ xyzt_units := 10;
+ cal_max:= 0.0;
+ cal_min:= 0.0;
+ slice_duration:=0;
+ toffset:= 0;
+ glmax:= 0;
+ glmin:= 0;
+ for lInc := 1 to 80 do
+ descrip[lInc] := chr(0);{80 spaces}
+ for lInc := 1 to 24 do
+ aux_file[lInc] := chr(0);{80 spaces}
+ {below are standard settings which are not 0}
+ bitpix := 16;//vc16; {8bits per pixel, e.g. unsigned char 136}
+ DataType := 4;//vc4;{2=unsigned char, 4=16bit int 136}
+ Dim[0] := 3;
+ Dim[1] := 256;
+ Dim[2] := 256;
+ Dim[3] := 128;
+ Dim[4] := 1; {n vols}
+ Dim[5] := 1;
+ Dim[6] := 1;
+ Dim[7] := 1;
+ glMin := 0;
+ glMax := 255;
+ qform_code := kNIFTI_XFORM_UNKNOWN;
+ sform_code:= kNIFTI_XFORM_UNKNOWN;
+ quatern_b := 0;
+ quatern_c := 0;
+ quatern_d := 0;
+ qoffset_x := 0;
+ qoffset_y := 0;
+ qoffset_z := 0;
+ NII_SetIdentityMatrix(lHdr);
+ magic := kNIFTI_MAGIC_SEPARATE_HDR;
+ end; //with the NIfTI header...
+end;
+
+
+procedure ZERO_MAT44(var m: mat44); //note sets m[3,3] to one
+var
+ i,j: integer;
+begin
+ for i := 0 to 3 do
+ for j := 0 to 3 do
+ m[i,j] := 0.0;
+ m[3,3] := 1;
+end;
+
+procedure LOAD_MAT33(var m: mat33; m00,m01,m02, m10,m11,m12, m20,m21,m22: single);
+begin
+ m[0,0] := m00;
+ m[0,1] := m01;
+ m[0,2] := m02;
+ m[1,0] := m10;
+ m[1,1] := m11;
+ m[1,2] := m12;
+ m[2,0] := m20;
+ m[2,1] := m21;
+ m[2,2] := m22;
+end;
+
+function nifti_mat33_mul( A,B: mat33): mat33;
+var
+ i,j: integer;
+begin
+ for i:=0 to 3 do
+ for j:=0 to 3 do
+ result[i,j] := A[i,0] * B[0,j]
+ + A[i,1] * B[1,j]
+ + A[i,2] * B[2,j] ;
+end;
+
+
+procedure LOAD_MAT44(var m: mat44; m00,m01,m02,m03, m10,m11,m12,m13, m20,m21,m22,m23: single);
+begin
+ m[0,0] := m00;
+ m[0,1] := m01;
+ m[0,2] := m02;
+ m[0,3] := m03;
+ m[1,0] := m10;
+ m[1,1] := m11;
+ m[1,2] := m12;
+ m[1,3] := m13;
+ m[2,0] := m20;
+ m[2,1] := m21;
+ m[2,2] := m22;
+ m[2,3] := m23;
+ m[3,0] := 0.0;
+ m[3,1] := 0.0;
+ m[3,2] := 0.0;
+ m[3,3] := 1.0;
+end;
+
+function validMatrix(var m: mat44): boolean;
+var
+ i: integer;
+begin
+ result := false;
+ for i := 0 to 2 do begin
+ if (m[0,i] = 0.0) and (m[1,i] = 0.0) and (m[2,i] = 0.0) then exit;
+ if (m[i,0] = 0.0) and (m[i,1] = 0.0) and (m[i,2] = 0.0) then exit;
+ end;
+ result := true;
+end;
+
+procedure convertForeignToNifti(var nhdr: TNIFTIhdr);
+var
+ i,nonSpatialMult: integer;
+ qto_xyz: mat44;
+ //dumqx, dumqy, dumqz,
+ dumdx, dumdy, dumdz: single;
+begin
+ nhdr.HdrSz := 348; //used to signify header does not need to be byte-swapped
+ nhdr.magic:=kNIFTI_MAGIC_EMBEDDED_HDR;
+ if (nhdr.dim[3] = 0) then nhdr.dim[3] := 1; //for 2D images the 3rd dim is not specified and set to zero
+ nhdr.dim[0] := 3; //for 2D images the 3rd dim is not specified and set to zero
+ nonSpatialMult := 1;
+ for i := 4 to 7 do
+ if nhdr.dim[i] > 0 then
+ nonSpatialMult := nonSpatialMult * nhdr.dim[i];
+ if (nonSpatialMult > 1) then begin
+ nhdr.dim[0] := 4;
+ nhdr.dim[4] := nonSpatialMult;
+ for i := 5 to 7 do
+ nhdr.dim[i] := 0;
+ end;
+ nhdr.bitpix := 8;
+ if (nhdr.datatype = 4) or (nhdr.datatype = 512) then nhdr.bitpix := 16;
+ if (nhdr.datatype = 8) or (nhdr.datatype = 16) or (nhdr.datatype = 768) then nhdr.bitpix := 32;
+ if (nhdr.datatype = 32) or (nhdr.datatype = 64) or (nhdr.datatype = 1024) or (nhdr.datatype = 1280) then nhdr.bitpix := 64;
+ LOAD_MAT44(qto_xyz, nhdr.srow_x[0], nhdr.srow_x[1], nhdr.srow_x[2], nhdr.srow_x[3],
+ nhdr.srow_y[0], nhdr.srow_y[1], nhdr.srow_y[2], nhdr.srow_y[3],
+ nhdr.srow_z[0], nhdr.srow_z[1], nhdr.srow_z[2], nhdr.srow_z[3]);
+ if not validMatrix(qto_xyz) then begin
+ nhdr.sform_code := 0;
+ nhdr.qform_code := 0;
+ for i := 0 to 3 do begin
+ nhdr.srow_x[i] := 0;
+ nhdr.srow_y[i] := 0;
+ nhdr.srow_z[i] := 0;
+ end;
+ nhdr.srow_x[0] := 1;
+ nhdr.srow_y[1] := 1;
+ nhdr.srow_z[2] := 1;
+ exit;
+ end;
+ nhdr.sform_code := 1;
+ nifti_mat44_to_quatern( qto_xyz , nhdr.quatern_b, nhdr.quatern_c, nhdr.quatern_d,nhdr.qoffset_x,nhdr.qoffset_y,nhdr.qoffset_z, dumdx, dumdy, dumdz,nhdr.pixdim[0]) ;
+ nhdr.qform_code := kNIFTI_XFORM_SCANNER_ANAT;
+end;
+
+procedure NSLog( str: string);
+begin
+ showmsg(str);
+end;
+
+function readMGHHeader (var fname: string; var nhdr: TNIFTIhdr; var gzBytes: int64; var swapEndian: boolean): boolean;
+Type
+ Tmgh = packed record //Next: analyze Format Header structure
+ version, width,height,depth,nframes,mtype,dof : longint;
+ goodRASFlag: smallint;
+ spacingX,spacingY,spacingZ,xr,xa,xs,yr,ya,ys,zr,za,zs,cr,ca,cs: single;
+ end;
+var
+ mgh: Tmgh;
+ lBuff: Bytep;
+ lExt: string;
+ lHdrFile: file;
+ PxyzOffset, Pcrs: vect4;
+ i,j: integer;
+ base: single;
+ m: mat44;
+begin
+ result := false;
+ lExt := UpCaseExt(fname);
+ if (lExt = '.MGZ') then begin
+ lBuff := @mgh;
+ UnGZip(fname,lBuff,0,sizeof(Tmgh)); //1388
+ gzBytes := K_gzBytes_headerAndImageCompressed;
+ end else begin //if MGZ, else assume uncompressed MGH
+ gzBytes := 0;
+ {$I-}
+ AssignFile(lHdrFile, fname);
+ FileMode := 0; //Set file access to read only
+ Reset(lHdrFile, 1);
+ {$I+}
+ if ioresult <> 0 then begin
+ NSLog('Error in reading NIFTI header.'+inttostr(IOResult));
+ FileMode := 2;
+ exit;
+ end;
+ BlockRead(lHdrFile, mgh, sizeof(Tmgh));
+ CloseFile(lHdrFile);
+ end;
+ {$IFDEF ENDIAN_BIG} //data always stored big endian
+ swapEndian := false;
+ {$ELSE}
+ swapEndian := true;
+ swap4(mgh.version);
+ swap4(mgh.width);
+ swap4(mgh.height);
+ swap4(mgh.depth);
+ swap4(mgh.nframes);
+ swap4(mgh.mtype);
+ swap4(mgh.dof);
+ mgh.goodRASFlag := swap(mgh.goodRASFlag);
+ Xswap4r(mgh.spacingX);
+ Xswap4r(mgh.spacingY);
+ Xswap4r(mgh.spacingZ);
+ Xswap4r(mgh.xr);
+ Xswap4r(mgh.xa);
+ Xswap4r(mgh.xs);
+ Xswap4r(mgh.yr);
+ Xswap4r(mgh.ya);
+ Xswap4r(mgh.ys);
+ Xswap4r(mgh.zr);
+ Xswap4r(mgh.za);
+ Xswap4r(mgh.zs);
+ Xswap4r(mgh.cr);
+ Xswap4r(mgh.ca);
+ Xswap4r(mgh.cs);
+ {$ENDIF}
+ if ((mgh.version <> 1) or (mgh.mtype < 0) or (mgh.mtype > 4)) then begin
+ NSLog('Error: first value in a MGH header should be 1 and data type should be in the range 1..4.');
+ exit;
+ end;
+ if (mgh.mtype = 0) then
+ nhdr.datatype := kDT_UINT8
+ else if (mgh.mtype = 4) then
+ nhdr.datatype := kDT_INT16
+ else if (mgh.mtype = 1) then
+ nhdr.datatype := kDT_INT32
+ else if (mgh.mtype = 3) then
+ nhdr.datatype := kDT_FLOAT32;
+ nhdr.dim[1]:=mgh.width;
+ nhdr.dim[2]:=mgh.height;
+ nhdr.dim[3]:=mgh.depth;
+ nhdr.dim[4]:=mgh.nframes;
+ nhdr.pixdim[1]:=mgh.spacingX;
+ nhdr.pixdim[2]:=mgh.spacingY;
+ nhdr.pixdim[3]:=mgh.spacingZ;
+ nhdr.vox_offset := 284;
+ nhdr.sform_code := 1;
+ //convert MGH to NIfTI transform see Bruce Fischl mri.c MRIxfmCRS2XYZ https://github.com/neurodebian/freesurfer/blob/master/utils/mri.c
+ LOAD_MAT44(m,mgh.xr*nhdr.pixdim[1],mgh.yr*nhdr.pixdim[2],mgh.zr*nhdr.pixdim[3],0,
+ mgh.xa*nhdr.pixdim[1],mgh.ya*nhdr.pixdim[2],mgh.za*nhdr.pixdim[3],0,
+ mgh.xs*nhdr.pixdim[1],mgh.ys*nhdr.pixdim[2],mgh.zs*nhdr.pixdim[3],0);
+ base := 0.0; //0 or 1: are voxels indexed from 0 or 1?
+ Pcrs[0] := (nhdr.dim[1]/2.0)+base;
+ Pcrs[1] := (nhdr.dim[2]/2.0)+base;
+ Pcrs[2] := (nhdr.dim[3]/2.0)+base;
+ Pcrs[3] := 1;
+ for i:=0 to 3 do begin //multiply Pcrs * m
+ PxyzOffset[i] := 0;
+ for j := 0 to 3 do
+ PxyzOffset[i] := PxyzOffset[i]+ (m[i,j]*Pcrs[j]);
+ end;
+ nhdr.srow_x[0]:=m[0,0]; nhdr.srow_x[1]:=m[0,1]; nhdr.srow_x[2]:=m[0,2]; nhdr.srow_x[3]:=mgh.cr - PxyzOffset[0];
+ nhdr.srow_y[0]:=m[1,0]; nhdr.srow_y[1]:=m[1,1]; nhdr.srow_y[2]:=m[1,2]; nhdr.srow_y[3]:=mgh.ca - PxyzOffset[1];
+ nhdr.srow_z[0]:=m[2,0]; nhdr.srow_z[1]:=m[2,1]; nhdr.srow_z[2]:=m[2,2]; nhdr.srow_z[3]:=mgh.cs - PxyzOffset[2];
+ convertForeignToNifti(nhdr);
+ result := true;
+end;
+
+procedure splitStr(delimiter: char; str: string; mArray: TStrings);
+begin
+ mArray.Clear;
+ mArray.Delimiter := delimiter;
+ mArray.DelimitedText := str;
+end;
+
+procedure splitStrStrict(delimiter: char; S: string; sl: TStrings);
+begin
+ sl.Clear;
+ sl.Delimiter := delimiter;
+ sl.DelimitedText := '"' + StringReplace(S, sl.Delimiter, '"' + sl.Delimiter + '"', [rfReplaceAll]) + '"';
+end;
+
+function cleanStr (S:string): string; // "(12.31)" ->"12.31"
+begin
+ result := StringReplace(S, '(', '', [rfReplaceAll]);
+ result := StringReplace(result, ')', '', [rfReplaceAll]);
+end;
+
+(*function FSize (lFName: String): Int64;
+var SearchRec: TSearchRec;
+begin
+ result := 0;
+ if not fileexistsex(lFName) then exit;
+ FindFirst(lFName, faAnyFile, SearchRec);
+ result := SearchRec.size;
+ FindClose(SearchRec);
+end; *)
+
+(*procedure report_mat(m: mat33);
+begin
+ showmsg('mat = ['+floattostr(m[0,0])+' ' +floattostr(m[0,1]) +' ' +floattostr(m[0,2]) +'; '
+ +floattostr(m[1,0])+' ' +floattostr(m[1,1]) +' ' +floattostr(m[1,2]) +'; '
+ +floattostr(m[2,0])+' ' +floattostr(m[2,1]) +' ' +floattostr(m[2,2]) +'] ');
+end;*)
+
+function readMHAHeader (var fname: string; var nhdr: TNIFTIhdr; var gzBytes: int64; var swapEndian: boolean): boolean;
+//Read VTK "MetaIO" format image
+//http://www.itk.org/Wiki/ITK/MetaIO/Documentation#Reading_a_Brick-of-Bytes_.28an_N-Dimensional_volume_in_a_single_file.29
+//https://www.assembla.com/spaces/plus/wiki/Sequence_metafile_format
+//http://itk-insight-users.2283740.n2.nabble.com/MHA-MHD-File-Format-td7585031.html
+var
+ FP: TextFile;
+ str, tagName, elementNames: string;
+ ch: char;
+ isLocal,compressedData: boolean;
+ matOrient, mat, d, t: mat33;
+ nPosition, nOffset, matElements, matElementsOrient, compressedDataSize, headerSize, nItems, nBytes, i, channels, fileposBytes: longint;
+ offset,position, elementSize: array [0..3] of single;
+ transformMatrix: array [0..11] of single;
+ mArray: TStringList;
+begin
+ result := false;
+ if not FileExistsEX(fname) then exit;
+ {$IFDEF FPC}
+ DefaultFormatSettings.DecimalSeparator := '.' ;
+ // DecimalSeparator := '.';
+ {$ELSE}
+ DecimalSeparator := '.';
+ {$ENDIF}
+ for i := 0 to 3 do begin
+ position[i] := 0;
+ offset[i] := 0;
+ elementSize[i] := 1;
+ end;
+ nPosition := 0;
+ nOffset := 0;
+ gzBytes := 0;
+ fileposBytes := 0;
+ compressedDataSize := 0;
+ swapEndian := false;
+ isLocal := true; //image and header embedded in same file, if false detached image
+ headerSize := 0;
+ matElements := 0;
+ matElementsOrient := 0;
+ compressedData := false;
+ mArray := TStringList.Create;
+ Filemode := fmOpenRead;
+ AssignFile(fp,fname);
+ reset(fp);
+ while not EOF(fp) do begin
+ str := '';
+ while not EOF(fp) do begin
+ read(fp,ch);
+ inc(fileposBytes);
+ if (ch = chr($0D)) or (ch = chr($0A)) then break;
+ str := str+ch;
+ end;
+ if (length(str) < 1) or (str[1]='#') then continue;
+ splitstrStrict('=',str,mArray);
+ if (mArray.count < 2) then continue;
+ tagName := cleanStr(mArray[0]);
+ elementNames := mArray[1];
+ splitstr(',',elementNames,mArray);
+ nItems :=mArray.count;
+ if (nItems < 1) then continue;
+ for i := 0 to (nItems-1) do
+ mArray[i] := cleanStr(mArray[i]); //remove '(' and ')',
+ if AnsiContainsText(tagName, 'ObjectType') and (not AnsiContainsText(mArray.Strings[0], 'Image')) then begin
+ NSLog('Expecting file with tag "ObjectType = Image" instead of "ObjectType = '+mArray.Strings[0]+'"');
+
+ end {else if AnsiContainsText(tagName, 'NDims') then begin
+ nDims := strtoint(mArray[0]);
+ if (nDims > 4) then begin
+ NSLog('Warning: only reading first 4 dimensions');
+ nDims := 4;
+ end;
+ end} else if AnsiContainsText(tagName, 'BinaryDataByteOrderMSB') then begin
+ {$IFDEF ENDIAN_BIG} //data always stored big endian
+ if not AnsiContainsText(mArray[0], 'True') then swapEndian := true;
+ {$ELSE}
+ if AnsiContainsText(mArray[0], 'True') then swapEndian := true;
+ {$ENDIF}
+ end {else if AnsiContainsText(tagName, 'BinaryData') then begin
+ if AnsiContainsText(mArray[0], 'True') then binaryData := true;
+ end else if AnsiContainsText(tagName, 'CompressedDataSize') then begin
+ compressedDataSize := strtoint(mArray[0]);
+ end} else if AnsiContainsText(tagName, 'CompressedData') then begin
+ if AnsiContainsText(mArray[0], 'True') then
+ compressedData := true;
+ end else if AnsiContainsText(tagName, 'Orientation') and (not AnsiContainsText(tagName, 'Anatomical') ) then begin
+ if (nItems > 12) then nItems := 12;
+ matElementsOrient := nItems;
+ for i := 0 to (nItems-1) do
+ transformMatrix[i] := strtofloat(mArray[i]);
+
+
+ if (matElementsOrient >= 12) then
+ LOAD_MAT33(matOrient, transformMatrix[0],transformMatrix[1],transformMatrix[2],
+ transformMatrix[4],transformMatrix[5],transformMatrix[6],
+ transformMatrix[8],transformMatrix[9],transformMatrix[10])
+ else if (matElementsOrient >= 9) then
+ LOAD_MAT33(matOrient, transformMatrix[0],transformMatrix[1],transformMatrix[2],
+ transformMatrix[3],transformMatrix[4],transformMatrix[5],
+ transformMatrix[6],transformMatrix[7],transformMatrix[8]);
+
+ end else if AnsiContainsText(tagName, 'TransformMatrix') then begin
+ if (nItems > 12) then nItems := 12;
+ matElements := nItems;
+ for i := 0 to (nItems-1) do
+ transformMatrix[i] := strtofloat(mArray[i]);
+ if (matElements >= 12) then
+ LOAD_MAT33(mat, transformMatrix[0],transformMatrix[1],transformMatrix[2],
+ transformMatrix[4],transformMatrix[5],transformMatrix[6],
+ transformMatrix[8],transformMatrix[9],transformMatrix[10])
+ else if (matElements >= 9) then
+ LOAD_MAT33(mat, transformMatrix[0],transformMatrix[1],transformMatrix[2],
+ transformMatrix[3],transformMatrix[4],transformMatrix[5],
+ transformMatrix[6],transformMatrix[7],transformMatrix[8]);
+ end else if AnsiContainsText(tagName, 'Position') then begin
+ if (nItems > 3) then nItems := 3;
+ nPosition := nItems;
+ for i := 0 to (nItems-1) do
+ position[i] := strtofloat(mArray[i]);
+ end else if AnsiContainsText(tagName, 'Offset') then begin
+ if (nItems > 3) then nItems := 3;
+ nOffset := nItems;
+ for i := 0 to (nItems-1) do
+ offset[i] := strtofloat(mArray[i]);
+ end else if AnsiContainsText(tagName, 'AnatomicalOrientation') then begin
+ //e.g. RAI
+ end else if AnsiContainsText(tagName, 'ElementSpacing') then begin
+ if (nItems > 4) then nItems := 4;
+ for i := 0 to (nItems-1) do
+ nhdr.pixdim[i+1] := strtofloat(mArray[i]);
+ end else if AnsiContainsText(tagName, 'DimSize') then begin
+ if (nItems > 4) then nItems := 4;
+ for i := 0 to (nItems-1) do
+ nhdr.dim[i+1] := strtoint(mArray[i]);
+ end else if AnsiContainsText(tagName, 'HeaderSize') then begin
+ headerSize := strtoint(mArray[0]);
+ end else if AnsiContainsText(tagName, 'ElementSize') then begin
+ if (nItems > 4) then nItems := 4;
+ for i := 0 to (nItems-1) do
+ elementSize[i] := strtofloat(mArray[i]);
+ end else if AnsiContainsText(tagName, 'ElementNumberOfChannels') then begin
+ channels := strtoint(mArray[0]);
+ if (channels > 1) then NSLog('Unable to read MHA/MHD files with multiple channels ');
+ end else if AnsiContainsText(tagName, 'ElementByteOrderMSB') then begin
+ {$IFDEF ENDIAN_BIG} //data always stored big endian
+ if not AnsiContainsText(mArray[0], 'True') then swapEndian := true;
+ {$ELSE}
+ if AnsiContainsText(mArray[0], 'True') then swapEndian := true;
+ {$ENDIF}
+ end else if AnsiContainsText(tagName, 'ElementType') then begin
+
+ //convert metaImage format to NIfTI http://portal.nersc.gov/svn/visit/tags/2.2.1/vendor_branches/vtk/src/IO/vtkMetaImageWriter.cxx
+ //set NIfTI datatype http://nifti.nimh.nih.gov/pub/dist/src/niftilib/nifti1.h
+ if AnsiContainsText(mArray[0], 'MET_UCHAR') then
+ nhdr.datatype := kDT_UINT8 //
+ else if AnsiContainsText(mArray[0], 'MET_CHAR') then
+ nhdr.dataType := kDT_INT8 //
+ else if AnsiContainsText(mArray[0], 'MET_SHORT') then
+ nhdr.dataType := kDT_INT16 //
+ else if AnsiContainsText(mArray[0], 'MET_USHORT') then
+ nhdr.dataType := kDT_UINT16 //
+ else if AnsiContainsText(mArray[0], 'MET_INT') then
+ nhdr.dataType := kDT_INT32 //DT_INT32
+ else if AnsiContainsText(mArray[0], 'MET_UINT') then
+ nhdr.dataType := kDT_UINT32 //DT_UINT32
+ else if AnsiContainsText(mArray[0], 'MET_ULONG') then
+ nhdr.dataType := kDT_UINT64 //DT_UINT64
+ else if AnsiContainsText(mArray[0], 'MET_LONG') then
+ nhdr.dataType := kDT_INT64 //DT_INT64
+ else if AnsiContainsText(mArray[0], 'MET_FLOAT') then
+ nhdr.dataType := kDT_FLOAT32 //DT_FLOAT32
+ else if AnsiContainsText(mArray[0], 'MET_DOUBLE') then
+ nhdr.dataType := kDT_DOUBLE; //DT_FLOAT64
+ end else if AnsiContainsText(tagName, 'ElementDataFile') then begin
+ if not AnsiContainsText(mArray[0], 'local') then begin
+ str := mArray.Strings[0];
+ if fileexistsex(str) then
+ fname := str
+ else begin
+ fname := ExtractFileDirWithPathDelim(fname)+str;
+ end;
+ isLocal := false;
+ end;
+ break;
+ end;
+ end; //while reading
+ if (headerSize = 0) and (isLocal) then headerSize :=fileposBytes; //!CRAP 2015
+ nhdr.vox_offset := headerSize;
+ CloseFile(FP);
+ Filemode := 2;
+ mArray.free;
+ //convert transform
+ if (matElements >= 9) or (matElementsOrient >= 9) then begin
+ //report_Mat(matOrient);
+ LOAD_MAT33(d, nhdr.pixdim[1],0,0,
+ 0, nhdr.pixdim[2],0,
+ 0,0, nhdr.pixdim[3]);
+ if (matElements >= 9) then
+ t := nifti_mat33_mul( d, mat)
+ else
+ t := nifti_mat33_mul( d, matOrient) ;
+ if nPosition > nOffset then begin
+ offset[0] := position[0];
+ offset[1] := position[1];
+ offset[2] := position[2];
+
+ end;
+ nhdr.srow_x[0] := -t[0,0];
+ nhdr.srow_x[1] := -t[1,0];
+ nhdr.srow_x[2] := -t[2,0];
+ nhdr.srow_x[3] := -offset[0];
+ nhdr.srow_y[0] := -t[0,1];
+ nhdr.srow_y[1] := -t[1,1];
+ nhdr.srow_y[2] := -t[2,1];
+ nhdr.srow_y[3] := -offset[1];
+ nhdr.srow_z[0] := t[0,2];
+ nhdr.srow_z[1] := t[1,2];
+ nhdr.srow_z[2] := t[2,2];
+ nhdr.srow_z[3] := offset[2];
+ end else begin
+ //NSLog('Warning: unable to determine image orientation (unable to decode metaIO "TransformMatrix" tag)')};
+ nhdr.sform_code:=0;
+ nhdr.srow_x[0] := 0;
+ nhdr.srow_x[1] := 0;
+ nhdr.srow_x[2] := 0;
+ end;
+ //end transform
+ convertForeignToNifti(nhdr);
+ if (compressedData) then
+ gzBytes := K_gzBytes_onlyImageCompressed;
+ if (nhdr.vox_offset < 0) then begin
+ nBytes := (nhdr.bitpix div 8);
+ for i := 1 to 7 do begin
+ if nhdr.dim[i] > 0 then
+ nBytes := nBytes * nhdr.dim[i];
+ end;
+ nhdr.vox_offset := FSize(fname) - nBytes;
+ if (nhdr.vox_offset < 0) then nhdr.vox_offset := -1;
+ end;
+ result := true;
+end;//MHA
+
+function readNRRDHeader (var fname: string; var nhdr: TNIFTIhdr; var gzBytes: int64; var swapEndian: boolean): boolean;
+//http://www.sci.utah.edu/~gk/DTI-data/
+//http://teem.sourceforge.net/nrrd/format.html
+label
+ 666;
+var
+ FP: TextFile;
+ ch: char;
+ mArray: TStringList;
+ str,tagName,elementNames: string;
+ i,s,nItems,headerSize,matElements,fileposBytes: integer;
+ mat: mat33;
+ isDetachedFile,isFirstLine: boolean;
+ offset: array[0..3] of single;
+ vSqr: single;
+ transformMatrix: array [0..11] of single;
+begin
+ {$IFDEF FPC}
+ DefaultFormatSettings.DecimalSeparator := '.' ;
+ //DecimalSeparator := '.';
+ {$ELSE}
+ DecimalSeparator := '.';
+ {$ENDIF}
+ result := false;
+ gzBytes :=0;
+ fileposBytes := 0;
+ swapEndian :=false;
+ //nDims := 0;
+ headerSize :=0;
+ isDetachedFile :=false;
+ matElements :=0;
+ mArray := TStringList.Create;
+ Filemode := 0;
+ isFirstLine := true;
+ AssignFile(fp,fname);
+ reset(fp);
+ while (not EOF(fp)) do begin
+ str := '';
+ while not EOF(fp) do begin
+ read(fp,ch);
+ fileposBytes := fileposBytes + 1;
+ if (ch = chr($0D)) or (ch = chr($0A)) then break;
+ str := str+ch;
+ end;
+ if str = '' then break;
+ if (isFirstLine) then begin
+ if (length(str) <4) or (str[1]<>'N') or (str[2]<>'R') or (str[3]<>'R') or (str[4]<>'D') then
+ goto 666;
+ isFirstLine := false;
+ end;
+ //showmessage(str+'->'+inttostr(fileposBytes));
+ if (length(str) < 1) or (str[1]='#') then continue;
+ splitstrStrict(':',str,mArray);
+ if (mArray.count < 2) then continue;
+ tagName := mArray[0];
+ elementNames := mArray[1];
+ splitstr(',',elementNames,mArray);
+ nItems :=mArray.count;
+ if (nItems < 1) then continue;
+ for i := 0 to (nItems-1) do
+ mArray.Strings[i] := cleanStr(mArray.Strings[i]); //remove '(' and ')'
+ (*if AnsiContainsText(tagName, 'dimension') then
+ nDims := strtoint(mArray.Strings[0])
+ else*) if AnsiContainsText(tagName, 'spacings') then begin
+ if (nItems > 6) then nItems :=6;
+ for i:=0 to (nItems-1) do
+ nhdr.pixdim[i+1] :=strtofloat(mArray.Strings[i]);
+ end else if AnsiContainsText(tagName, 'sizes') then begin
+ if (nItems > 6) then nItems :=6;
+ for i:=0 to (nItems-1) do
+ nhdr.dim[i+1] := strtoint(mArray.Strings[i]);
+ end else if AnsiContainsText(tagName, 'space directions') then begin
+ if (nItems > 12) then nItems :=12;
+ matElements :=nItems;
+ for i:=0 to (nItems-1) do
+ transformMatrix[i] :=strtofloat(mArray.Strings[i]);
+ if (matElements >= 12) then
+ LOAD_MAT33(mat, transformMatrix[0],transformMatrix[1],transformMatrix[2],
+ transformMatrix[4],transformMatrix[5],transformMatrix[6],
+ transformMatrix[8],transformMatrix[9],transformMatrix[10])
+ else if (matElements >= 9) then
+ LOAD_MAT33(mat, transformMatrix[0],transformMatrix[1],transformMatrix[2],
+ transformMatrix[3],transformMatrix[4],transformMatrix[5],
+ transformMatrix[6],transformMatrix[7],transformMatrix[8]);
+ end else if AnsiContainsText(tagName, 'type') then begin
+ if AnsiContainsText(mArray.Strings[0], 'uchar') or
+ AnsiContainsText(mArray.Strings[0], 'uint8') or
+ AnsiContainsText(mArray.Strings[0], 'uint8_t') then
+ nhdr.datatype := KDT_UINT8 //DT_UINT8 DT_UNSIGNED_CHAR
+ else if AnsiContainsText(mArray.Strings[0], 'short') or //specific so
+ AnsiContainsText(mArray.Strings[0], 'int16') or
+ AnsiContainsText(mArray.Strings[0], 'int16_t') then
+ nhdr.datatype :=kDT_INT16 //DT_INT16
+ else if AnsiContainsText(mArray.Strings[0], 'float') then
+ nhdr.datatype := kDT_FLOAT32 //DT_FLOAT32
+ else if AnsiContainsText(mArray.Strings[0], 'unsigned')
+ and (nItems > 1) and AnsiContainsText(mArray.Strings[1], 'char') then
+ nhdr.datatype := kDT_UINT8 //DT_UINT8
+ else if AnsiContainsText(mArray.Strings[0], 'unsigned') and
+ (nItems > 1) and AnsiContainsText(mArray.Strings[1], 'int') then
+ nhdr.datatype := kDT_INT32 //
+ else if AnsiContainsText(mArray.Strings[0], 'signed') and
+ (nItems > 1) and AnsiContainsText(mArray.Strings[1], 'char') then
+ nhdr.datatype := kDT_INT8 //do UNSIGNED first, as "isigned" includes string "unsigned"
+ else if AnsiContainsText(mArray.Strings[0], 'signed') and
+ (nItems > 1) and AnsiContainsText(mArray.Strings[1], 'short') then
+ nhdr.datatype := kDT_INT16 //do UNSIGNED first, as "isigned" includes string "unsigned"
+ else if AnsiContainsText(mArray.Strings[0], 'double') then
+ nhdr.datatype := kDT_DOUBLE //DT_DOUBLE
+ else if AnsiContainsText(mArray.Strings[0], 'int') then //do this last and "uint" includes "int"
+ nhdr.datatype := kDT_UINT32
+ else begin
+ NSLog('Unsupported NRRD datatype'+mArray.Strings[0]);
+ end
+ end else if AnsiContainsText(tagName, 'endian') then begin
+ {$IFDEF ENDIAN_BIG} //data always stored big endian
+ if AnsiContainsText(mArray.Strings[0], 'little') then swapEndian :=true;
+ {$ELSE}
+ if AnsiContainsText(mArray.Strings[0], 'big') then swapEndian :=true;
+ {$ENDIF}
+ end else if AnsiContainsText(tagName, 'encoding') then begin
+ if AnsiContainsText(mArray.Strings[0], 'raw') then
+ gzBytes :=0
+ else if AnsiContainsText(mArray.Strings[0], 'gz') or AnsiContainsText(mArray.Strings[0], 'gzip') then
+ gzBytes := K_gzBytes_headerAndImageCompressed//K_gzBytes_headeruncompressed
+ else
+ NSLog('Unknown encoding format '+mArray.Strings[0]);
+ end else if AnsiContainsText(tagName, 'space origin') then begin
+ if (nItems > 3) then nItems :=3;
+ for i:=0 to (nItems-1) do
+ offset[i] := strtofloat(mArray.Strings[i]);
+ end else if AnsiContainsText(tagName, 'data file') then begin
+ str := mArray.Strings[0];
+ if fileexistsex(str) then
+ fname := str
+ else begin
+ fname := ExtractFileDirWithPathDelim(fname)+str;
+ end;
+ isDetachedFile :=true;
+ //break;
+ end; //for ...else tag names
+ end;
+ if ((headerSize = 0) and ( not isDetachedFile)) then begin
+ if gzBytes = K_gzBytes_headerAndImageCompressed then
+ gzBytes := K_gzBytes_onlyImageCompressed; //raw text file followed by GZ image
+ headerSize :=fileposBytes;
+ end;
+ result := true;
+666:
+ CloseFile(FP);
+ Filemode := 2;
+ mArray.free;
+ if not result then exit;
+ nhdr.vox_offset :=headerSize;
+ if (matElements >= 9) then begin
+ nhdr.srow_x[0] :=-mat[0,0];
+ nhdr.srow_x[1] :=-mat[1,0];
+ nhdr.srow_x[2] :=-mat[2,0];
+ nhdr.srow_x[3] :=-offset[0];
+ nhdr.srow_y[0] :=-mat[0,1];
+ nhdr.srow_y[1] :=-mat[1,1];
+ nhdr.srow_y[2] :=-mat[2,1];
+ nhdr.srow_y[3] :=-offset[1];
+ nhdr.srow_z[0] :=mat[0,2];
+ nhdr.srow_z[1] :=mat[1,2];
+ nhdr.srow_z[2] :=mat[2,2];
+ nhdr.srow_z[3] :=offset[2];
+ //next: ITK does not generate a "spacings" tag - get this from the matrix...
+ for s :=0 to 2 do begin
+ vSqr :=0.0;
+ for i :=0 to 2 do
+ vSqr := vSqr+ ( mat[s,i]*mat[s,i]);
+ nhdr.pixdim[s+1] :=sqrt(vSqr);
+ end //for each dimension
+ end else
+ NSLog('Warning: unable to determine image orientation (unable to decode metaIO "TransformMatrix" tag)'+inttostr(matElements));
+ convertForeignToNifti(nhdr);
+end;
+
+
+procedure THD_daxes_to_NIFTI (var nhdr: TNIFTIhdr; xyzDelta, xyzOrigin: vect3; orientSpecific: ivect3);
+//see http://afni.nimh.nih.gov/pub/dist/src/thd_matdaxes.c
+const
+ ORIENT_xyz1 = 'xxyyzzg'; //note Pascal strings indexed from 1, not 0!
+ ORIENT_sign1 = '+--++-'; //note Pascal strings indexed from 1, not 0!
+var
+ axnum: array[0..2] of integer;
+ axcode,axsign: array[0..2] of char;
+ axstart,axstep: array[0..2] of single;
+ ii, nif_x_axnum, nif_y_axnum, nif_z_axnum: integer;
+ qto_xyz: mat44;
+
+begin
+ nif_x_axnum := -1;
+ nif_y_axnum := -1;
+ nif_z_axnum := -1;
+ axnum[0] := nhdr.dim[1];
+ axnum[1] := nhdr.dim[2];
+ axnum[2] := nhdr.dim[3];
+ axcode[0] := ORIENT_xyz1[1+ orientSpecific[0] ] ;
+ axcode[1] := ORIENT_xyz1[1+ orientSpecific[1] ] ;
+ axcode[2] := ORIENT_xyz1[1+ orientSpecific[2] ] ;
+ axsign[0] := ORIENT_sign1[1+ orientSpecific[0] ] ;
+ axsign[1] := ORIENT_sign1[1+ orientSpecific[1] ] ;
+ axsign[2] := ORIENT_sign1[1+ orientSpecific[2] ] ;
+ axstep[0] := xyzDelta[0] ;
+ axstep[1] := xyzDelta[1] ;
+ axstep[2] := xyzDelta[2] ;
+ axstart[0] := xyzOrigin[0] ;
+ axstart[1] := xyzOrigin[1] ;
+ axstart[2] := xyzOrigin[2] ;
+ for ii := 0 to 2 do begin
+ if (axcode[ii] = 'x') then
+ nif_x_axnum := ii
+ else if (axcode[ii] = 'y') then
+ nif_y_axnum := ii
+ else
+ nif_z_axnum := ii ;
+ end;
+ if (nif_x_axnum < 0) or (nif_y_axnum < 0) or (nif_z_axnum < 0) then exit; //not assigned
+ if (nif_x_axnum = nif_y_axnum) or (nif_x_axnum = nif_z_axnum) or (nif_y_axnum = nif_z_axnum) then exit; //not assigned
+ ZERO_MAT44(qto_xyz);
+ //-- set voxel and time deltas and units --
+ nhdr.pixdim[1] := abs ( axstep[0] ) ;
+ nhdr.pixdim[2] := abs ( axstep[1] ) ;
+ nhdr.pixdim[3] := abs ( axstep[2] ) ;
+ qto_xyz[0,nif_x_axnum] := - axstep[nif_x_axnum];
+ qto_xyz[1,nif_y_axnum] := - axstep[nif_y_axnum];
+ qto_xyz[2,nif_z_axnum] := axstep[nif_z_axnum];
+ nhdr.qoffset_x := -axstart[nif_x_axnum] ;
+ nhdr.qoffset_y := -axstart[nif_y_axnum];
+ nhdr.qoffset_z := axstart[nif_z_axnum];
+ qto_xyz[0,3] := nhdr.qoffset_x ;
+ qto_xyz[1,3] := nhdr.qoffset_y ;
+ qto_xyz[2,3] := nhdr.qoffset_z ;
+ //nifti_mat44_to_quatern( qto_xyz , nhdr.quatern_b, nhdr.quatern_c, nhdr.quatern_d,dumqx, dumqy, dumqz, dumdx, dumdy, dumdz,nhdr.pixdim[0]) ;
+ //nhdr.qform_code := kNIFTI_XFORM_SCANNER_ANAT;
+ nhdr.srow_x[0] :=qto_xyz[0,0]; nhdr.srow_x[1] :=qto_xyz[0,1]; nhdr.srow_x[2] :=qto_xyz[0,2]; nhdr.srow_x[3] :=qto_xyz[0,3];
+ nhdr.srow_y[0] :=qto_xyz[1,0]; nhdr.srow_y[1] :=qto_xyz[1,1]; nhdr.srow_y[2] :=qto_xyz[1,2]; nhdr.srow_y[3] :=qto_xyz[1,3];
+ nhdr.srow_z[0] :=qto_xyz[2,0]; nhdr.srow_z[1] :=qto_xyz[2,1]; nhdr.srow_z[2] :=qto_xyz[2,2]; nhdr.srow_z[3] :=qto_xyz[2,3];
+ nhdr.sform_code := kNIFTI_XFORM_SCANNER_ANAT;
+end;
+
+function readAFNIHeader (var fname: string; var nhdr: TNIFTIhdr; var gzBytes: int64; var swapEndian: boolean): boolean;
+label
+ 666;
+var
+ sl, mArray: TStringList;
+ typeStr,nameStr, valStr: string;
+ lineNum, itemCount,i, vInt, nVols: integer;
+ isAllVolumesSame, isProbMap, isStringAttribute: boolean;
+ valArray : Array of double;
+ orientSpecific: ivect3;
+ xyzOrigin, xyzDelta: vect3;
+begin
+ {$IFDEF FPC}
+ DefaultFormatSettings.DecimalSeparator := '.' ;
+ //DecimalSeparator := '.';
+ {$ELSE}
+ DecimalSeparator := '.';
+ {$ENDIF}
+ nVols := 1;
+ result := false;
+ isProbMap := false;
+ gzBytes := 0;
+ swapEndian := false;
+ sl := TStringList.Create;
+ mArray := TStringList.Create;
+ sl.LoadFromFile(fname);
+ if(sl.count) < 4 then goto 666;
+ lineNum := -1;
+ repeat
+ //read type string
+ lineNum := lineNum + 1;
+ if length(sl[lineNum]) < 1 then continue;
+ splitstr('=',sl[lineNum],mArray);
+ if mArray.Count < 2 then continue;
+ if not AnsiContainsText(cleanStr(mArray[0]), 'type') then continue;
+ typeStr := cleanStr(mArray[1]);
+ isStringAttribute := AnsiContainsText(typeStr, 'string-attribute');
+ //next: read name string
+ lineNum := lineNum + 1;
+ if (lineNum >= (sl.count-1)) then continue;
+ splitstr('=',sl[lineNum],mArray);
+ if mArray.Count < 2 then continue;
+ if not AnsiContainsText(cleanStr(mArray[0]), 'name') then continue;
+ nameStr := cleanStr(mArray[1]);
+ //if AnsiContainsText(nameStr,'BYTEORDER_STRING') and isStringAttribute then showmessage('txt');
+ //next: read count string
+ lineNum := lineNum + 1;
+ if (lineNum >= (sl.count-1)) then continue;
+ splitstr('=',sl[lineNum],mArray);
+ if mArray.Count < 2 then continue;
+ if not AnsiContainsText(cleanStr(mArray[0]), 'count') then continue;
+ itemCount := strtoint(cleanStr(mArray[1]));
+ if itemCount < 1 then exit;
+ //next read values
+ lineNum := lineNum + 1;
+ if (lineNum > (sl.count-1)) then continue;
+ valStr := sl[lineNum];
+ while ((lineNum+1) <= (sl.count-1)) and (length(sl[lineNum+1]) > 0) do begin
+ lineNum := lineNum + 1; //AFNI wraps some arrays across multiple lines
+ valStr := valStr + ' '+ sl[lineNum];
+ end;
+ splitstr(' ',valStr,mArray);
+ if (mArray.Count < itemCount) then itemCount := mArray.Count; // <- only if corrupt
+ if itemCount < 1 then continue; // <- only if corrupt data
+ if isStringAttribute then begin
+ if AnsiContainsText(nameStr,'BYTEORDER_STRING') then begin
+ {$IFDEF ENDIAN_BIG}
+ if AnsiContainsText(mArray[0],'LSB_FIRST') then swapEndian := true;
+ {$ELSE}
+ if AnsiContainsText(mArray[0],'MSB_FIRST') then swapEndian := true;
+ {$ENDIF}
+ end
+ end else begin //if numeric attributes...
+ setlength(valArray,itemCount);
+ for i := 0 to (itemCount-1) do
+ valArray[i] := strtofloat(cleanStr(mArray[i]) );
+ //next - harvest data from important names
+ if AnsiContainsText(nameStr,'BRICK_TYPES') then begin
+ vInt := round(valArray[0]);
+ if (vInt = 0) then begin
+ nhdr.datatype := kDT_UINT8;
+ end else if (vInt = 1) then begin
+ nhdr.datatype := kDT_INT16; //16 bit signed int
+ end else if (vInt = 3) then begin
+ nhdr.datatype := kDT_FLOAT32;//32-bit float
+ end else begin
+ NSLog('Unsupported BRICK_TYPES '+inttostr(vInt));
+ goto 666;
+ end;
+ if (itemCount > 1) then begin //check that all volumes are of the same datatype
+ nVols := itemCount;
+ isAllVolumesSame := true;
+ for i := 1 to (itemCount-1) do
+ if (valArray[0] <> valArray[i]) then isAllVolumesSame := false;
+ if (not isAllVolumesSame) then begin
+ NSLog('Unsupported BRICK_TYPES feature: datatype varies between sub-bricks');
+ goto 666;
+ end;
+ end; //if acount > 0
+ //NSLog('HEAD datatype is '+inttostr(nhdr.datatype) );
+ end else if AnsiContainsText(nameStr,'BRICK_FLOAT_FACS') then begin
+ nhdr.scl_slope := valArray[0];
+ if (itemCount > 1) then begin //check that all volumes are of the same datatype
+ isAllVolumesSame := true;
+ for i := 1 to (itemCount-1) do
+ if (valArray[0] <> valArray[i]) then isAllVolumesSame := false;
+ if (not isAllVolumesSame) then begin
+ NSLog('Unsupported BRICK_FLOAT_FACS feature: intensity scale between sub-bricks');
+ end;
+ end; //if acount > 0
+ end else if AnsiContainsText(nameStr,'DATASET_DIMENSIONS') then begin
+ if itemCount > 3 then itemCount := 3;
+ for i := 0 to (itemCount-1) do
+ nhdr.dim[i+1] := round(valArray[i]);
+ end else if AnsiContainsText(nameStr,'ORIENT_SPECIFIC') then begin
+ if itemCount > 3 then itemCount := 3;
+ for i := 0 to (itemCount-1) do
+ orientSpecific[i] := round(valArray[i]);;
+ //NSLog(@"HEAD orient specific %d %d %d",orientSpecific.v[0],orientSpecific.v[1],orientSpecific.v[2]);
+ end else if AnsiContainsText(nameStr,'ORIGIN') then begin
+ if itemCount > 3 then itemCount := 3;
+ for i := 0 to (itemCount-1) do
+ xyzOrigin[i] := valArray[i];
+ //NSLog(@"HEAD origin %g %g %g",xyzOrigin.v[0],xyzOrigin.v[1],xyzOrigin.v[2]);
+ end else if AnsiContainsText(nameStr,'ATLAS_PROB_MAP') then begin
+ if (round(valArray[0]) = 1) then isProbMap := true;
+ end else if AnsiContainsText(nameStr,'ATLAS_LABEL_TABLE') then begin
+ nhdr.intent_code := kNIFTI_INTENT_LABEL;
+ end else if AnsiContainsText(nameStr,'DELTA') then begin
+ if itemCount > 3 then itemCount := 3;
+ for i := 0 to (itemCount-1) do
+ xyzDelta[i] := valArray[i];
+ //NSLog(@"HEAD delta %g %g %g",xyzDelta.v[0],xyzDelta.v[1],xyzDelta.v[2]);
+ end else if AnsiContainsText(nameStr,'TAXIS_FLOATS') then begin
+ if (itemCount > 1) then nhdr.pixdim[4] := valArray[1]; //second item is TR
+ end;
+ end;// if isStringAttribute else numeric inputs...
+ until (lineNum >= (sl.count-1));
+ result := true;
+666:
+ valArray := nil; //release dynamic array
+ Filemode := 2;
+ sl.free;
+ mArray.free;
+ if not result then exit; //error - code jumped to 666 without setting result to true
+ if (nVols > 1) then nhdr.dim[4] := nVols;
+ if (isProbMap) and (nhdr.intent_code = kNIFTI_INTENT_LABEL) then nhdr.intent_code := kNIFTI_INTENT_NONE;
+ THD_daxes_to_NIFTI(nhdr, xyzDelta, xyzOrigin, orientSpecific );
+ nhdr.vox_offset := 0;
+ convertForeignToNifti(nhdr);
+ fname := ChangeFileExtX(fname, '.BRIK');
+ if (not FileExistsEX(fname)) then begin
+ fname := fname+'.gz';
+ gzBytes := K_gzBytes_headerAndImageCompressed;
+ end;
+end;
+
+function readForeignHeader (var lFilename: string; var lHdr: TNIFTIhdr; var gzBytes: int64; var swapEndian: boolean): boolean;
+var
+ lExt: string;
+begin
+ NII_Clear (lHdr);
+ result := false;
+ lExt := UpCaseExt(lFilename);
+ if (lExt = '.MGH') or (lExt = '.MGZ') then
+ result := readMGHHeader(lFilename, lHdr, gzBytes, swapEndian)
+ else if (lExt = '.MHD') or (lExt = '.MHA') then
+ result := readMHAHeader(lFilename, lHdr, gzBytes, swapEndian)
+ else if (lExt = '.NRRD') or (lExt = '.NHDR') then
+ result := readNRRDHeader(lFilename, lHdr, gzBytes, swapEndian)
+ else if (lExt = '.HEAD') then
+ result := readAFNIHeader(lFilename, lHdr, gzBytes, swapEndian);
+end;
+
+end.
+
\ No newline at end of file
diff --git a/common/nifti_hdr.pas b/common/nifti_hdr.pas
index ecf4ce8..b74e1ea 100755
--- a/common/nifti_hdr.pas
+++ b/common/nifti_hdr.pas
@@ -9,84 +9,10 @@ uses
gzio2,
{$ENDIF}
{$IFNDEF Unix} Windows, {$ENDIF}
-define_types,SysUtils,GraphicsMathLibrary,
-{$IFDEF GUI}dialogs;{$ELSE} dialogsx;{$ENDIF}
+define_types,SysUtils,GraphicsMathLibrary, nifti_types, nifti_foreign,
+ dialogsx;
type
- int64_t= int64;
- TNIFTIhdr2 = packed record //Next: analyze Format Header structure
- HdrSz : longint; //MUST BE 348
- Data_Type: array [1..10] of char; //unused
- db_name: array [1..18] of char; //unused
- extents: longint; //unused
- session_error: smallint; //unused `
- regular: char; ////unused: in Analyze 7.5 this must be 114
- dim_info: byte; //MRI slice order
- dim: array[0..7] of int64_t; //Data array dimensions
- intent_p1, intent_p2, intent_p3: single;
- intent_code: smallint;
- datatype: smallint;
- bitpix: smallint;
- slice_start: smallint;
- pixdim: array[0..7]of single;
- vox_offset: int64_t;
- scl_slope: single;//scaling slope
- scl_inter: single;//scaling intercept
- slice_end: smallint;
- slice_code: byte; //e.g. ascending
- xyzt_units: byte; //e.g. mm and sec
- cal_max,cal_min: single; //unused
- slice_duration: single; //time for one slice
- toffset: single; //time axis to shift
- glmax, glmin: longint; //UNUSED
- descrip: array[1..80] of char;
- aux_file: array[1..24] of char;
- qform_code, sform_code: smallint;
- quatern_b,quatern_c,quatern_d,
- qoffset_x,qoffset_y,qoffset_z: double;
- srow_x, srow_y,srow_z: array[0..3]of double;
- intent_name: array[1..16] of char;
- magic: longint;
- unused_str: array[1..4] of char;
- end; //TNIFTIhdr Header Structure
-
- TNIFTIhdr1 = packed record //Next: analyze Format Header structure
- HdrSz : longint; //MUST BE 348
- Data_Type: array [1..10] of char; //unused
- db_name: array [1..18] of char; //unused
- extents: longint; //unused
- session_error: smallint; //unused `
- regular: char; ////unused: in Analyze 7.5 this must be 114
- dim_info: byte; //MRI slice order
- dim: array[0..7] of smallint; //Data array dimensions
- intent_p1, intent_p2, intent_p3: single;
- intent_code: smallint;
- datatype: smallint;
- bitpix: smallint;
- slice_start: smallint;
- pixdim: array[0..7]of single;
- vox_offset: single;
- scl_slope: single;//scaling slope
- scl_inter: single;//scaling intercept
- slice_end: smallint;
- slice_code: byte; //e.g. ascending
- xyzt_units: byte; //e.g. mm and sec
- cal_max,cal_min: single; //unused
- slice_duration: single; //time for one slice
- toffset: single; //time axis to shift
- glmax, glmin: longint; //UNUSED
- descrip: array[1..80] of char;
- aux_file: array[1..24] of char;
- qform_code, sform_code: smallint;
- quatern_b,quatern_c,quatern_d,
- qoffset_x,qoffset_y,qoffset_z: single;
- srow_x: array[0..3]of single;
- srow_y: array[0..3]of single;
- srow_z: array[0..3]of single;
- intent_name: array[1..16] of char;
- magic: longint;
- end; //TNIFTIhdr Header Structure
- TNIFTIhdr = TNIFTIhdr1; //Next: analyze Format Header structure
TAnalyzeHdrSection = packed record //Next: analyze Format Header structure
Pad: array [1..253] of byte;
@@ -98,106 +24,19 @@ type
AutoBalMinUnscaled,AutoBalMaxUnscaled
,WindowScaledMin,WindowScaledMax
,GlMinUnscaledS,GlMaxUnscaledS,Zero8Bit,Slope8bit: single; //brightness and contrast
- NIfTItransform,DiskDataNativeEndian,UsesCustomPalette,LutFromZero: boolean;
+ NIfTItransform,DiskDataNativeEndian,UsesCustomPalette,UsesCustomPaletteRandomRainbow,UsesLabels,LutFromZero: boolean;
HdrFileName,ImgFileName: string;
+ gzBytesX: int64;
NIFTIVersion,LUTindex,ScrnBufferItems,ImgBufferItems,RenderBufferItems,ImgBufferBPP,RenderDim,Index: longint;
ImgBufferUnaligned: Pointer; //raw address of Image Buffer: address may not be aligned
ScrnBuffer,ImgBuffer,RenderBuffer: Bytep;
LUTinvisible: TRGBQuad;//DWord;
- LUT: array[0..255] of TRGBQuad;
+ LUT: TLUT;//array[0..255] of TRGBQuad;
Mat: TMatrix;
+
end; //TNIFTIhdr Header Structure
- const
-//DataTypes
-kDT_BINARY =1; // binary (1 bit/voxel)
-kDT_UNSIGNED_CHAR =2; // unsigned char (8 bits/voxel)
-kDT_SIGNED_SHORT =4; // signed short (16 bits/voxel)
-kDT_SIGNED_INT =8; // signed int (32 bits/voxel)
-kDT_FLOAT =16; // float (32 bits/voxel)
-kDT_COMPLEX =32; // complex (64 bits/voxel)
-kDT_DOUBLE =64; // double (64 bits/voxel)
-kDT_RGB =128; // RGB triple (24 bits/voxel)
-kDT_INT8 =256; // signed char (8 bits)
-kDT_UINT16 =512; // unsigned short (16 bits)
-kDT_UINT32 =768; // unsigned int (32 bits)
-kDT_INT64 =1024; // long long (64 bits)
-kDT_UINT64 =1280; // unsigned long long (64 bits)
-kDT_FLOAT128 =1536; // long double (128 bits)
-kDT_COMPLEX128 =1792; // double pair (128 bits)
-kDT_COMPLEX256 =2048; // long double pair (256 bits)
-// slice_code values
- kNIFTI_SLICE_SEQ_UNKNOWN = 0;
- kNIFTI_SLICE_SEQ_INC = 1;
- kNIFTI_SLICE_SEQ_DEC = 2;
- kNIFTI_SLICE_ALT_INC = 3;
- kNIFTI_SLICE_ALT_DEC = 4;
-//xyzt_units values: note 3bit space and 3bit time packed into single byte
- kNIFTI_UNITS_UNKNOWN = 0;
- kNIFTI_UNITS_METER = 1;
- kNIFTI_UNITS_MM = 2;
- kNIFTI_UNITS_MICRON = 3;
- kNIFTI_UNITS_SEC = 8;
- kNIFTI_UNITS_MSEC = 16;
- kNIFTI_UNITS_USEC = 24;
- kNIFTI_UNITS_HZ = 32;
- kNIFTI_UNITS_PPM = 40;
- //qform_code, sform_code values
- kNIFTI_XFORM_UNKNOWN = 0;
- kNIFTI_XFORM_SCANNER_ANAT = 1;//Scanner-based anatomical coordinates
- kNIFTI_XFORM_ALIGNED_ANAT = 2; //Coordinates aligned to another file e.g. EPI coregistered to T1
- kNIFTI_XFORM_TALAIRACH = 3; //Talairach-Tournoux Atlas; (0,0,0)=AC, etc.
- kNIFTI_XFORM_MNI_152 = 4; //MNI 152 normalized coordinates
- //Magic values
- kNIFTI_MAGIC_SEPARATE_HDR = $0031696E;//$6E693100;
- kNIFTI_MAGIC_EMBEDDED_HDR = $00312B6E;//$6E2B3100;
- kNIFTI2_MAGIC_SEPARATE_HDR = $0032696E;//$6E693100;
- kNIFTI2_MAGIC_EMBEDDED_HDR = $00322B6E;//$6E2B3100;
-
- kNIFTI_MAGIC_DCM = $0044434D;
- //byte-swapped magic values
- kswapNIFTI_MAGIC_SEPARATE_HDR = $6E693100;
- kswapNIFTI_MAGIC_EMBEDDED_HDR = $6E2B3100;
- kswapNIFTI2_MAGIC_SEPARATE_HDR = $6E693200;
- kswapNIFTI2_MAGIC_EMBEDDED_HDR = $6E2B3200;
- //Statistics Intention
- kNIFTI_INTENT_NONE =0;
-kNIFTI_INTENT_CORREL =2;
-kNIFTI_INTENT_TTEST =3;
-kNIFTI_INTENT_FTEST =4;
-kNIFTI_INTENT_ZSCORE =5;
-kNIFTI_INTENT_CHISQ =6;
-kNIFTI_INTENT_BETA =7;
-kNIFTI_INTENT_BINOM =8;
-kNIFTI_INTENT_GAMMA =9;
-kNIFTI_INTENT_POISSON =10;
-kNIFTI_INTENT_NORMAL =11;
-kNIFTI_INTENT_FTEST_NONC =12;
-kNIFTI_INTENT_CHISQ_NONC =13;
-kNIFTI_INTENT_LOGISTIC =14;
-kNIFTI_INTENT_LAPLACE =15;
-kNIFTI_INTENT_UNIFORM =16;
-kNIFTI_INTENT_TTEST_NONC =17;
-kNIFTI_INTENT_WEIBULL =18;
-kNIFTI_INTENT_CHI =19;
-kNIFTI_INTENT_INVGAUSS =20;
-kNIFTI_INTENT_EXTVAL =21;
-kNIFTI_INTENT_PVAL =22;
-NIFTI_INTENT_LOGPVAL =23;
-NIFTI_INTENT_LOG10PVAL =24;
-kNIFTI_LAST_STATCODE = 24;//kNIFTI_INTENT_PVAL;
-kNIFTI_INTENT_ESTIMATE =1001;
-kNIFTI_FIRST_NONSTATCODE = kNIFTI_INTENT_ESTIMATE;
-kNIFTI_INTENT_LABEL =1002;
-kNIFTI_INTENT_NEURONAME =1003;
-kNIFTI_INTENT_GENMATRIX =1004;
-kNIFTI_INTENT_SYMMATRIX =1005;
-kNIFTI_INTENT_DISPVECT =1006;
-kNIFTI_INTENT_VECTOR =1007;
-kNIFTI_INTENT_POINTSET =1008;
-kNIFTI_INTENT_TRIANGLE =1009;
-kNIFTI_INTENT_QUATERNION =1010;
- function NII1_2_NII2 ( lS: TNIfTIHdr1; var lD: TNIfTIHdr2): boolean;
+
function IsVOIROIExt (var lFName: string):boolean;
function ComputeImageDataBytes (var lHdr: TMRIcroHdr): longint; //size of image data in bytes
function ComputeImageDataBytes8bpp (var lHdr: TMRIcroHdr): longint; //size of image as 32-bit per voxel data in bytes
@@ -225,7 +64,9 @@ kNIFTI_INTENT_QUATERNION =1010;
implementation
-uses dicomhdr;//2/2208
+uses
+{$IFDEF GUI} dialogs,{$ENDIF}
+dicomhdr;//2/2208
function CopyNiftiHdr (var lInHdr,lOutHdr: TNIFTIhdr): boolean;
begin
@@ -254,14 +95,6 @@ begin
end; //with lHdr
end;
-function IsNifTi2Magic (var lHdr: TNIFTIhdr): boolean;
-begin
- if (lHdr.magic =kNIFTI2_MAGIC_SEPARATE_HDR) or (lHdr.Magic = kNIFTI2_MAGIC_EMBEDDED_HDR ) then
- result := true
- else
- result :=false; //analyze
-end;
-
function IsNifTi1Magic (var lHdr: TNIFTIhdr): boolean;
begin
if (lHdr.magic =kNIFTI_MAGIC_SEPARATE_HDR) or (lHdr.Magic = kNIFTI_MAGIC_EMBEDDED_HDR ) then
@@ -272,7 +105,7 @@ end;
function IsNifTiMagic (var lHdr: TNIFTIhdr): boolean;
begin
- if (IsNifTi1Magic(lHdr)) or (IsNifTi2Magic(lHdr)) then
+ if (IsNifTi1Magic(lHdr)) then
result := true
else
result :=false; //analyze
@@ -307,7 +140,7 @@ begin
result := 0;
with lHdr.NIFTIhdr do begin
if Dim[0] < 1 then begin
- ShowMessage('NIFTI format error: datasets must have at least one dimension (dim[0] < 1).');
+ ShowMsg('NIFTI format error: datasets must have at least one dimension (dim[0] < 1).');
exit;
end;
lSzInBits := 32; //bits per voxel
@@ -324,7 +157,7 @@ begin
result := 0;
with lHdr.NIFTIhdr do begin
if Dim[0] < 1 then begin
- ShowMessage('NIFTI format error: datasets must have at least one dimension (dim[0] < 1).');
+ ShowMsg('NIFTI format error: datasets must have at least one dimension (dim[0] < 1).');
exit;
end;
lSzInBits := 8; //bits per voxel
@@ -340,7 +173,7 @@ begin
result := 0;
with lHdr.NIFTIhdr do begin
if Dim[0] < 1 then begin
- ShowMessage('NIFTI format error: datasets must have at least one dimension (dim[0] < 1).');
+ ShowMsg('NIFTI format error: datasets must have at least one dimension (dim[0] < 1).');
exit;
end;
lSzInBits := bitpix; //bits per voxel
@@ -389,7 +222,7 @@ end;
procedure ReportMatrix (lStr: string;lM:TMatrix);
begin
- ShowMessage(lStr+kCR+
+ ShowMsg(lStr+kCR+
RealToStr(lM.matrix[1,1],6)+','+RealToStr(lM.matrix[1,2],6)+','+RealToStr(lM.matrix[1,3],6)+','+RealToStr(lM.matrix[1,4],6)+
kCR+RealToStr(lM.matrix[2,1],6)+','+RealToStr(lM.matrix[2,2],6)+','+RealToStr(lM.matrix[2,3],6)+','+RealToStr(lM.matrix[2,4],6)+
kCR+RealToStr(lM.matrix[3,1],6)+','+RealToStr(lM.matrix[3,2],6)+','+RealToStr(lM.matrix[3,3],6)+','+RealToStr(lM.matrix[3,4],6)+
@@ -470,7 +303,7 @@ begin
SameVec(lVec000,lVec010) or
SameVec(lVec000,lVec001) then begin
lMat := eye3D;
- ShowMessage('Warning: the transformation matrix is corrupt [some dimensions have zero size]');
+ ShowMsg('Warning: the transformation matrix is corrupt [some dimensions have zero size]');
end;
end;
@@ -848,143 +681,15 @@ begin
//fx(lHdr.NIFTIhdr.bitpix, lHdr.NIFTIhdr.datatype);
end;
-function NII1_2_NII2 ( lS: TNIfTIHdr1; var lD: TNIfTIHdr2): boolean;
-var i: integer;
-begin
- with lD do begin
- HdrSz := sizeof(TNIfTIHdr2);//B.HdrSz;
- for i := 1 to 10 do
- Data_Type[i]:= lS.Data_Type[i]; //unused
- for i := 1 to 18 do
- db_name[i]:= lS.db_name[i]; //unused
- extents:= lS.extents;
- session_error:= lS.session_error;
- regular:= lS.regular; ////unused: in Analyze 7.5 this must be 114
- dim_info:= lS.dim_info; //MRI slice order
- for i := 0 to 7 do
- dim[i]:= lS.dim[i];
- intent_p1:= lS.intent_p1;
- intent_p2:= lS.intent_p2;
- intent_p3:= lS.intent_p3;
- intent_code:= lS.intent_code;
- datatype:= lS.datatype;
- bitpix:= lS.bitpix;
- slice_start:= lS.slice_start;
- for i := 0 to 7 do
- pixdim[i] := lS.pixdim[i];
- vox_offset:= round(lS.vox_offset);
- scl_slope:= lS.scl_slope;
- scl_inter:= lS.scl_inter;
- slice_end:= lS.slice_end;
- slice_code:= lS.slice_code;
- xyzt_units:= lS.xyzt_units;
- cal_max:=lS.cal_max;
- cal_min:=lS.cal_min;
- slice_duration:=lS.slice_duration;
- toffset:=lS.toffset;
- glmax:=lS.glmax;
- glmin:=lS.glmin;
- for i := 1 to 80 do
- descrip[i]:= lS.descrip[i];
- for i := 1 to 24 do
- aux_file[i]:= lS.aux_file[i];
- qform_code:=lS.qform_code;
- sform_code:=lS.sform_code;
- quatern_b:=lS.quatern_b;
- quatern_c:=lS.quatern_c;
- quatern_d:=lS.quatern_d;
- qoffset_x:=lS.qoffset_x;
- qoffset_y:=lS.qoffset_y;
- qoffset_z:=lS.qoffset_z;
- for i := 0 to 3 do begin
- srow_x[i]:= lS.srow_x[i];
- srow_y[i]:= lS.srow_y[i];
- srow_z[i]:= lS.srow_z[i];
- end;
- for i := 1 to 16 do
- intent_name[i]:=lS.intent_name[i];
- magic:=lS.magic;
- result := true;
- //unused_str:='NA ';
- end; //with A
-end;
-
-function NII2_2_NII1 ( lS: TNIfTIHdr2; var lD: TNIfTIHdr1): boolean;
-var i: integer;
-begin
- result := true;
- with lD do begin
- HdrSz := 348;//B.HdrSz;
- for i := 1 to 10 do
- Data_Type[i]:= lS.Data_Type[i]; //unused
- for i := 1 to 18 do
- db_name[i]:= lS.db_name[i]; //unused
- extents:= lS.extents;
- session_error:= lS.session_error;
- regular:= lS.regular; ////unused: in Analyze 7.5 this must be 114
- dim_info:= lS.dim_info; //MRI slice order
- for i := 0 to 7 do begin
- if lS.dim[i] > 32767 then begin
- Showmessage('Error, NIfTI2 format image dimensions too large to be stored as a NIfTI1 image.');
- result := false;
- end;
- dim[i]:= lS.dim[i];
- end;
- intent_p1:= lS.intent_p1;
- intent_p2:= lS.intent_p2;
- intent_p3:= lS.intent_p3;
- intent_code:= lS.intent_code;
- datatype:= lS.datatype;
- bitpix:= lS.bitpix;
- slice_start:= lS.slice_start;
- for i := 0 to 7 do
- pixdim[i] := lS.pixdim[i];
- vox_offset:= lS.vox_offset;
- scl_slope:= lS.scl_slope;
- scl_inter:= lS.scl_inter;
- slice_end:= lS.slice_end;
- slice_code:= lS.slice_code;
- xyzt_units:= lS.xyzt_units;
- cal_max:=lS.cal_max;
- cal_min:=lS.cal_min;
- slice_duration:=lS.slice_duration;
- toffset:=lS.toffset;
- glmax:=lS.glmax;
- glmin:=lS.glmin;
- for i := 1 to 80 do
- descrip[i]:= lS.descrip[i];
- for i := 1 to 24 do
- aux_file[i]:= lS.aux_file[i];
- qform_code:=lS.qform_code;
- sform_code:=lS.sform_code;
- quatern_b:=lS.quatern_b;
- quatern_c:=lS.quatern_c;
- quatern_d:=lS.quatern_d;
- qoffset_x:=lS.qoffset_x;
- qoffset_y:=lS.qoffset_y;
- qoffset_z:=lS.qoffset_z;
- for i := 0 to 3 do begin
- srow_x[i]:= lS.srow_x[i];
- srow_y[i]:= lS.srow_y[i];
- srow_z[i]:= lS.srow_z[i];
- end;
- for i := 1 to 16 do
- intent_name[i]:=lS.intent_name[i];
- magic:=lS.magic;
- //unused_str:='NA ';
- end; //with A
-end;
-
function NIFTIhdr_LoadHdr (var lFilename: string; var lHdr: TMRIcroHdr): boolean;
var
lHdrFile: file;
lOri: array [1..3] of single;
lBuff: Bytep;
lAHdr: TAnalyzeHdrSection;
- lHdr2: TNIfTIHdr2;
- lCompress: boolean;
lFileSz : int64;
- lReportedSz, lSwappedReportedSz,lHdrSz2,lHdrSz1: Longint;
+ swapEndian: boolean;
+ lReportedSz, lSwappedReportedSz,lHdrSz: Longint;
lExt: string; //1494
begin
Result := false; //assume error
@@ -992,94 +697,83 @@ begin
lExt := UpCaseExt(lFilename);
if lExt = '.IMG' then
lFilename := changeFileExt(lFilename,'.hdr');
- if (lExt = '.NII.GZ') or (lExt = '.VOI') then
- lCompress := true
- else
- lCompress := false;
- lHdrSz1 := sizeof(TniftiHdr1);
- lHdrSz2 := sizeof(TniftiHdr2);
+ if (lExt = '.BRIK') or (lExt = '.BRIK.GZ') then
+ lFilename := changeFileExtX(lFilename,'.HEAD');
+ lExt := UpCaseExt(lFilename);
+ lHdrSz := sizeof(TniftiHdr);
lFileSz := FSize (lFilename);
if lFileSz = 0 then begin
- ShowMessage('Unable to find NIFTI header named '+lFilename+'. Possible solution: make sure VAL file and images are in the same folder.');
+ ShowMsg('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 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
- lBuff := @lHdr;
- UnGZip(lFileName,lBuff,0,lHdrSz1); //1388
- end else begin //if gzip
- {$I-}
- AssignFile(lHdrFile, lFileName);
- FileMode := 0; { Set file access to read only }
- Reset(lHdrFile, 1);
- {$I+}
- if ioresult <> 0 then begin
- ShowMessage('Error in reading NIFTI header.'+inttostr(IOResult));
- FileMode := 2;
- exit;
- end;
- BlockRead(lHdrFile, lHdr, lHdrSz1);
- CloseFile(lHdrFile);
- end;
- FileMode := 2;
+ swapEndian := false;
+ lHdr.gzBytesX := K_gzBytes_headerAndImageUncompressed;
+ lHdr.ImgFileName:= lFilename ;
+ lHdr.HdrFileName:= lFilename ;
+
+ FileMode := fmOpenRead; //Set file access to read only
+ if (lExt = '.MGH') or (lExt = '.MGZ') or (lExt = '.MHD') or (lExt = '.MHA') or (lExt = '.NRRD') or (lExt = '.NHDR') or (lExt = '.HEAD') then begin
+ result := readForeignHeader( lFilename, lHdr.NIFTIhdr,lHdr.gzBytesX, swapEndian); //we currently ignore result!
+ lHdr.ImgFileName := lFilename;
+ end else begin //native NIfTI
+ if (lExt = '.NII.GZ') or (lExt = '.VOI') or (lExt = '.GZ') then begin//1388
+ lBuff := @lHdr;
+ UnGZip(lFileName,lBuff,0,lHdrSz); //1388
+ lHdr.gzBytesX := K_gzBytes_headerAndImageCompressed;
+ end else begin //if gzip else uncompressed
+ if (lFileSz < lHdrSz) then begin
+ showmsg('Error in reading NIFTI header: NIfTI headers need to be at least '+inttostr(lHdrSz)+ ' bytes: '+lFilename);
+ result := false;
+ end else begin
+ {$I-}
+ AssignFile(lHdrFile, lFileName);
+ FileMode := 0; { Set file access to read only }
+ Reset(lHdrFile, 1);
+ {$I+}
+ if ioresult <> 0 then begin
+ ShowMessage('Error in reading NIFTI header.'+inttostr(IOResult));
+ CloseFile(lHdrFile);
+ FileMode := fmOpenReadWrite;
+ exit;
+ end;
+ BlockRead(lHdrFile, lHdr, lHdrSz);
+ CloseFile(lHdrFile);
+ if (lExt = '.HDR') then
+ lHdr.ImgFileName:= changefileext(lFilename,'.img');
+ end;
+ end;
+
+ end; //native NIFTI
+
+ FileMode := fmOpenReadWrite;
if (IOResult <> 0) then exit;
lReportedSz := lHdr.niftiHdr.HdrSz;
lSwappedReportedSz := lReportedSz;
swap4(lSwappedReportedSz);
lHdr.NIFTIVersion := 1;
- if lReportedSz = lHdrSz1 then begin
+ if lReportedSz = lHdrSz then begin
lHdr.DiskDataNativeEndian := true;
- end else if lSwappedReportedSz = lHdrSz1 then begin
+ end else if lSwappedReportedSz = lHdrSz then begin
lHdr.DiskDataNativeEndian := false;
NIFTIhdr_SwapBytes (lHdr.niftiHdr);
- end else if (lSwappedReportedSz = lHdrSz2) or (lReportedSz = lHdrSz2) then begin
- //reload header...nifti version 2
- FileMode := 0; { Set file access to read only }
- if lCompress then begin//1388
- lBuff := @lHdr2;
- UnGZip(lFileName,lBuff,0,lHdrSz2); //1388
- end else begin //if gzip
- {$I-}
- AssignFile(lHdrFile, lFileName);
- FileMode := 0; { Set file access to read only }
- Reset(lHdrFile, 1);
- {$I+}
- if ioresult <> 0 then begin
- ShowMessage('Error in reading NIFTI header.'+inttostr(IOResult));
- FileMode := 2;
- exit;
- end;
- BlockRead(lHdrFile, lHdr2, lHdrSz2);
- CloseFile(lHdrFile);
- end;
- FileMode := 2;
- lHdr.NIFTIVersion := 2;
- if not NII2_2_NII1(lHdr2,lHdr.NiftiHdr) then begin
- ShowMessage('Warning: compatibility with this version of NIfTI has not been tested.');
- end;
-
end else begin
result := NIFTIhdr_LoadDCM (lFilename,lHdr); //2/2008
if not result then
- ShowMessage('Warning: the header file is not in NIfTi format [the first 4 bytes do not have the value 348]. Assuming big-endian data.');
+ ShowMsg('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.NIFTIhdr.dim[0] > 7) or (lHdr.NIFTIhdr.dim[0] < 1) then begin //only 1..7 dims, so this
- ShowMessage('Illegal NIfTI Format Header: this header does not specify 1..7 dimensions.');
+ ShowMsg('Illegal NIfTI Format Header: this header does not specify 1..7 dimensions.');
exit;
end;
FixDataType(lHdr);
result := true;
//tx('nHdr',lHdr.NIFTIhdr.srow_x[3]);
- lHdr.HdrFileName:= lFilename;
- if ((lHdr.niftiHdr.magic = kNIFTI_MAGIC_EMBEDDED_HDR) and (lFileSz > lHdrSz1)) or ((lHdr.niftiHdr.magic = kNIFTI2_MAGIC_EMBEDDED_HDR) and (lFileSz > lHdrSz2)) or (lExt = '.NII.GZ') or (lExt = '.VOI') or (lExt = '.NII'){1494} then
+ (*lHdr.HdrFileName:= lFilename;
+ if ((lHdr.niftiHdr.magic = kNIFTI_MAGIC_EMBEDDED_HDR) and (lFileSz > lHdrSz)) or (lExt = '.NII.GZ') or (lExt = '.VOI') or (lExt = '.NII'){1494} then
lHdr.ImgFileName:= lFilename
else
- lHdr.ImgFileName:= changefileext(lFilename,'.img');
+ lHdr.ImgFileName:= changefileext(lFilename,'.img'); *)
if IsNifTiMagic(lHdr.niftiHdr) then begin //must match MAGMA in nifti_img
lOri[1] := (lHdr.NIFTIhdr.dim[1]+1) div 2;
lOri[2] := (lHdr.NIFTIhdr.dim[2]+1) div 2;
@@ -1168,7 +862,7 @@ begin
//Warning: some of the NIFTI float values that do exist as integer values in Analyze may have bizarre values like +INF, -INF, NaN
lHdr.NIFTIhdr.toffset := 0;
lHdr.NIFTIhdr.intent_code := kNIFTI_INTENT_NONE;
- lHdr.NIFTIhdr.dim_info := kNIFTI_SLICE_SEQ_UNKNOWN + (kNIFTI_SLICE_SEQ_UNKNOWN shl 2) + (kNIFTI_SLICE_SEQ_UNKNOWN shl 4); //Freq, Phase and Slie all unknown
+ lHdr.NIFTIhdr.dim_info := kNIFTI_SLICE_SEQ_UNKNOWN + (kNIFTI_SLICE_SEQ_UNKNOWN shl 2) + (kNIFTI_SLICE_SEQ_UNKNOWN shl 4); //Freq, Phase and Slice order all unknown
lHdr.NIFTIhdr.xyzt_units := kNIFTI_UNITS_UNKNOWN;
lHdr.NIFTIhdr.slice_duration := 0; //avoid +inf/-inf, NaN
lHdr.NIFTIhdr.intent_p1 := 0; //avoid +inf/-inf, NaN
@@ -1191,6 +885,9 @@ begin
0,0,0,1);
end;
FixCrapMat(lHdr.Mat);
+ if swapEndian then
+ lHdr.DiskDataNativeEndian := false;//foreign data with swapped image data
+
//ReportMatrix(lHdr.mat);
end; //func NIFTIhdr_LoadHdr
@@ -1219,6 +916,8 @@ var lInc: byte;
begin
lHdr.NIFTIVersion := 1;
lHdr.UsesCustomPalette := false;
+ lHdr.UsesCustomPaletteRandomRainbow:= false;
+ lHdr.UsesLabels := false;
lHdr.DiskDataNativeEndian := true;
lHdr.LutFromZero := false;
lHdr.NIfTItransform := true;//assume genuine NIfTI, not Analyze
@@ -1296,85 +995,12 @@ begin
end; //proc NIFTIhdr_ClearHdr
-function NIFTIhdr_SaveHdr2 (var lFilename: string; var lHdr1: TNIFTIHdr; lAllowOverwrite,lSPM2: boolean): boolean; overload;
-var
- lExt: string;
- lF: File;
- lOverwrite: boolean;
- lOutHdr,lHdr: TNIFTIHdr2;
-begin
- result := false;
- if not NII1_2_NII2(lHdr1,lHdr) then
- exit;
- if lHdr.magic = kNIFTI_MAGIC_EMBEDDED_HDR then
- lHdr.magic := kNIFTI2_MAGIC_EMBEDDED_HDR;
- if lHdr.magic = kNIFTI_MAGIC_SEPARATE_HDR then
- lHdr.magic := kNIFTI2_MAGIC_SEPARATE_HDR;
- lOverwrite := false; //will we overwrite existing file?
- result := false; //assume failure
- if lHdr.magic = kNIFTI2_MAGIC_EMBEDDED_HDR then begin
- lExt := UpCaseExt(lFileName);
- if (lExt = '.GZ') or (lExt = '.NII.GZ') then begin
- ShowMessage('Unable to save .nii.gz headers (first ungzip your image if you wish to edit the header)');
- exit;
- end;
- lFilename := changefileext(lFilename,'.nii')
- end else
- lFilename := changefileext(lFilename,'.hdr');
- if ((sizeof(TNIFTIhdr))> DiskFreeEx(lFileName)) then begin
- ShowMessage('There is not enough free space on the destination disk to save the header. '+kCR+
- lFileName+ kCR+' Bytes Required: '+inttostr(sizeof(TNIFTIhdr)) );
- exit;
- end;
- if Fileexists(lFileName) then begin
- if lAllowOverwrite then begin
- case MessageDlg('Do you wish to modify the existing file '+lFilename+'?', mtConfirmation,[mbYes, mbNo], 0) of { produce the message dialog box }
- 6: lOverwrite := true; //6= mrYes, 7=mrNo... not sure what this is for Linux. Hardcoded as we do not include Form values
- end;//case
- end else
- showmessage('Error: the file '+lFileName+' already exists.');
- if not lOverwrite then Exit;
- end;
- if lHdr.magic = kNIFTI2_MAGIC_EMBEDDED_HDR then
- if lHdr.vox_offset < sizeof(TNIFTIHdr) then
- lHdr.vox_offset := sizeof(TNIFTIHdr); //embedded images MUST start after header
- if lHdr.magic = kNIFTI2_MAGIC_SEPARATE_HDR then
- lHdr.vox_offset := 0; //embedded images MUST start after header
-
- if lSPM2 then begin //SPM2 does not recognize NIfTI - origin values will be wrong
- lHdr.magic := 0;
- {lHdr.qform_code := 0;
- lHdr.sform_code:= 0;
- lHdr.quatern_b := 0;
- lHdr.quatern_c := 0;
- lHdr.quatern_d := 0;
- lHdr.qoffset_x := 0;
- lHdr.qoffset_y := 0;
- lHdr.qoffset_z := 0; }
- end;
- result := true;
- move(lHdr, lOutHdr, sizeof(lOutHdr));
- Filemode := 1;
- AssignFile(lF, lFileName); {WIN}
- if lOverwrite then //this allows us to modify just the 348byte header of an existing NII header without touching image data
- Reset(lF,sizeof(TNIFTIhdr))
- else
- Rewrite(lF,sizeof(TNIFTIhdr));
- BlockWrite(lF,lOutHdr, 1 );
- CloseFile(lF);
- Filemode := 2;
-end; //func NIFTIhdr_SaveHdr
-
function NIFTIhdr_SaveHdr (var lFilename: string; var lHdr: TNIFTIHdr; lAllowOverwrite,lSPM2: boolean): boolean; overload;
var lOutHdr: TNIFTIhdr;
lExt: string;
lF: File;
lOverwrite: boolean;
begin
- if (lHdr.magic = kNIFTI2_MAGIC_EMBEDDED_HDR) or (lHdr.Magic = kNIFTI2_MAGIC_SEPARATE_HDR) then begin
- result := NIFTIhdr_SaveHdr2(lFilename,lHdr,lAllowOverwrite,lSPM2);
- exit;
- end;
lOverwrite := false; //will we overwrite existing file?
result := false; //assume failure
if lHdr.magic = kNIFTI_MAGIC_EMBEDDED_HDR then begin
@@ -1393,9 +1019,14 @@ begin
end;
if Fileexists(lFileName) then begin
if lAllowOverwrite then begin
+ {$IFNDEF GUI}
+ ShowMsg('Overwriting '+lFilename);
+ lOverwrite := true;
+ {$ELSE}
case MessageDlg('Do you wish to modify the existing file '+lFilename+'?', mtConfirmation,[mbYes, mbNo], 0) of { produce the message dialog box }
6: lOverwrite := true; //6= mrYes, 7=mrNo... not sure what this is for Linux. Hardcoded as we do not include Form values
end;//case
+ {$ENDIF}
end else
showmessage('Error: the file '+lFileName+' already exists.');
if not lOverwrite then Exit;
@@ -1427,10 +1058,6 @@ var lOutHdr: TNIFTIhdr;
lF: File;
lOverwrite: boolean;
begin
- if (lHdr.NIFTIVersion = 2) or (lHdr.NIFTIhdr.magic = kNIFTI2_MAGIC_EMBEDDED_HDR) or (lHdr.NIFTIhdr.Magic = kNIFTI2_MAGIC_SEPARATE_HDR) then begin
- result := NIFTIhdr_SaveHdr2(lFilename,lHdr.NIFTIhdr,lAllowOverwrite,false); //666 byte swapping
- exit;
- end;
lOverwrite := false; //will we overwrite existing file?
result := false; //assume failure
if lHdr.NIFTIhdr.magic = kNIFTI_MAGIC_EMBEDDED_HDR then begin
@@ -1449,9 +1076,14 @@ begin
end;
if Fileexists(lFileName) then begin
if lAllowOverwrite then begin
+ {$IFNDEF GUI}
+ ShowMsg('Overwriting '+lFilename);
+ lOverwrite := true;
+ {$ELSE}
case MessageDlg('Do you wish to modify the existing file '+lFilename+'?', mtConfirmation,[mbYes, mbNo], 0) of { produce the message dialog box }
6: lOverwrite := true; //6= mrYes, 7=mrNo... not sure what this is for unix. Hardcoded as we do not include Form values
end;//case
+ {$ENDIF}
end else
showmessage('Error: the file '+lFileName+' already exists.');
if not lOverwrite then Exit;
diff --git a/common/nifti_types.pas b/common/nifti_types.pas
new file mode 100755
index 0000000..78ad791
--- /dev/null
+++ b/common/nifti_types.pas
@@ -0,0 +1,166 @@
+unit nifti_types;
+{$IFDEF FPC}
+{$mode objfpc}{$ENDIF}{$H+}
+interface
+
+uses
+ Classes, SysUtils, define_types;
+
+type
+ TNIFTIhdr = packed record //Next: analyze Format Header structure
+ HdrSz : longint; //MUST BE 348
+ Data_Type: array [1..10] of ansichar; //unused
+ db_name: array [1..18] of ansichar; //unused
+ extents: longint; //unused
+ session_error: smallint; //unused
+ regular: ansichar; ////unused: in Analyze 7.5 this must be 114
+ dim_info: byte; //MRI slice order
+ dim: array[0..7] of smallint; //Data array dimensions
+ intent_p1, intent_p2, intent_p3: single;
+ intent_code: smallint;
+ datatype: smallint;
+ bitpix: smallint;
+ slice_start: smallint;
+ pixdim: array[0..7]of single;
+ vox_offset: single;
+ scl_slope: single;//scaling slope
+ scl_inter: single;//scaling intercept
+ slice_end: smallint;
+ slice_code: byte; //e.g. ascending
+ xyzt_units: byte; //e.g. mm and sec
+ cal_max,cal_min: single; //unused
+ slice_duration: single; //time for one slice
+ toffset: single; //time axis to shift
+ glmax, glmin: longint; //UNUSED
+ descrip: array[1..80] of ansichar;
+ aux_file: array[1..24] of ansichar;
+ qform_code, sform_code: smallint;
+ quatern_b,quatern_c,quatern_d,
+ qoffset_x,qoffset_y,qoffset_z: single;
+ srow_x: array[0..3]of single;
+ srow_y: array[0..3]of single;
+ srow_z: array[0..3]of single;
+ intent_name: array[1..16] of ansichar;
+ magic: longint;
+ end; //TNIFTIhdr Header Structure
+ TAnalyzeHdrSection = packed record //Next: analyze Format Header structure
+ Pad: array [1..253] of byte;
+ originator: array [1..5] of smallint; (* 105 + 10 *)
+end;//TAnalyzeHdrSection Structure
+
+
+ const
+
+ K_gzBytes_headerAndImageCompressed = -2;
+ K_gzBytes_onlyImageCompressed= -1;
+ K_gzBytes_headerAndImageUncompressed= 0;
+//DataTypes
+kDT_BINARY =1; // binary (1 bit/voxel)
+kDT_UNSIGNED_CHAR =2; // unsigned char (8 bits/voxel)
+kDT_UINT8 = kDT_UNSIGNED_CHAR;
+kDT_SIGNED_SHORT =4; // signed short (16 bits/voxel)
+kDT_INT16 = kDT_SIGNED_SHORT;
+kDT_SIGNED_INT =8; // signed int (32 bits/voxel)
+kDT_INT32 = kDT_SIGNED_INT;
+kDT_FLOAT =16; // float (32 bits/voxel)
+kDT_FLOAT32 = kDT_FLOAT;
+kDT_COMPLEX =32; // complex (64 bits/voxel)
+kDT_DOUBLE =64; // double (64 bits/voxel)
+kDT_RGB =128; // RGB triple (24 bits/voxel)
+kDT_INT8 =256; // signed char (8 bits)
+kDT_UINT16 =512; // unsigned short (16 bits)
+kDT_UINT32 =768; // unsigned int (32 bits)
+kDT_INT64 =1024; // long long (64 bits)
+kDT_UINT64 =1280; // unsigned long long (64 bits)
+kDT_FLOAT128 =1536; // long double (128 bits)
+kDT_COMPLEX128 =1792; // double pair (128 bits)
+kDT_COMPLEX256 =2048; // long double pair (256 bits)
+// slice_code values
+ kNIFTI_SLICE_SEQ_UNKNOWN = 0;
+ kNIFTI_SLICE_SEQ_INC = 1;
+ kNIFTI_SLICE_SEQ_DEC = 2;
+ kNIFTI_SLICE_ALT_INC = 3;
+ kNIFTI_SLICE_ALT_DEC = 4;
+ kNIFTI_SLICE_ALT_INC2 = 5; // 05 May 2005: RWCox
+ kNIFTI_SLICE_ALT_DEC2 = 6; // 05 May 2005: RWCox
+kSliceOrderStr: array [kNIFTI_SLICE_SEQ_UNKNOWN..kNIFTI_SLICE_ALT_DEC2] of string =
+ ('UNKNOWN','ascending','descending'
+ , 'interleaved ascending (1,3..,2,4...)', 'interleaved ascending (N,N-2...N-1,N-3...)'
+ , 'Siemens-even interleaved ascending (2,4..,1,3...)', 'Siemens-even interleaved ascending (N-1,N-3...N,N-2...)' );
+//xyzt_units values: note 3bit space and 3bit time packed into single byte
+ kNIFTI_UNITS_UNKNOWN = 0;
+ kNIFTI_UNITS_METER = 1;
+ kNIFTI_UNITS_MM = 2;
+ kNIFTI_UNITS_MICRON = 3;
+ kNIFTI_UNITS_SEC = 8;
+ kNIFTI_UNITS_MSEC = 16;
+ kNIFTI_UNITS_USEC = 24;
+ kNIFTI_UNITS_HZ = 32;
+ kNIFTI_UNITS_PPM = 40;
+ //qform_code, sform_code values
+ kNIFTI_XFORM_UNKNOWN = 0;
+ kNIFTI_XFORM_SCANNER_ANAT = 1;//Scanner-based anatomical coordinates
+ kNIFTI_XFORM_ALIGNED_ANAT = 2; //Coordinates aligned to another file e.g. EPI coregistered to T1
+ kNIFTI_XFORM_TALAIRACH = 3; //Talairach-Tournoux Atlas; (0,0,0)=AC, etc.
+ kNIFTI_XFORM_MNI_152 = 4; //MNI 152 normalized coordinates
+{$IFDEF ENDIAN_BIG}
+ //Magic values
+ kswapNIFTI_MAGIC_SEPARATE_HDR = $0031696E;//$6E693100;
+ kswapNIFTI_MAGIC_EMBEDDED_HDR = $00312B6E;//$6E2B3100;
+ kNIFTI_MAGIC_DCM = $0044434D;//DCM
+ //byte-swapped magic values
+ kNIFTI_MAGIC_SEPARATE_HDR = $6E693100;
+ kNIFTI_MAGIC_EMBEDDED_HDR = $6E2B3100;
+{$ELSE}
+ //Magic values
+ kNIFTI_MAGIC_SEPARATE_HDR = $0031696E;//$6E693100;
+ kNIFTI_MAGIC_EMBEDDED_HDR = $00312B6E;//$6E2B3100;
+ kNIFTI_MAGIC_DCM = $0044434D;//DCM
+ //byte-swapped magic values
+ kswapNIFTI_MAGIC_SEPARATE_HDR = $6E693100;
+ kswapNIFTI_MAGIC_EMBEDDED_HDR = $6E2B3100;
+{$ENDIF}
+ //Statistics Intention
+ kNIFTI_INTENT_NONE =0;
+kNIFTI_INTENT_CORREL =2;
+kNIFTI_INTENT_TTEST =3;
+kNIFTI_INTENT_FTEST =4;
+kNIFTI_INTENT_ZSCORE =5;
+kNIFTI_INTENT_CHISQ =6;
+kNIFTI_INTENT_BETA =7;
+kNIFTI_INTENT_BINOM =8;
+kNIFTI_INTENT_GAMMA =9;
+kNIFTI_INTENT_POISSON =10;
+kNIFTI_INTENT_NORMAL =11;
+kNIFTI_INTENT_FTEST_NONC =12;
+kNIFTI_INTENT_CHISQ_NONC =13;
+kNIFTI_INTENT_LOGISTIC =14;
+kNIFTI_INTENT_LAPLACE =15;
+kNIFTI_INTENT_UNIFORM =16;
+kNIFTI_INTENT_TTEST_NONC =17;
+kNIFTI_INTENT_WEIBULL =18;
+kNIFTI_INTENT_CHI =19;
+kNIFTI_INTENT_INVGAUSS =20;
+kNIFTI_INTENT_EXTVAL =21;
+kNIFTI_INTENT_PVAL =22;
+NIFTI_INTENT_LOGPVAL =23;
+NIFTI_INTENT_LOG10PVAL =24;
+kNIFTI_LAST_STATCODE = 24;//kNIFTI_INTENT_PVAL;
+kNIFTI_INTENT_ESTIMATE =1001;
+kNIFTI_FIRST_NONSTATCODE = kNIFTI_INTENT_ESTIMATE;
+kNIFTI_INTENT_LABEL =1002;
+kNIFTI_INTENT_NEURONAME =1003;
+kNIFTI_INTENT_GENMATRIX =1004;
+kNIFTI_INTENT_SYMMATRIX =1005;
+kNIFTI_INTENT_DISPVECT =1006;
+kNIFTI_INTENT_VECTOR =1007;
+kNIFTI_INTENT_POINTSET =1008;
+kNIFTI_INTENT_TRIANGLE =1009;
+kNIFTI_INTENT_QUATERNION =1010;
+
+implementation
+
+
+
+end.
+
diff --git a/crop.pas b/crop.pas
index 40ba4bf..7809103 100755
--- a/crop.pas
+++ b/crop.pas
@@ -6,7 +6,7 @@ function GrowNeck (lFilename: string; lVox: integer): boolean;
implementation
-uses nifti_hdr_view, 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_types;
// 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);
@@ -260,4 +260,4 @@ begin
end;
-end.
\ No newline at end of file
+end.
\ No newline at end of file
diff --git a/dcm2nii/convert.pas b/dcm2nii/convert.pas
index b0fe4ad..0042bf9 100755
--- a/dcm2nii/convert.pas
+++ b/dcm2nii/convert.pas
@@ -10,8 +10,8 @@ gzio2,
{$ELSE}
{$ENDIF}
-filename,define_types,classes,SysUtils,dicom,dicomtypes,
-niftiutil,GraphicsMathLibrary, userdir,csaread,dialogs_msg,
+filename,define_types,classes,SysUtils,dicom,dicomtypes, nifti_types,
+niftiutil,GraphicsMathLibrary, userdir,csaread,dialogs_msg, math,
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
@@ -244,9 +244,9 @@ begin
lDicomData.Orient[2],lDicomData.Orient[5],lv2,
lDicomData.Orient[3],lDicomData.Orient[6],lv3);
if nifti_mat33_determ(Q) < 0 then begin
- result := true;
- //lDicomData.SiemensFlipMosaic := true;
- //reportmatrix('mosaic FLIPPED:'+lFilename,Q);
+
+ dcmMsg('Note: raw slice order R>>L (Siemens convention), dcm2niiprior to 2014 stored these as L>>R, NIfTI convention). Benefit: simpler slice timing correction (ascending is 1..N, descending is N..1)');
+ //result := true;
end;
lMosaicSlices := lnmos;
end;
@@ -720,8 +720,11 @@ begin
//lImgBytes := (lPanelBytes*lDICOMdata.XYZdim[2]);
lPos := 0;
if lFlip then begin
- //Msg('...Flip mosaic');
- for lMos := lnMos downto 1 do begin
+
+dcmmsg('*** WARNING: CSA "ProtocolSliceNumber" SUGGESTS MOSAIC SLICE ORDER REVERSED. SPATIAL AND DTI COORDINATES UNTESTED ****');
+dcmmsg('*** SOLUTION: open sequence on scanner, go to System tab, select Miscellaneous sub-tab, set default image numbering (F>>H, R>>L, A>>P');
+dcmmsg('*** If this is impossible and you wish to use these sequences for DTI please conduct DTI validation described on the dcm2nii web page');
+for lMos := lnMos downto 1 do begin
lStartOffset := ((lMos-1) mod lmosX)*lStripBytes+ ( ((lMos-1) div lmosX)* (lPanelBytes*lMosH));
for lH := 1 to lMosH do begin
for lW := 1 to lStripBytes do begin
@@ -797,8 +800,6 @@ begin
result := result + lFirstDICOM;
end;
-
-
function VV (lLabel: string; var lV: TVector): string;
begin
result := lLabel +' =['+ floattostr(lV.x)+','+floattostr(lV.y)+','+ floattostr(lV.z)+']'';';
@@ -828,7 +829,6 @@ begin
dcmMsg('DTI vector error: Position is not head first supine');
exit;
end;
- //fx(lDTI.v1,lDTI.v2,lDTI.v3);
read_vector := Vector3D(lDICOMData.Orient[1],lDICOMData.Orient[2],lDICOMData.Orient[3]);
phase_vector := Vector3D(lDICOMData.Orient[4],lDICOMData.Orient[5],lDICOMData.Orient[6]);
slice_vector := CrossProduct(read_vector ,phase_vector);
@@ -1078,8 +1078,89 @@ begin
lSliceBytesOut := lnPix * 4;
end;
+procedure SaveTextReport(lOutImgName: string; var lDICOM: dicomdata; var lAHdr: TNIFTIhdr ; lDTIdir: integer);
+var
+ lFile : TextFile;
+ lname,lstr: string;
+begin
+ lname := changefileext(lOutImgName,'.txt');
+ AssignFile(lFile, lname);
+ ReWrite(lFile);
+ // Write a couple of well known words to this file
+ lStr := DICOMstr(lDICOM)+kTab+'DimXYZT:'+kTab+inttostr(lAHdr.dim[1])+kTab+inttostr(lAHdr.dim[2])+kTab+inttostr(lAHdr.dim[3])+kTab+inttostr(lAHdr.dim[4]) ;
+ if lDTIdir > 1 then
+ lStr := lStr+'DTIdir:'+kTab+inttostr(lDTIdir);
+ WriteLn(lFile, lStr);
+ // Close the file
+ CloseFile(lFile);
+end;
+
+function reportSliceTimes(lSliceTimes: TSliceTimes): integer;
+//returns multiband factor
+var
+ i: integer;
+ s: string;
+begin
+ result := 1;
+ if length(lSliceTImes) < 1 then exit;
+ s := ' MosaicRefAcqTimes (Slice Time Correction) ';
+ for i := 0 to (length(lSliceTimes)-1) do
+ s := s+kTab+floattostr(lSliceTImes[i]);
+ dcmmsg(s);
+ for i := 1 to (length(lSliceTimes)-1) do
+ if SameValue(lSliceTImes[i], lSliceTImes[0]) then
+ inc(result);
+ if (result > 1) then
+ dcmmsg('Slice Timing Note: multiband factor x'+inttostr(result));
+end;
+
+
+function padS(ins: string; outl: integer): string;
+var
+ i: integer;
+begin
+ result := '';
+ for i := 1 to outl do begin
+ if i <= length(ins) then
+ result := result + ins[i]
+ else
+ result := result + chr(0);
+ end;
+end;
+
+procedure SetNiiStr(var lH: TNIFTIhdr; lSdb, lSaux: string);
+var
+ i,l: integer;
+ s: string;
+begin
+ s := padS (lSdb,18);
+ for i := 1 to 18 do
+ lH.db_name[i] := s[i];
+ s := padS (lSaux,24);
+ for i := 1 to 24 do
+ lH.aux_file[i] := s[i];
+end;
+
+procedure AddNiiDescrip(var lH: TNIFTIhdr; lS: string);
+var
+ i,l: integer;
+ s: string;
+begin
+ s := padS (lS,80);
+ l := 0;
+ for i := 1 to 80 do
+ if lH.descrip[i] <> chr(0) then l := i;
+ if l >= 80 then exit;
+ for i := 1+l to 80 do
+ lH.descrip[i] := s[i-l];
+end;
+
+
+
function Dicom2NII(var lDICOMra: TDICOMrap; lFirstDICOM, lLastDICOM: integer; var lOutDirOrig: string; var lPrefs: TPrefs; lVols: integer): boolean;
var
+ lCSA:TCSA;
+ lSliceTimes: TSliceTimes;
lPref: TPrefs;
lDTIra: TDTIra;
lDTIdir,lRGB: integer;
@@ -1087,27 +1168,29 @@ var
lAllocSLiceSz,
lStart,lEnd,lmosX,lmosY,lIndex,lSecondDICOM,lSeries,lnSeries,lSliceBytes,
//lBaseBitDepth,
- lMosaicSlices,lSliceBytesOut,lvolOffset,lvolOffsetInit,lvolBytesOut: integer;
+ lMosaicSlices,lSliceBytesOut,lvolOffset,lvolOffsetInit,lvolBytesOut,lSliceOrder: integer;
//lBaseIntenScale,lBaseIntenIntercept,
lDX: single;
//lDynStr,
- lDicomImgName,lOutHdrName,lOutImgName,lOutImgNameGZ,lOutDir,lOutDTIname:string;
+ lDicomImgName,lOutHdrName,lOutImgName,lOutImgNameGZ,lOutDir,lOutDTIname, lStr:string;
lDICOMData:dicomdata;
- lReadOK,lFlip,lIntenScaleVaries,lInterleaved,lFlipMosaic,lVolSave,lByteSwap : boolean;
+ lReadOK,lFlip,lIntenScaleVaries,lInterleaved,lVolSave,lByteSwap : boolean;
lAHdr: TNIFTIhdr;
lTextF: TextFile;
lOutF,lInF: File;
lvBuffer,lsBuffer: bytep;
+ lOldFlipMosaic,lFlippedMosaic: boolean;
begin
+ lDicomImgName := lDICOMra^[lFirstDICOM].Filename;
+ lDicomData := lDICOMra^[lFirstDICOM];
if lPrefs.DebugMode2 then begin
-
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;
result := false;
-
+ lSliceOrder := kNIFTI_SLICE_SEQ_UNKNOWN; //unknown
lPref := lPrefs;
CorrectPrefs(lPref);
lmosX := 1;
@@ -1122,8 +1205,7 @@ begin
//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
@@ -1189,7 +1271,6 @@ begin
exit;
end;
-
if (lVols > 1) and ((lnSeries mod lVols)=0) then
lDICOMdata.SlicesPer3DVol := round(lnSeries/lVols);
lDTIra[1].bval := -1; //not DTI
@@ -1197,7 +1278,7 @@ begin
IsSiemensDTI(lDicomData,lDTIra[1], lDicomImgName, lPrefs);//see if this is a Siemens DTI image - mosaics in B13, non-mosaic in B12
if (lDICOMdata.SiemensMosaicX > 1) or (lDICOMdata.SiemensMosaicY > 1) then begin
- lFlipMosaic := IsNormalMosaic(lDicomData,lMosaicSlices, lDicomImgName);
+ lOldFlipMosaic := IsNormalMosaic(lDicomData,lMosaicSlices, lDicomImgName);
lAHdr.dim[1] := lDicomData.XYZdim[1] div lDICOMdata.SiemensMosaicX;
lAHdr.dim[2] := lDicomData.XYZdim[2] div lDICOMdata.SiemensMosaicY;
lmosX := lDICOMdata.SiemensMosaicX;
@@ -1228,7 +1309,28 @@ begin
end else
lAHdr.dim[3] := lnSeries;
end;
-
+ if (lDICOMdata.ManufacturerID = kSiemensID) and (lDicomData.CSASeriesHeaderInfoPos > 0) and (lDicomData.CSASeriesHeaderInfoSz > 0) then begin
+ lStr := GetCSASeriesHeaderInfo (lDicomImgName, lDicomData.CSASeriesHeaderInfoPos,lDicomData.CSASeriesHeaderInfoSz,lAHdr.dim[3], lSliceOrder);
+ if (lSliceOrder < kNIFTI_SLICE_SEQ_UNKNOWN) or (lSliceOrder > kNIFTI_SLICE_ALT_DEC2) then lSliceOrder := kNIFTI_SLICE_SEQ_UNKNOWN;
+ lAHdr.slice_code := lSliceOrder;
+ lAHdr.dim_info:= 3 shl 4;
+ lAHdr.slice_start:= 0;
+ lAHdr.slice_end := lAHdr.dim[3]-1;
+ if lAHdr.slice_code <> kNIFTI_SLICE_SEQ_UNKNOWN then begin
+ //read final not first image https://github.com/eauerbach/CMRR-MB/issues/29
+ //DecodeCSA2 (lDicomImgName, lDicomData.CSAImageHeaderInfoPos,lDicomData.CSAImageHeaderInfoSz, lCSA, lSliceTimes, lFlippedMosaic);
+ DecodeCSA2 (lDICOMra^[lLastDICOM].Filename, lDICOMra^[lLastDICOM].CSAImageHeaderInfoPos,lDICOMra^[lLastDICOM].CSAImageHeaderInfoSz, lCSA, lSliceTimes, lFlippedMosaic);
+ reportSliceTimes(lSliceTimes);
+ SetNiiStr(lAHdr, lStr, lDICOMra^[lLastDICOM].ImageComments);
+ if (lCSA.PhaseDirectionPositive = 1) then
+ AddNiiDescrip(lAHdr,';phaseDir=+')
+ else if (lCSA.PhaseDirectionPositive = 0) then
+ AddNiiDescrip(lAHdr,';phaseDir=-');
+ lSliceTimes := nil;
+ end;
+ //
+ dcmmsg('For slice timing correction: the slice order is '+kSliceOrderStr[lSliceOrder]);
+ end;
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
@@ -1241,8 +1343,9 @@ begin
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]));
+ //dcmMsg(inttostr(lAHdr.dim[1]));
end;
+ AddNiiDescrip(lAHdr,';dwell='+realtostr( lAHdr.pixdim[6],3));
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');
@@ -1255,6 +1358,7 @@ lFlip := false;
lDICOMdata := lDICOMra^[lLastDICOM];
end;
end;
+
//next compute dx between slices
if (lAHdr.dim[3] > 1) and (lnSeries > 1) and (lDICOMdata.SiemensMosaicX <2) then begin
lDX := abs(DICOMinterslicedistance( lDICOMra^[ Index (1,lFirstDICOM,lInterleaved,lFlip,lAHdr)], lDICOMra^[ Index (2,lFirstDICOM,lInterleaved,lFlip,lAHdr)]) );
@@ -1263,7 +1367,7 @@ lFlip := false;
lAHdr.pixdim[3] := lDX;
end;
end;
- dicom_2_nifti(lDICOMdata,lAHdr,lMosaicSlices,lFlipmosaic);
+ dicom_2_nifti(lDICOMdata,lAHdr,lMosaicSlices,lFlippedMosaic);
//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;
@@ -1442,7 +1546,7 @@ lFlip := false;
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);
+ DeMosaic(lsBuffer,lmosX,lmosY,lMosaicSlices,lFlippedMosaic,lDICOMdata);
lSliceBytesOut :=lAHdr.dim[1]*lAHdr.dim[2]*lAHdr.dim[3]*trunc((lAHdr.bitpix+7)/8);
end else
FlipTB(lDICOMdata,lsBuffer);
@@ -1461,8 +1565,10 @@ lFlip := false;
freemem(lsBuffer);
Filemode := 2; //read and write
lOutImgNameGZ := lOutImgName;
+ if lPref.TxtReport then
+ SaveTextReport(lOutImgName, lDICOMdata, lAHdr,lDTIdir);
if lVolSave then begin{save slice-by-slice}
- lOutImgNameGZ := SaveNIfTICore (lOutImgName, lvBuffer, lVolOffsetInit, lAHdr, lPref,lByteSwap)
+ lOutImgNameGZ := SaveNIfTICore (lOutImgName, lvBuffer, lVolOffsetInit, lAHdr, lPref)
end else //data saved slice by slice
CloseFile(lOutF);
//if (lPref.StartClip > 0) or (lPref.EndClip > 0) then
@@ -1513,7 +1619,7 @@ lFlip := false;
lEnd := lIndex;
if ((lStart >1) or (lEnd < lDTIdir)) and (lStart <= lEnd) then begin
if lVolSave then {save slice-by-slice}
- lOutDTIname := SaveNIfTICoreCrop (lOutImgName, lvBuffer, lVolOffsetInit,lStart-1,lDTIdir-lEnd, lAHdr, lPref,lByteSwap)
+ lOutDTIname := SaveNIfTICoreCrop (lOutImgName, lvBuffer, lVolOffsetInit,lStart-1,lDTIdir-lEnd, lAHdr, lPref)
else
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);
diff --git a/dcm2nii/csaread.pas b/dcm2nii/csaread.pas
index 19ebd42..b8e144e 100755
--- a/dcm2nii/csaread.pas
+++ b/dcm2nii/csaread.pas
@@ -5,17 +5,25 @@ 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,dialogs_msg;
+uses SysUtils, dialogsx, define_types,dialogs_msg, nifti_hdr, nifti_types;
{DEFINE verbose}
+{$H+}
type
TBytearray = array of byte;
+ TSliceTimes = array of single;
TCSA = record
+ PhaseDirectionPositive: integer; //0 or 1, -1 for unknown
Slices,MosaicX,MosaicY: longword;
BandwidthPerPixelPhaseEncode,
Bvalue,DTIv1,DTIv2,DTIv3, SliceNormV1, SliceNormV2,SliceNormV3: double;
+ CustomerSeq: string;
+ //SliceTimes : array of single;
end;
-function DecodeCSA2 (lFilename: string; lCSAImageHeaderInfoPos, lCSAImageHeaderInfoSz: integer; var lCSA: TCSA): boolean;
+
+function DecodeCSA2 (lFilename: string; lCSAImageHeaderInfoPos, lCSAImageHeaderInfoSz: integer; var lCSA: TCSA; var lSliceTimes: TSliceTimes; var lFlippedMosaic: boolean): boolean;
+
+function GetCSASeriesHeaderInfo (lFilename: string; lStart, lLength, lnSlices: integer; var lSliceOrder: integer): string;
function GetCSAImageHeaderInfoDTI (lFilename: string; lStart,lLength: integer; var lBval: integer; var ldti1,ldti2,ldti3: double): boolean;
function GetCSAImageHeaderInfo (lFilename: string; lStart,lLength: integer; var lMosaicSlices,lMosaicX,lMosaicY: integer; var lv1,lv2,lv3: double): boolean;
@@ -26,9 +34,12 @@ implementation
function GetCSAImageHeaderInfoDTI (lFilename: string; lStart,lLength: integer; var lBval: integer; var ldti1,ldti2,ldti3: double): boolean;
var
lCSA: TCSA;
+ lFlippedMosaic: boolean;
+ lSliceTimes: TSliceTimes ;
begin
//lBval := -1;//imposibble - read error
- result := DecodeCSA2 (lFilename, lStart,lLength, lCSA);
+ result := DecodeCSA2 (lFilename, lStart,lLength, lCSA, lSliceTimes, lFlippedMosaic);
+ lSliceTimes := nil; //free
if not result then exit;
lBval := round(lCSA.bvalue);
ldti1 := lCSA.DTIv1;
@@ -42,9 +53,12 @@ end;
function GetCSAImageHeaderInfo (lFilename: string; lStart,lLength: integer; var lMosaicSlices,lMosaicX,lMosaicY: integer; var lv1,lv2,lv3: double): boolean;
var
lCSA: TCSA;
+ lSliceTimes: TSliceTimes;
+ lFlippedMosaic: boolean;
begin
//lMosaicSlices := -1;//imposibble - read error
- result := DecodeCSA2 (lFilename, lStart,lLength, lCSA);
+ result := DecodeCSA2 (lFilename, lStart,lLength, lCSA,lSliceTimes, lFlippedMosaic);
+ lSliceTimes := nil; //free
if not result then exit;
lMosaicSlices := lCSA.Slices;
lMosaicX := lCSA.MosaicX;
@@ -54,11 +68,11 @@ begin
lv3 := lCSA.SliceNormV3; //5/5/2013
end;
-function DecodeCSA2 (lFilename: string; lCSAImageHeaderInfoPos, lCSAImageHeaderInfoSz: integer; var lCSA: TCSA): boolean;
+function DecodeCSA2 (lFilename: string; lCSAImageHeaderInfoPos, lCSAImageHeaderInfoSz: integer; var lCSA: TCSA; var lSliceTimes: TSliceTimes; var lFlippedMosaic: boolean): boolean;
//provided with DICOM file as well as location and size of CSA header, this code returns the Siemens CSA header information
const
- kMaxItem = 4; // if you only need first 3 values, set to 4 so if an item has 6 values the final ones will overwrite 4th item
+ kMaxItem = 1024; // if you only need first 3 values, set to 4 so if an item has 6 values the final ones will overwrite 4th item
type
TCSAtag = record
name : string[64];
@@ -181,8 +195,12 @@ begin
lPos := lPos + ((4-(result.xx2_len) mod 4 )mod 4) ;
end;//nested func freadItem
begin //main function DecodeCSA2
+ lFlippedMosaic := false;
result := false;
+ lSliceTimes := nil; //clear
+ lCSA.CustomerSeq := ''; //clear
lCSA.Bvalue := -1;
+ lCSA.PhaseDirectionPositive := -1;
if (lCSAImageHeaderInfoSz < 1) then
exit;
if FSize(lFilename) <= (lCSAImageHeaderInfoPos+lCSAImageHeaderInfoSz) then
@@ -210,9 +228,7 @@ begin //main function DecodeCSA2
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
@@ -222,36 +238,44 @@ begin //main function DecodeCSA2
lItem[lIbound] := freadItem;
end; //for each item
if (lTag.name = 'NumberOfImagesInMosaic') then
- lCSA.Slices := round(strtofloat(lItem[1].value)) ;
- if (lTag.name = 'AcquisitionMatrixText') then begin //'96p*96 -> X= 96 and Y= 96
+ lCSA.Slices := round(strtofloat(lItem[1].value))
+ else if (lTag.name = 'AcquisitionMatrixText') then begin //'96p*96 -> X= 96 and Y= 96
lCSA.MosaicX := LeftStr2Num(lItem[1].value);
lCSA.MosaicY := RightStr2Num(lItem[1].value);
- end;
- if (lTag.name = 'B_value') and (SafeStr2Num(lItem[1].value)) then
- lCSA.Bvalue := strtofloat(lItem[1].value);
- if (lTag.name = 'DiffusionGradientDirection') and (SafeStr2Num(lItem[1].value)) and (SafeStr2Num(lItem[2].value)) and (SafeStr2Num(lItem[3].value)) then begin
+ end else if (lTag.name = 'B_value') and (SafeStr2Num(lItem[1].value)) then
+ lCSA.Bvalue := strtofloat(lItem[1].value)
+ else if (lTag.name = 'DiffusionGradientDirection') and (SafeStr2Num(lItem[1].value)) and (SafeStr2Num(lItem[2].value)) and (SafeStr2Num(lItem[3].value)) then begin
lCSA.DTIv1 := strtofloat(lItem[1].value);
lCSA.DTIv2 := strtofloat(lItem[2].value);
lCSA.DTIv3 := strtofloat(lItem[3].value);
- end;
- if (lTag.name = 'SliceNormalVector') and (SafeStr2Num(lItem[1].value)) and (SafeStr2Num(lItem[2].value)) and (SafeStr2Num(lItem[3].value)) then begin
+ end else if (lTag.name = 'SliceNormalVector') and (SafeStr2Num(lItem[1].value)) and (SafeStr2Num(lItem[2].value)) and (SafeStr2Num(lItem[3].value)) then begin
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
+ end else 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
+ end else 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 else if (lTag.name = 'MosaicRefAcqTimes') and (lTag.nitems > 1) and (SafeStr2Num(lItem[1].value)) then begin
+ //showmsg(lTag.name+ '-> '+inttostr(lTag.nitems));
+ setlength(lSliceTimes,lTag.nitems);
+ for lI := 1 to lTag.nitems do
+ if SafeStr2Num(lItem[lI].value) then
+ lSliceTimes[lI-1] := strtofloat(lItem[lI].value);
+ end else if (lTag.name = 'ProtocolSliceNumber') and (lTag.nitems > 0) and (SafeStr2Num(lItem[1].value)) then begin
+ if SafeStr2Num(lItem[1].value) and (strtofloat(lItem[1].value) > 0) then lFlippedMosaic := true;
+ end else if (lTag.name = 'PhaseEncodingDirectionPositive') and (lTag.nitems > 0) and (SafeStr2Num(lItem[1].value)) then begin
+ lCSA.PhaseDirectionPositive := round(strtofloat(lItem[1].value));
end;
+
+ // else dcmmsg(lTag.name+ '-> '+inttostr(lTag.nitems));
+
+
(*if (lTag.name = 'EchoLinePosition') and (SafeStr2Num(lItem[1].value)) then begin
lCSA.BandwidthPerPixelPhaseEncode := strtofloat(lItem[1].value);
msg('EchoLinePosition: '+floattostr(lCSA.BandwidthPerPixelPhaseEncode));
@@ -260,6 +284,10 @@ begin //main function DecodeCSA2
lCSA.BandwidthPerPixelPhaseEncode := strtofloat(lItem[1].value);
{$IFDEF verbose} msg(lTag.name+' '+inttostr(lTag.nitems)+' '+floattostr(lCSA.BandwidthPerPixelPhaseEncode)); {$ENDIF}
end;
+ //if true then begin //(lTag.name = 'sSliceArray.ucMode') then begin
+ // showmsg(lTag.name+'xxxxxxxxxx'+lItem[1].value);
+
+ // end; ;
end;//at least one item
end; //for each tag
@@ -268,8 +296,108 @@ begin //main function DecodeCSA2
end else begin
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;
+ //Showmsg('CSA done, final tag '+lTag.name+' CSA started at '+inttostr(lCSAImageHeaderInfoPos)+' CSA length of '+inttostr(lCSAImageHeaderInfoSz)+' formal CSA ended at @ '+inttostr(lPos));
lData := nil;
end;// func DecodeCSA2
+function GetCSASeriesHeaderInfo (lFilename: string; lStart,lLength, lnSlices: integer; var lSliceOrder: integer): string;
+var
+ lData: array of byte;
+ lFile : File;
+function str2str (lStr: string): string;
+var
+ lPos,lOK, lStrLen,lDataLen: integer;
+ lS: string;
+begin
+ result := ''; //is failure
+ lStrLen := length(lStr);
+ lDataLen := lLength-lStrLen-1; //-1 since data must be at least 1 byte
+ lPos := 1;
+ lOK := 0;
+ while lPos < lDataLen do begin
+ lOK := 0;
+ while (chr(lData[lPos+lOK]) = lStr[lOK+1]) do begin
+ inc(lOK);
+ if (lOK = lStrLen) then begin
+ lS := '0';
+ lPos := lPos + lOK + 1;
+ while (lPos <= lLength) and (lData[lPos] <> 10) and (lData[lPos] <> ord('"')) do begin // end of line is 0x0A = 10
+ if (lData[lPos] <> ord('\')) and (lData[lPos] <> ord('/')) then
+ result := result + chr(lData[lPos]);
+ inc(lPos);
+ end; //while not end of line
+ exit;
+ end; //if whole string matches
+ end; //while character matches
+ lPos:= lPos + lOK + 1;
+ end; //while pos in less than data length
+end;
+
+function strValue (lStr: string): integer;
+//returns 4 for "sSliceArray.ucMode = 0x4" (0A ends line)
+var
+ lPos,lOK, lStrLen,lDataLen: integer;
+ lS: string;
+begin
+ result := 0; //is failure
+ lStrLen := length(lStr);
+ lDataLen := lLength-lStrLen-1; //-1 since data must be at least 1 byte
+ lPos := 1;
+ lOK := 0;
+ while lPos < lDataLen do begin
+ lOK := 0;
+ while (chr(lData[lPos+lOK]) = lStr[lOK+1]) do begin
+ inc(lOK);
+ if (lOK = lStrLen) then begin
+ lS := '0';
+ lPos := lPos + lOK + 1;
+ while (lPos <= lLength) and (lData[lPos] <> 10) do begin // end of line is 0x0A = 10
+ if chr(lData[lPos]) in ['0'..'9'] then
+ lS := lS + chr(lData[lPos]);
+ inc(lPos);
+ end; //while not end of line
+ result := strtoint(lS);
+ //https://wiki.cimec.unitn.it/tiki-index.php?page=MRIBOLDfMRI
+ //http://cbs.fas.harvard.edu/node/559#slice_order
+ case result of
+ 1: result := kNIFTI_SLICE_SEQ_INC;
+ 2 : result := kNIFTI_SLICE_SEQ_DEC;
+ 4: begin
+ if odd(lnSlices) then
+ result := kNIFTI_SLICE_ALT_INC
+ else begin
+ dcmMsg(' Warning: Siemens interleaved acquisition with an even number of slices. Assume even slices acquired PRIOR to odd slices. https://wiki.cimec.unitn.it/tiki-index.php?page=MRIBOLDfMRI');
+ result := kNIFTI_SLICE_ALT_INC2;
+ end;
+ end;
+ else begin
+ dcmMsg('Warning: Unknown Siemens slice order '+inttostr(result));
+ result := 0;
+ end;
+ end; //case
+ exit;
+ end; //if whole string matches
+ end; //while character matches
+ lPos:= lPos + lOK + 1;
+ end; //while pos in less than data length
+end;
+
+begin
+ result := '';
+ lSliceOrder := 0;
+ if (lLength < 0) then exit;
+ SetLength(lData,lLength);
+ FileMode := fmOpenRead;
+ AssignFile(lFile, lFilename);
+ Reset(lFile, 1); // Now we define one record as 1 byte
+ Seek(lFile, lStart); // Records start from 0
+ BlockRead(lFile, lData[0], lLength);
+ CloseFile(lFile);
+ lSliceOrder := strValue('sSliceArray.ucMode');
+ result := str2str ('CustomerSeq');
+ //dcmMsg('*********Got it '+inttostr(lSliceOrder));
+ lData := nil;
+end;
+
end.
\ No newline at end of file
diff --git a/dcm2nii/dcm2nii.lpi b/dcm2nii/dcm2nii.lpi
index 60beb96..7434a8f 100755
--- a/dcm2nii/dcm2nii.lpi
+++ b/dcm2nii/dcm2nii.lpi
@@ -25,16 +25,16 @@
<LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
</local>
</RunParams>
- <Units Count="32">
+ <Units Count="36">
<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"/>
+ <TopLine Value="48"/>
+ <CursorPos X="23" Y="65"/>
+ <UsageCount Value="121"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit0>
@@ -43,8 +43,8 @@
<UnitName Value="convert"/>
<EditorIndex Value="6"/>
<WindowIndex Value="0"/>
- <TopLine Value="1286"/>
- <CursorPos X="18" Y="1315"/>
+ <TopLine Value="1469"/>
+ <CursorPos X="55" Y="1482"/>
<UsageCount Value="57"/>
<Loaded Value="True"/>
</Unit1>
@@ -68,7 +68,7 @@
<EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="15" Y="6"/>
+ <CursorPos X="41" Y="2"/>
<UsageCount Value="57"/>
<Loaded Value="True"/>
</Unit4>
@@ -108,17 +108,17 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="120"/>
+ <UsageCount Value="121"/>
</Unit9>
<Unit10>
<Filename Value="dicomtypes.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="dicomtypes"/>
- <EditorIndex Value="7"/>
+ <EditorIndex Value="8"/>
<WindowIndex Value="0"/>
- <TopLine Value="19"/>
- <CursorPos X="74" Y="28"/>
- <UsageCount Value="120"/>
+ <TopLine Value="231"/>
+ <CursorPos X="19" Y="237"/>
+ <UsageCount Value="121"/>
<Loaded Value="True"/>
</Unit10>
<Unit11>
@@ -154,9 +154,12 @@
<Unit15>
<Filename Value="dicomcompat.pas"/>
<UnitName Value="dicomcompat"/>
- <TopLine Value="5888"/>
- <CursorPos X="31" Y="5918"/>
+ <EditorIndex Value="5"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="66" Y="5"/>
<UsageCount Value="11"/>
+ <Loaded Value="True"/>
</Unit15>
<Unit16>
<Filename Value="dialogsx.pas"/>
@@ -191,10 +194,10 @@
<Filename Value="paramstrs.pas"/>
<UnitName Value="paramstrs"/>
<IsVisibleTab Value="True"/>
- <EditorIndex Value="5"/>
+ <EditorIndex Value="9"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="37" Y="14"/>
+ <TopLine Value="300"/>
+ <CursorPos X="71" Y="315"/>
<UsageCount Value="11"/>
<Loaded Value="True"/>
</Unit20>
@@ -224,18 +227,22 @@
<Unit24>
<Filename Value="..\common\define_types.pas"/>
<UnitName Value="define_types"/>
+ <EditorIndex Value="7"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="1"/>
+ <TopLine Value="34"/>
+ <CursorPos X="21" Y="51"/>
<UsageCount Value="10"/>
+ <Loaded Value="True"/>
</Unit24>
<Unit25>
<Filename Value="..\common\gzio2.pas"/>
<UnitName Value="gzio2"/>
+ <EditorIndex Value="4"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="12" Y="1881"/>
+ <TopLine Value="20"/>
+ <CursorPos X="87" Y="33"/>
<UsageCount Value="10"/>
+ <Loaded Value="True"/>
</Unit25>
<Unit26>
<Filename Value="..\common\GraphicsMathLibrary.pas"/>
@@ -248,8 +255,8 @@
<Filename Value="..\common\dialogsx.pas"/>
<UnitName Value="dialogsx"/>
<WindowIndex Value="0"/>
- <TopLine Value="53"/>
- <CursorPos X="18" Y="77"/>
+ <TopLine Value="28"/>
+ <CursorPos X="16" Y="44"/>
<UsageCount Value="10"/>
</Unit27>
<Unit28>
@@ -257,8 +264,8 @@
<UnitName Value="prefs"/>
<EditorIndex Value="3"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="25" Y="8"/>
+ <TopLine Value="5"/>
+ <CursorPos X="49" Y="17"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit28>
@@ -284,96 +291,170 @@
<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>
+ <Unit32>
+ <Filename Value="..\..\..\..\..\..\usr\local\share\fpcsrc\packages\fv\src\dialogs.pas"/>
+ <UnitName Value="Dialogs"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1025"/>
+ <CursorPos X="41" Y="1052"/>
+ <UsageCount Value="10"/>
+ </Unit32>
+ <Unit33>
+ <Filename Value="..\common\dicomhdr.pas"/>
+ <UnitName Value="dicomhdr"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="18"/>
+ <CursorPos X="6" Y="33"/>
+ <UsageCount Value="10"/>
+ </Unit33>
+ <Unit34>
+ <Filename Value="..\common\nifti_hdr.pas"/>
+ <UnitName Value="nifti_hdr"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1459"/>
+ <CursorPos X="41" Y="1473"/>
+ <UsageCount Value="10"/>
+ </Unit34>
+ <Unit35>
+ <Filename Value="..\..\..\..\..\..\usr\local\share\fpcsrc\rtl\objpas\sysutils\finah.inc"/>
+ <EditorIndex Value="10"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="15"/>
+ <CursorPos X="24" Y="25"/>
+ <UsageCount Value="10"/>
+ <Loaded Value="True"/>
+ </Unit35>
</Units>
- <JumpHistory Count="19" HistoryIndex="18">
+ <JumpHistory Count="30" HistoryIndex="29">
<Position1>
- <Filename Value="dcm2nii.lpr"/>
- <Caret Line="3" Column="48" TopLine="1"/>
+ <Filename Value="dicomcompat.pas"/>
+ <Caret Line="309" Column="111" TopLine="307"/>
</Position1>
<Position2>
- <Filename Value="dcm2nii.lpr"/>
- <Caret Line="65" Column="27" TopLine="38"/>
+ <Filename Value="dicom.pas"/>
+ <Caret Line="6" Column="15" TopLine="2"/>
</Position2>
<Position3>
- <Filename Value="dcm2nii.lpr"/>
- <Caret Line="29" Column="21" TopLine="1"/>
+ <Filename Value="dicom.pas"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
</Position3>
<Position4>
- <Filename Value="dcm2nii.lpr"/>
- <Caret Line="29" Column="21" TopLine="11"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1090" Column="21" TopLine="1073"/>
</Position4>
<Position5>
- <Filename Value="dcm2nii.lpr"/>
- <Caret Line="67" Column="16" TopLine="40"/>
+ <Filename Value="dicomtypes.pas"/>
+ <Caret Line="246" Column="54" TopLine="230"/>
</Position5>
<Position6>
- <Filename Value="convert.pas"/>
- <Caret Line="4" Column="85" TopLine="1"/>
+ <Filename Value="dicomtypes.pas"/>
+ <Caret Line="229" Column="6" TopLine="219"/>
</Position6>
<Position7>
<Filename Value="convert.pas"/>
- <Caret Line="1128" Column="35" TopLine="1114"/>
+ <Caret Line="1090" Column="21" TopLine="1073"/>
</Position7>
<Position8>
- <Filename Value="convert.pas"/>
- <Caret Line="1129" Column="33" TopLine="1114"/>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="342" Column="23" TopLine="324"/>
</Position8>
<Position9>
<Filename Value="convert.pas"/>
- <Caret Line="1294" Column="58" TopLine="1273"/>
+ <Caret Line="1094" Column="25" TopLine="1070"/>
</Position9>
<Position10>
<Filename Value="convert.pas"/>
- <Caret Line="1411" Column="83" TopLine="1383"/>
+ <Caret Line="1081" Column="91" TopLine="1066"/>
</Position10>
<Position11>
<Filename Value="convert.pas"/>
- <Caret Line="1440" Column="83" TopLine="1413"/>
+ <Caret Line="1090" Column="143" TopLine="1081"/>
</Position11>
<Position12>
<Filename Value="convert.pas"/>
- <Caret Line="1441" Column="31" TopLine="1413"/>
+ <Caret Line="1094" Column="22" TopLine="1081"/>
</Position12>
<Position13>
- <Filename Value="convert.pas"/>
- <Caret Line="682" Column="6" TopLine="670"/>
+ <Filename Value="..\common\define_types.pas"/>
+ <Caret Line="11" Column="23" TopLine="1"/>
</Position13>
<Position14>
- <Filename Value="convert.pas"/>
- <Caret Line="1185" Column="34" TopLine="1176"/>
+ <Filename Value="dicom.pas"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
</Position14>
<Position15>
- <Filename Value="convert.pas"/>
- <Caret Line="1310" Column="13" TopLine="1282"/>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="75" Column="35" TopLine="75"/>
</Position15>
<Position16>
- <Filename Value="dicom.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="344" Column="17" TopLine="327"/>
</Position16>
<Position17>
- <Filename Value="dicom.pas"/>
- <Caret Line="6" Column="15" TopLine="1"/>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="343" Column="38" TopLine="332"/>
</Position17>
<Position18>
- <Filename Value="gui.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="342" Column="70" TopLine="332"/>
</Position18>
<Position19>
- <Filename Value="paramstrs.pas"/>
- <Caret Line="235" Column="6" TopLine="219"/>
+ <Filename Value="..\common\define_types.pas"/>
+ <Caret Line="3" Column="94" TopLine="1"/>
</Position19>
+ <Position20>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="342" Column="40" TopLine="335"/>
+ </Position20>
+ <Position21>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="344" Column="43" TopLine="337"/>
+ </Position21>
+ <Position22>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="342" Column="94" TopLine="339"/>
+ </Position22>
+ <Position23>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="344" Column="30" TopLine="335"/>
+ </Position23>
+ <Position24>
+ <Filename Value="dicom.pas"/>
+ <Caret Line="19" Column="44" TopLine="1"/>
+ </Position24>
+ <Position25>
+ <Filename Value="..\common\gzio2.pas"/>
+ <Caret Line="1881" Column="12" TopLine="1"/>
+ </Position25>
+ <Position26>
+ <Filename Value="..\common\gzio2.pas"/>
+ <Caret Line="2006" Column="3" TopLine="2005"/>
+ </Position26>
+ <Position27>
+ <Filename Value="..\common\gzio2.pas"/>
+ <Caret Line="2007" Column="3" TopLine="1994"/>
+ </Position27>
+ <Position28>
+ <Filename Value="dicom.pas"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
+ </Position28>
+ <Position29>
+ <Filename Value="dcm2nii.lpr"/>
+ <Caret Line="65" Column="23" TopLine="48"/>
+ </Position29>
+ <Position30>
+ <Filename Value="paramstrs.pas"/>
+ <Caret Line="13" Column="49" TopLine="1"/>
+ </Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
- <Version Value="9"/>
+ <Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<OtherUnitFiles Value="..\common"/>
@@ -390,12 +471,16 @@
</CodeGeneration>
<Linking>
<Debugging>
+ <GenerateDebugInfo Value="False"/>
<UseLineInfoUnit Value="False"/>
<StripSymbols Value="True"/>
</Debugging>
<LinkSmart Value="True"/>
</Linking>
<Other>
+ <ConfigFile>
+ <ConfigFilePath Value=""/>
+ </ConfigFile>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
diff --git a/dcm2nii/dcm2niigui.cfg b/dcm2nii/dcm2niigui.cfg
index 67f6fff..240d9f8 100755
--- a/dcm2nii/dcm2niigui.cfg
+++ b/dcm2nii/dcm2niigui.cfg
@@ -33,7 +33,7 @@
-K$00400000
-LE"c:\program files (x86)\borland\delphi7\Projects\Bpl"
-LN"c:\program files (x86)\borland\delphi7\Projects\Bpl"
--U"..\common\;C:\pas\d4\RX\Units\"
--O"..\common\;C:\pas\d4\RX\Units\"
--I"..\common\;C:\pas\d4\RX\Units\"
--R"..\common\;C:\pas\d4\RX\Units\"
+-U"..\common\;C:\pas\d4\RX\Units\;..\delphionly"
+-O"..\common\;C:\pas\d4\RX\Units\;..\delphionly"
+-I"..\common\;C:\pas\d4\RX\Units\;..\delphionly"
+-R"..\common\;C:\pas\d4\RX\Units\;..\delphionly"
diff --git a/dcm2nii/dcm2niigui.dof b/dcm2nii/dcm2niigui.dof
index 97da3dd..485b1ed 100755
--- a/dcm2nii/dcm2niigui.dof
+++ b/dcm2nii/dcm2niigui.dof
@@ -94,7 +94,7 @@ OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
-SearchPath=..\common\;C:\pas\d4\RX\Units\
+SearchPath=..\common\;C:\pas\d4\RX\Units\;..\delphionly
Packages=Vcl40;Vclx40;VclSmp40;Qrpt40;Vcldb40;RxCtl4
Conditionals=
DebugSourceDirs=
@@ -138,7 +138,8 @@ 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=4
+Item0=..\common\;C:\pas\d4\RX\Units\;..\delphionly
+Item1=..\common\;C:\pas\d4\RX\Units\
+Item2=..\common\;C:\pas\d4\RX\Units
+Item3=..\common\
diff --git a/dcm2nii/dcm2niigui.ini b/dcm2nii/dcm2niigui.ini
index 99e6b8a..80c40a5 100755
--- a/dcm2nii/dcm2niigui.ini
+++ b/dcm2nii/dcm2niigui.ini
@@ -6,7 +6,7 @@ Verbose=0
Anonymize=1
AnonymizeSourceDICOM=0
AppendAcqSeries=1
-AppendDate=1
+AppendDate=0
AppendFilename=0
AppendPatientName=0
AppendProtocolName=1
@@ -18,7 +18,7 @@ enablereorient=1
OrthoFlipXDim=0
EveryFile=1
fourD=1
-Gzip=1
+Gzip=0
ManualNIfTIConv=1
PhilipsPrecise=0
RecursiveUseNameAppend=0
@@ -27,6 +27,7 @@ SPM2=0
Stack3DImagesWithSameAcqNum=0
Swizzle4D=1
UseGE_0021_104F=0
+TxtReport=0
[INT]
BeginClip=0
diff --git a/dcm2nii/dcm2niigui.lpi b/dcm2nii/dcm2niigui.lpi
index ba35aaa..3518472 100755
--- a/dcm2nii/dcm2niigui.lpi
+++ b/dcm2nii/dcm2niigui.lpi
@@ -33,14 +33,14 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
- <Units Count="50">
+ <Units Count="52">
<Unit0>
<Filename Value="dcm2niigui.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="dcm2niigui"/>
<TopLine Value="1"/>
<CursorPos X="2" Y="1"/>
- <UsageCount Value="104"/>
+ <UsageCount Value="167"/>
</Unit0>
<Unit1>
<Filename Value="gui.pas"/>
@@ -50,16 +50,16 @@
<ResourceBaseClass Value="Form"/>
<UnitName Value="gui"/>
<WindowIndex Value="0"/>
- <TopLine Value="41"/>
- <CursorPos X="18" Y="486"/>
- <UsageCount Value="104"/>
+ <TopLine Value="955"/>
+ <CursorPos X="26" Y="961"/>
+ <UsageCount Value="167"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
<Filename Value="dcm2niigui.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="5"/>
+ <UsageCount Value="10"/>
</Unit2>
<Unit3>
<Filename Value="nifti_form.pas"/>
@@ -69,20 +69,24 @@
<ResourceBaseClass Value="Form"/>
<UnitName Value="nifti_form"/>
<WindowIndex Value="0"/>
- <TopLine Value="65"/>
- <CursorPos X="37" Y="10"/>
- <UsageCount Value="104"/>
+ <TopLine Value="66"/>
+ <CursorPos X="26" Y="73"/>
+ <UsageCount Value="167"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit3>
<Unit4>
<Filename Value="pref_form.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="PrefsForm"/>
+ <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="pref_form"/>
+ <EditorIndex Value="7"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="10"/>
- <UsageCount Value="104"/>
+ <TopLine Value="69"/>
+ <CursorPos X="33" Y="82"/>
+ <UsageCount Value="167"/>
+ <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
@@ -91,113 +95,115 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="128" Y="6"/>
- <UsageCount Value="21"/>
+ <UsageCount Value="16"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
<Filename Value="pref_form.lrs"/>
<TopLine Value="1"/>
<CursorPos X="4" Y="36"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="1"/>
</Unit6>
<Unit7>
<Filename Value="..\..\lcl\lresources.pp"/>
<UnitName Value="LResources"/>
<TopLine Value="2628"/>
<CursorPos X="21" Y="2642"/>
- <UsageCount Value="5"/>
+ <UsageCount Value="10"/>
</Unit7>
<Unit8>
<Filename Value="dialogsx.pas"/>
<UnitName Value="dialogsx"/>
<TopLine Value="1"/>
<CursorPos X="33" Y="9"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="1"/>
</Unit8>
<Unit9>
<Filename Value="readint.pas"/>
<UnitName Value="readint"/>
<TopLine Value="1"/>
<CursorPos X="15" Y="7"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="1"/>
</Unit9>
<Unit10>
<Filename Value="readint.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="1"/>
</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="5"/>
+ <UsageCount Value="10"/>
</Unit11>
<Unit12>
<Filename Value="define_types.pas"/>
<UnitName Value="define_types"/>
<TopLine Value="1"/>
<CursorPos X="40" Y="2"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="1"/>
</Unit12>
<Unit13>
<Filename Value="paramstrs.pas"/>
<UnitName Value="paramstrs"/>
- <EditorIndex Value="7"/>
<WindowIndex Value="0"/>
- <TopLine Value="181"/>
- <CursorPos X="33" Y="194"/>
- <UsageCount Value="17"/>
- <Loaded Value="True"/>
+ <TopLine Value="316"/>
+ <CursorPos X="16" Y="342"/>
+ <UsageCount Value="16"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit13>
<Unit14>
<Filename Value="niftiutil.pas"/>
<UnitName Value="niftiutil"/>
+ <EditorIndex Value="9"/>
<WindowIndex Value="0"/>
- <TopLine Value="260"/>
- <CursorPos X="10" Y="274"/>
- <UsageCount Value="16"/>
+ <TopLine Value="992"/>
+ <CursorPos X="13" Y="1001"/>
+ <UsageCount Value="41"/>
+ <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit14>
<Unit15>
<Filename Value="prefs.pas"/>
<UnitName Value="prefs"/>
+ <EditorIndex Value="8"/>
<WindowIndex Value="0"/>
- <TopLine Value="186"/>
- <CursorPos X="9" Y="199"/>
- <UsageCount Value="21"/>
+ <TopLine Value="1"/>
+ <CursorPos X="74" Y="22"/>
+ <UsageCount Value="46"/>
+ <Loaded Value="True"/>
<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="12"/>
- <Loaded Value="True"/>
+ <CursorPos X="23" Y="6"/>
+ <UsageCount Value="11"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit16>
<Unit17>
<Filename Value="dicomtypes.pas"/>
<UnitName Value="dicomtypes"/>
- <EditorIndex Value="4"/>
+ <EditorIndex Value="6"/>
<WindowIndex Value="0"/>
- <TopLine Value="7"/>
- <CursorPos X="15" Y="638"/>
- <UsageCount Value="32"/>
+ <TopLine Value="1"/>
+ <CursorPos X="68" Y="59"/>
+ <UsageCount Value="60"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit17>
<Unit18>
<Filename Value="filename.pas"/>
<UnitName Value="filename"/>
- <TopLine Value="118"/>
- <CursorPos X="55" Y="131"/>
- <UsageCount Value="11"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="120"/>
+ <CursorPos X="41" Y="133"/>
+ <UsageCount Value="6"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit18>
<Unit19>
<Filename Value="userdir.pas"/>
@@ -205,14 +211,14 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="3"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="2"/>
</Unit19>
<Unit20>
<Filename Value="gzio2.pas"/>
<UnitName Value="gzio2"/>
<TopLine Value="762"/>
<CursorPos X="26" Y="788"/>
- <UsageCount Value="5"/>
+ <UsageCount Value="10"/>
</Unit20>
<Unit21>
<Filename Value="nii_crop.pas"/>
@@ -220,7 +226,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="31" Y="26"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit21>
<Unit22>
@@ -228,17 +234,16 @@
<UnitName Value="userdir"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="15"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="6"/>
</Unit22>
<Unit23>
<Filename Value="..\common\define_types.pas"/>
<UnitName Value="define_types"/>
- <IsVisibleTab Value="True"/>
- <EditorIndex Value="2"/>
+ <EditorIndex Value="3"/>
<WindowIndex Value="0"/>
- <TopLine Value="6"/>
- <CursorPos X="28" Y="21"/>
- <UsageCount Value="35"/>
+ <TopLine Value="51"/>
+ <CursorPos X="21" Y="67"/>
+ <UsageCount Value="55"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit23>
@@ -247,16 +252,17 @@
<UnitName Value="gziod"/>
<TopLine Value="311"/>
<CursorPos X="98" Y="322"/>
- <UsageCount Value="5"/>
+ <UsageCount Value="10"/>
</Unit24>
<Unit25>
<Filename Value="convert.pas"/>
<UnitName Value="convert"/>
- <EditorIndex Value="5"/>
+ <IsVisibleTab Value="True"/>
+ <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
- <TopLine Value="899"/>
- <CursorPos X="154" Y="904"/>
- <UsageCount Value="38"/>
+ <TopLine Value="1309"/>
+ <CursorPos X="42" Y="1313"/>
+ <UsageCount Value="69"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit25>
@@ -267,28 +273,28 @@
<WindowIndex Value="0"/>
<TopLine Value="53"/>
<CursorPos X="1" Y="71"/>
- <UsageCount Value="12"/>
+ <UsageCount Value="43"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit26>
<Unit27>
<Filename Value="nii_asl.pas"/>
<UnitName Value="nii_asl"/>
- <EditorIndex Value="8"/>
<WindowIndex Value="0"/>
<TopLine Value="525"/>
<CursorPos X="42" Y="539"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit27>
<Unit28>
<Filename Value="..\common\GraphicsMathLibrary.pas"/>
<UnitName Value="GraphicsMathLibrary"/>
+ <EditorIndex Value="4"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="25" Y="9"/>
- <UsageCount Value="13"/>
+ <TopLine Value="809"/>
+ <CursorPos X="11" Y="825"/>
+ <UsageCount Value="32"/>
+ <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit28>
<Unit29>
@@ -297,7 +303,7 @@
<WindowIndex Value="0"/>
<TopLine Value="53"/>
<CursorPos X="52" Y="60"/>
- <UsageCount Value="32"/>
+ <UsageCount Value="27"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit29>
<Unit30>
@@ -305,7 +311,7 @@
<UnitName Value="LibTar"/>
<TopLine Value="246"/>
<CursorPos X="35" Y="272"/>
- <UsageCount Value="5"/>
+ <UsageCount Value="10"/>
</Unit30>
<Unit31>
<Filename Value="untar.pas"/>
@@ -313,26 +319,26 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="44" Y="11"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit31>
<Unit32>
<Filename Value="dicomfastread.pas"/>
<UnitName Value="dicomfastread"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="27" Y="26"/>
- <UsageCount Value="19"/>
+ <TopLine Value="418"/>
+ <CursorPos X="57" Y="431"/>
+ <UsageCount Value="14"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit32>
<Unit33>
<Filename Value="dicomcompat.pas"/>
<UnitName Value="dicomcompat"/>
- <EditorIndex Value="1"/>
+ <EditorIndex Value="10"/>
<WindowIndex Value="0"/>
- <TopLine Value="3104"/>
- <CursorPos X="24" Y="3104"/>
- <UsageCount Value="41"/>
+ <TopLine Value="4784"/>
+ <CursorPos X="42" Y="4799"/>
+ <UsageCount Value="70"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit33>
@@ -342,7 +348,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="22" Y="10"/>
- <UsageCount Value="13"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit34>
<Unit35>
@@ -351,19 +357,17 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="93" Y="7"/>
- <UsageCount Value="13"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit35>
<Unit36>
<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"/>
+ <TopLine Value="187"/>
+ <CursorPos X="38" Y="199"/>
+ <UsageCount Value="122"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit36>
<Unit37>
@@ -372,21 +376,21 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="83" Y="9"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit37>
<Unit38>
<Filename Value="gui.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="3"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="2"/>
</Unit38>
<Unit39>
<Filename Value="nii_math.pas"/>
<UnitName Value="nii_math"/>
<TopLine Value="576"/>
<CursorPos X="78" Y="592"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="2"/>
</Unit39>
<Unit40>
<Filename Value="C:\Documents and Settings\chris\Desktop\scripter\unit1.pas"/>
@@ -395,32 +399,33 @@
<UnitName Value="Unit1"/>
<TopLine Value="34"/>
<CursorPos X="1" Y="35"/>
- <UsageCount Value="17"/>
+ <UsageCount Value="12"/>
</Unit40>
<Unit41>
<Filename Value="..\common\nifti_hdr.pas"/>
<UnitName Value="nifti_hdr"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="25" Y="310"/>
+ <TopLine Value="3"/>
+ <CursorPos X="94" Y="9"/>
<UsageCount Value="7"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
</Unit41>
<Unit42>
<Filename Value="..\common\isgui.inc"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="10" Y="1"/>
- <UsageCount Value="27"/>
+ <UsageCount Value="22"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit42>
<Unit43>
<Filename Value="csaread.pas"/>
<UnitName Value="csaread"/>
- <EditorIndex Value="3"/>
+ <EditorIndex Value="5"/>
<WindowIndex Value="0"/>
- <TopLine Value="22"/>
- <CursorPos X="61" Y="35"/>
- <UsageCount Value="27"/>
+ <TopLine Value="376"/>
+ <CursorPos X="20" Y="384"/>
+ <UsageCount Value="58"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit43>
@@ -429,9 +434,9 @@
<IsPartOfProject Value="True"/>
<UnitName Value="dialogs_msg"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="17" Y="1"/>
- <UsageCount Value="23"/>
+ <TopLine Value="7"/>
+ <CursorPos X="11" Y="9"/>
+ <UsageCount Value="86"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit44>
<Unit45>
@@ -440,7 +445,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="26" Y="19"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit45>
<Unit46>
@@ -449,7 +454,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="26" Y="11"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit46>
<Unit47>
@@ -458,7 +463,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="56" Y="21"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit47>
<Unit48>
@@ -467,7 +472,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="65" Y="5"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit48>
<Unit49>
@@ -476,130 +481,152 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="71" Y="9"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit49>
+ <Unit50>
+ <Filename Value="..\common\nifti_types.pas"/>
+ <UnitName Value="nifti_types"/>
+ <EditorIndex Value="1"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="72"/>
+ <CursorPos X="72" Y="86"/>
+ <UsageCount Value="37"/>
+ <Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit50>
+ <Unit51>
+ <Filename Value="..\common\nifti_foreign.pas"/>
+ <UnitName Value="nifti_foreign"/>
+ <EditorIndex Value="11"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="416"/>
+ <CursorPos X="6" Y="420"/>
+ <UsageCount Value="37"/>
+ <Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit51>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="3209" Column="39" TopLine="3178"/>
+ <Caret Line="5948" Column="93" TopLine="5947"/>
</Position1>
<Position2>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="3220" Column="42" TopLine="3189"/>
+ <Caret Line="131" Column="156" TopLine="131"/>
</Position2>
<Position3>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="3892" Column="73" TopLine="3862"/>
+ <Caret Line="1241" Column="39" TopLine="1223"/>
</Position3>
<Position4>
<Filename Value="dicomcompat.pas"/>
- <Caret Line="3902" Column="53" TopLine="3872"/>
+ <Caret Line="1255" Column="22" TopLine="1237"/>
</Position4>
<Position5>
- <Filename Value="convert.pas"/>
- <Caret Line="264" Column="78" TopLine="263"/>
+ <Filename Value="dicomcompat.pas"/>
+ <Caret Line="1257" Column="47" TopLine="1239"/>
</Position5>
<Position6>
- <Filename Value="convert.pas"/>
- <Caret Line="1360" Column="57" TopLine="1330"/>
+ <Filename Value="dicomcompat.pas"/>
+ <Caret Line="1258" Column="86" TopLine="1240"/>
</Position6>
<Position7>
- <Filename Value="convert.pas"/>
- <Caret Line="1" Column="142" TopLine="1"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="1005" Column="77" TopLine="996"/>
</Position7>
<Position8>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="3874" Column="107" TopLine="3873"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="3" Column="140" TopLine="1"/>
</Position8>
<Position9>
- <Filename Value="convert.pas"/>
- <Caret Line="825" Column="46" TopLine="797"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="1002" Column="51" TopLine="995"/>
</Position9>
<Position10>
<Filename Value="convert.pas"/>
- <Caret Line="826" Column="146" TopLine="797"/>
+ <Caret Line="3" Column="138" TopLine="1"/>
</Position10>
<Position11>
<Filename Value="convert.pas"/>
- <Caret Line="899" Column="146" TopLine="868"/>
+ <Caret Line="125" Column="137" TopLine="123"/>
</Position11>
<Position12>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="133" Column="16" TopLine="122"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1144" Column="24" TopLine="1134"/>
</Position12>
<Position13>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="6" Column="12" TopLine="1"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1155" Column="7" TopLine="1141"/>
</Position13>
<Position14>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="127" Column="47" TopLine="112"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="170" Column="138" TopLine="168"/>
</Position14>
<Position15>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="161" Column="57" TopLine="132"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="5" Column="136" TopLine="1"/>
</Position15>
<Position16>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="142" Column="10" TopLine="128"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="929" Column="21" TopLine="905"/>
</Position16>
<Position17>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="135" Column="25" TopLine="113"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="976" Column="39" TopLine="953"/>
</Position17>
<Position18>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="126" Column="6" TopLine="112"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="978" Column="53" TopLine="955"/>
</Position18>
<Position19>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="129" Column="9" TopLine="115"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="981" Column="20" TopLine="959"/>
</Position19>
<Position20>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="6" Column="5" TopLine="1"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="1003" Column="25" TopLine="991"/>
</Position20>
<Position21>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="149" Column="39" TopLine="134"/>
+ <Filename Value="niftiutil.pas"/>
+ <Caret Line="1002" Column="92" TopLine="991"/>
</Position21>
<Position22>
- <Filename Value="philips_bvec.pas"/>
- <Caret Line="167" Column="132" TopLine="148"/>
+ <Filename Value="csaread.pas"/>
+ <Caret Line="15" Column="28" TopLine="6"/>
</Position22>
<Position23>
- <Filename Value="paramstrs.pas"/>
- <Caret Line="238" Column="1" TopLine="231"/>
+ <Filename Value="csaread.pas"/>
+ <Caret Line="203" Column="9" TopLine="197"/>
</Position23>
<Position24>
- <Filename Value="nii_asl.pas"/>
- <Caret Line="9" Column="3" TopLine="3"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1135" Column="30" TopLine="1130"/>
</Position24>
<Position25>
- <Filename Value="nii_asl.pas"/>
- <Caret Line="535" Column="49" TopLine="521"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="13" Column="62" TopLine="1"/>
</Position25>
<Position26>
- <Filename Value="paramstrs.pas"/>
- <Caret Line="193" Column="9" TopLine="174"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1098" Column="26" TopLine="1099"/>
</Position26>
<Position27>
- <Filename Value="paramstrs.pas"/>
- <Caret Line="14" Column="1" TopLine="2"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1159" Column="21" TopLine="1147"/>
</Position27>
<Position28>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="3" Column="116" TopLine="1"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1162" Column="16" TopLine="1153"/>
</Position28>
<Position29>
- <Filename Value="dicomcompat.pas"/>
- <Caret Line="5067" Column="76" TopLine="5052"/>
+ <Filename Value="convert.pas"/>
+ <Caret Line="1175" Column="79" TopLine="1153"/>
</Position29>
<Position30>
<Filename Value="csaread.pas"/>
- <Caret Line="38" Column="131" TopLine="24"/>
+ <Caret Line="262" Column="69" TopLine="259"/>
</Position30>
</JumpHistory>
</ProjectOptions>
diff --git a/dcm2nii/dicomcompat.pas b/dcm2nii/dicomcompat.pas
index 9233356..df185bf 100755
--- a/dcm2nii/dicomcompat.pas
+++ b/dcm2nii/dicomcompat.pas
@@ -4956,7 +4956,10 @@ end;
$1005: info := 'Patient''s Birth Name';
$1010: begin info := 'Patient Age'; t := _string; end;
$1030: info := 'Patient Weight';
- $21b0: info := 'Additional Patient History';
+ $21b0: begin
+ info := 'Additional Patient History';
+ DICOMHeaderString(lDicomData.PatientHx);
+ end ;
$4000: info := 'Patient Comments';
end;
@@ -4969,6 +4972,7 @@ end;
info := 'Scanning Sequence';t := _string;
TmpStr := '';
DICOMHeaderString(TmpStr);
+ lDICOMdata.ScanningSequence0018_0020 := TmpStr;
if TmpStr = 'RM' then lResearchMode := true;
end;
$21 : begin info := 'Sequence Variant';t := _string; end;
@@ -5023,7 +5027,14 @@ end;
end;
//qq
- $87 : info := 'Magnetic Field Strength';
+ $87 : begin
+ info := 'Magnetic Field Strength';
+ readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
+ lDICOMdata.FieldStrength := round(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!
+ end;
$88 : begin
info := 'Spacing Between Slices';
readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
@@ -5474,7 +5485,10 @@ $0020 :
$3404: info := 'Modifying Device Mfg.';
$3405: info := 'Modified Image Time';
$3406: info := 'Modified Image Desc.';
- $4000: info := 'Image Comments';
+ $4000: begin
+ info := 'Image Comments';
+ DICOMHeaderString(lDicomData.ImageComments);
+ end;
$5000: info := 'Original Image ID';
$5002: info := 'Original Image... Nomenclature';
//$9113: xxxx
@@ -5925,13 +5939,13 @@ 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;
+ 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 then
- time_to_quit := TRUE;
+ time_to_quit := TRUE;
//x(lDicomData.RunLengthEncoding) or ( ((lDicomData.JPEGLossycpt) or (lDicomData.JPEGLosslesscpt)) and (gECATJPEG_table_entries >= lDICOMdata.XYZdim[3]))}
@@ -5940,6 +5954,15 @@ end; //$0028
remaining := 0;
e_len := 0; {show tempstr}
end;
+ $1020: begin
+ if (lDicomData.kV = 0) then begin //Siemens uses 0029:1020 for both CT and MRI, but only MRI is in CSA format
+ info := 'CSA Series Header Info';
+ lDicomData.CSASeriesHeaderInfoPos := (dFilePos(fp));
+ lDicomData.CSASeriesHeaderInfoSz := e_len;
+ //dcmMsg('CSA Series Header Info @ '+Inttostr (dFilePos(fp))+ 'length: '+inttostr(e_len) );
+ end;
+ //(0029, 1020) [CSA Series Header Info] OB: Array of 80248 bytes
+ end;
$1053: begin
info :='Philips Scale Slope';
readfloats (fp, remaining, lDummyStr, lfloat1, lfloat2, lROK);
diff --git a/dcm2nii/dicomtypes.pas b/dcm2nii/dicomtypes.pas
index 537665e..d67b355 100755
--- a/dcm2nii/dicomtypes.pas
+++ b/dcm2nii/dicomtypes.pas
@@ -21,9 +21,7 @@ TDTI = record
end;
TDTIRA = array [1..kMaxDTIDir] of TDTI;//TDICOM;//unsigned 8-bit int
TOrder= array [1..kMaxOrderVal] of byte;
-
-
- kDICOMStr = String[32];
+ kDICOMStr = String[128];
DICOMdata = record
XYZdim: array [1..4] of integer;
XYZori: array [1..3] of integer;
@@ -31,14 +29,15 @@ end;
Orient: array [1..6] of double;
SignedData,SiemensDICOMDTICSA,SiemensDICOMDTI,FloatData,file4D,JPEGLossyCpt,JPEGLosslessCpt: boolean;
SecSinceMidnight,PatientPosX,PatientPosY,PatientPosZ,AngulationAP,AngulationFH,AngulationRL: double;
- BandwidthPerPixelPhaseEncode, kV,TE, TR,IntenScale,IntenIntercept,location{,DTIv1,DTIv2,DTIv3}: single;
+ FieldStrength, 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,
+ CSAImageHeaderInfoPos,CSAImageHeaderInfoSz,
+ CSASeriesHeaderInfoPos,CSASeriesHeaderInfoSz,ManufacturerID,PlanarConfig, //ImplementationVersion,
Vers0018_1020,
CompressOffset,CompresssZ: integer;
DateTime: TDateTime;
- PatientGender,PatientDoB,PatientPos,PatientName,ProtocolName,StudyDate,StudyTime,PhilipsSliceOrient,PhaseEncoding: kDICOMStr;
+ PatientHx, ImageComments,PatientGender,PatientDoB,PatientPos,PatientName,ProtocolName,StudyDate,StudyTime,PhilipsSliceOrient,ScanningSequence0018_0020 ,PhaseEncoding: kDICOMStr;
Filename: string[255];
DTI: TDTIRA;
Order: TOrder; //4D datasets
@@ -47,7 +46,7 @@ end;
TDICOMRA = array [1..1] of DicomData;//TDICOM;//unsigned 8-bit int
TDICOMRAp = ^TDICOMRA;
- TNIFTIhdr = packed record //Next: analyze Format Header structure
+(* TNIFTIhdr = packed record //Next: analyze Format Header structure
HdrSz : longint; //MUST BE 348
Data_Type: array [1..10] of char; //unused
db_name: array [1..18] of char; //unused
@@ -167,7 +166,7 @@ kNIFTI_INTENT_VECTOR =1007;
kNIFTI_INTENT_POINTSET =1008;
kNIFTI_INTENT_TRIANGLE =1009;
kNIFTI_INTENT_QUATERNION =1010;
-
+ *)
const //dicom
kCR = chr (13);//PC EOLN
kA = ord('A');
@@ -200,6 +199,8 @@ procedure AplhaNumericStrDICOM (var lStr: kDICOMStr);
procedure PartialAcquisitionError;
function DICOMstr (i: integer; var lDICOMra: TDICOMrap;lOutname:string): string; overload;
function DICOMstr (i: integer; var lDICOMra: TDICOMrap): string; overload;
+function DICOMstr (var lDICOM: DICOMdata): string; overload;
+
implementation
@@ -221,17 +222,56 @@ begin
result := 0;
end;
end;
+
+function DICOMstr (var lDICOM: DICOMdata): string; overload;
+begin
+
+ result := lDICOM.Filename
+ //ProtocolName,StudyDate,StudyTime,PhilipsSliceOrient,PhaseEncoding: kDICOMStr;
+ +kTab+'Field Strength:'+kTab+floattostr(lDICOM.fieldStrength)
+ +kTab+'ProtocolName:'+kTab+ lDICOM.ProtocolName
+ +kTab+'ScanningSequence00180020:'+kTab+ lDICOM.ScanningSequence0018_0020
+ +kTab+'TE:'+kTab+floattostr(lDICOM.TE)
+ +kTab+'TR:'+kTab+floattostr(lDICOM.TR)
+
+ +kTab+'SeriesNum:'+kTab+inttostr(lDICOM.SeriesNum)
+ +kTab+'AcquNum:'+kTab+inttostr(lDICOM.AcquNum)
+ +kTab+'ImageNum:'+kTab+inttostr(lDICOM.ImageNum)
+ +kTab+'ImageComments:'+kTab+lDICOM.ImageComments
+
+ +kTab+'DateTime:'+kTab+DateTimeToStr(lDICOM.DateTime)
+ +kTab+'Name:'+kTab+lDICOM.PatientName
+ +kTab+'PatientHistory:'+kTab+lDICOM.PatientHx
+ +kTab+'DoB:'+kTab+lDICOM.PatientDoB
+ +kTab+'Gender:'+kTab+lDICOM.PatientGender
+
+ +kTab+'Age(Years):'+kTab+floattostr(YearsOld(lDICOM)) ;
+
+end;
+
function DICOMstr (i: integer; var lDICOMra: TDICOMrap;lOutname: string): string; overload;
var
lS: string;
begin
+ result := DICOMstr (lDICOMra^[i]);
+ if lOutname <> '' then
+ result := kTab+'SuggestedOutput:'+lOutname;
+end;
+
+(*function DICOMstr (i: integer; var lDICOMra: TDICOMrap;lOutname: string): string; overload;
+var
+ lS: string;
+begin
if lOutname <> '' then
lS := kTab+'SuggestedOutput:'+lOutname
else
lS := '';
result := lDICOMra^[i].Filename
- +kTab+'SeriesNum:'+kTab+inttostr(lDICOMra^[i].SeriesNum)
+ +kTab+'ImageComments:'+lDICOMra^[i].ImageComments
+ +kTab+'PatientHistory:'+lDICOMra^[i].PatientHx
+
+ +kTab+'SeriesNum:'+kTab+inttostr(lDICOMra^[i].SeriesNum)
+kTab+'AcquNum:'+inttostr(lDICOMra^[i].AcquNum)
+kTab+'ImageNum:'+inttostr(lDICOMra^[i].ImageNum)
+kTab+'Name:'+lDICOMra^[i].PatientName
@@ -239,9 +279,10 @@ begin
+kTab+'Gender:'+lDICOMra^[i].PatientGender
+kTab+'DateTime:'+DateTimeToStr(lDICOMra^[i].DateTime)
+kTab+'Age(Years):'+floattostr(YearsOld(lDICOMra^[i]))
+
+lS ;
-end;
+end; *)
function DICOMstr (i: integer; var lDICOMra: TDICOMrap): string; overload;
begin
@@ -625,6 +666,8 @@ begin
with lDicomData do begin
lDicomData.CSAImageHeaderInfoPos := 0;
lDicomData.CSAImageHeaderInfoSz := 0;
+ lDicomData.CSASeriesHeaderInfoPos := 0;
+ lDicomData.CSASeriesHeaderInfoSz := 0;
for lI := 1 to 6 do
Orient[lI] := 0;
DateTime := BogusDateTime;
@@ -638,6 +681,7 @@ begin
nDTIdir := 0;
nOrder := 0;
PhilipsSliceOrient := 'NA';
+ ScanningSequence0018_0020 := '';
PhaseEncoding := 'NA';
PatientPos := 'NA';
for lI := 1 to kMaxDTIdir do begin
@@ -656,6 +700,8 @@ begin
PatientName := 'NO NAME';
PatientDoB := 'NO DOB';
PatientGender := 'NA';
+ PatientHx := '';
+ ImageComments := '';
//PatientID := 'NO ID';
StudyDate := '';
StudyTime := '';
@@ -721,6 +767,7 @@ begin
CompressOffset := 0;
CompresssZ := 0;
BandwidthPerPixelPhaseEncode := 0; //7/2013
+ FieldStrength := 0;
end;
end;
diff --git a/dcm2nii/filename.pas b/dcm2nii/filename.pas
index 48d8105..e84fdf2 100755
--- a/dcm2nii/filename.pas
+++ b/dcm2nii/filename.pas
@@ -197,4 +197,4 @@ begin
end;
end.
-
+
\ No newline at end of file
diff --git a/dcm2nii/gui.dfm b/dcm2nii/gui.dfm
index 9961827..ebf3d88 100755
Binary files a/dcm2nii/gui.dfm and b/dcm2nii/gui.dfm differ
diff --git a/dcm2nii/gui.pas b/dcm2nii/gui.pas
index 7235205..aca2fde 100755
--- a/dcm2nii/gui.pas
+++ b/dcm2nii/gui.pas
@@ -3,8 +3,6 @@ unit gui;
interface
uses
-
-
{$IFDEF FPC}LResources,LCLIntf, {$ELSE} Messages,{$ENDIF}
{$IFNDEF UNIX} Windows,ShellAPI,ShlObj,
{$ELSE}
@@ -15,7 +13,7 @@ LCLType,
SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls,
//ToolWin,
//ComCtrls,
-ExtCtrls,
+ExtCtrls, nifti_types,
//IniFiles,
define_types,sortdicom,//dicom,
parconvert,
@@ -192,6 +190,7 @@ var
lINc,lProcess: integer;
lExt,lFilename,lOutname: string;
lHdr: TNIFTIhdr;
+ lO: TNIIOpts;
begin
if lFilenames.Count < 1 then exit;
lPrev4D := false; //ignored in if statement - set only to avoid compiler warning
@@ -201,7 +200,7 @@ begin
lExt := UpCaseExt(lFilename);
if lExt ='.IMG' then
lFilename := changefileext(lFilename,'.hdr');
- if not NIFTIhdr_LoadHdr (lFilename, lHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lHdr, lO) then begin
MsgX('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
@@ -662,14 +661,14 @@ var
lPrefs: TPrefs;
lMaskName: string;
lHdr: TNIfTIHdr;
- lByteSwap {, lSaveThresh3D}: boolean;
+ lO: TNIIOpts;
lI,lV: integer;
begin
PrefsForm.ReadPrefs(lPrefs);
if not MainForm.OpenDialogExecute('Select the mask image',false,false,kImgFilter) then
exit;
lMaskName := MainForm.OpenHdrDlg.Filename;
- if not NIFTIhdr_LoadHdr (lMaskName, lHdr, lByteSwap) then
+ if not NIFTIhdr_LoadHdr (lMaskName, lHdr, lO) then
exit;
lV := 1;
//lSaveThresh3D := (MessageDlg('Save thresholded images for each individual?',mtCustom,[mbYes,mbNo], 0)=mrYes);
diff --git a/dcm2nii/nifti_form.lfm b/dcm2nii/nifti_form.lfm
index b6de3d9..3d4dfc9 100755
--- a/dcm2nii/nifti_form.lfm
+++ b/dcm2nii/nifti_form.lfm
@@ -2,19 +2,21 @@ object NIfTIForm: TNIfTIForm
Left = 797
Height = 266
Top = 32
- Width = 338
+ Width = 400
ActiveControl = OKBtn
+ BiDiMode = bdRightToLeft
BorderIcons = [biSystemMenu]
BorderStyle = bsDialog
Caption = 'Convert NIfTI File'
ClientHeight = 266
- ClientWidth = 338
+ ClientWidth = 400
Constraints.MaxHeight = 266
- Constraints.MaxWidth = 338
+ Constraints.MaxWidth = 400
Constraints.MinHeight = 266
- Constraints.MinWidth = 338
+ Constraints.MinWidth = 400
OnCreate = FormCreate
- LCLVersion = '0.9.30.2'
+ ParentBiDiMode = False
+ LCLVersion = '1.0.12.0'
object Label1: TLabel
Left = 8
Height = 17
@@ -99,7 +101,7 @@ object NIfTIForm: TNIfTIForm
end
object StartEdit: TSpinEdit
Left = 224
- Height = 16
+ Height = 15
Top = 13
Width = 74
MaxValue = 9999999
@@ -107,7 +109,7 @@ object NIfTIForm: TNIfTIForm
end
object EndEdit: TSpinEdit
Left = 224
- Height = 16
+ Height = 15
Top = 53
Width = 74
MaxValue = 9999999
@@ -118,7 +120,7 @@ object NIfTIForm: TNIfTIForm
Left = 47
Height = 20
Top = 11
- Width = 280
+ Width = 337
ItemHeight = 0
Items.Strings = (
'Change format'
@@ -136,7 +138,7 @@ object NIfTIForm: TNIfTIForm
Left = 48
Height = 20
Top = 11
- Width = 279
+ Width = 336
ItemHeight = 0
Items.Strings = (
'Change format'
@@ -159,7 +161,7 @@ object NIfTIForm: TNIfTIForm
Left = 16
Height = 20
Top = 11
- Width = 246
+ Width = 250
ItemHeight = 0
Items.Strings = (
'Subtract pairs - first image tagged'
@@ -177,6 +179,7 @@ object NIfTIForm: TNIfTIForm
Top = 56
Width = 273
BevelOuter = bvNone
+ BorderStyle = bsSingle
ClientHeight = 114
ClientWidth = 273
TabOrder = 7
@@ -200,7 +203,7 @@ object NIfTIForm: TNIfTIForm
end
object ScaleEdit: TFloatSpinEdit
Left = 127
- Height = 16
+ Height = 15
Top = 11
Width = 130
DecimalPlaces = 8
@@ -212,7 +215,7 @@ object NIfTIForm: TNIfTIForm
end
object PowerEdit: TFloatSpinEdit
Left = 127
- Height = 16
+ Height = 15
Top = 56
Width = 130
DecimalPlaces = 8
diff --git a/dcm2nii/nifti_form.lrs b/dcm2nii/nifti_form.lrs
index eb9a942..fec7501 100755
--- a/dcm2nii/nifti_form.lrs
+++ b/dcm2nii/nifti_form.lrs
@@ -2,61 +2,62 @@
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
+ +#5'Width'#3#144#1#13'ActiveControl'#7#5'OKBtn'#8'BiDiMode'#7#13'bdRightToLef'
+ +'t'#11'BorderIcons'#11#12'biSystemMenu'#0#11'BorderStyle'#7#8'bsDialog'#7'Ca'
+ +'ption'#6#18'Convert NIfTI File'#12'ClientHeight'#3#10#1#11'ClientWidth'#3
+ +#144#1#21'Constraints.MaxHeight'#3#10#1#20'Constraints.MaxWidth'#3#144#1#21
+ +'Constraints.MinHeight'#3#10#1#20'Constraints.MinWidth'#3#144#1#8'OnCreate'#7
+ +#10'FormCreate'#14'ParentBiDiMode'#8#10'LCLVersion'#6#8'1.0.12.0'#0#6'TLabel'
+ +#6'Label1'#4'Left'#2#8#6'Height'#2#17#3'Top'#3#168#0#5'Width'#2'f'#9'Alignme'
+ +'nt'#7#8'taCenter'#7'Caption'#6#15'Output Format: '#11'ParentColor'#8#0#0#6
+ +'TLabel'#6'Label4'#4'Left'#2#8#6'Height'#2#17#3'Top'#2#16#5'Width'#2'#'#9'Al'
+ +'ignment'#7#8'taCenter'#7'Caption'#6#5'Task:'#11'ParentColor'#8#0#0#7'TButto'
+ +'n'#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'ModalResult'#2#1#7'OnC'
+ +'lick'#7#10'OKBtnClick'#8'TabOrder'#2#0#0#0#7'TButton'#9'CancelBtn'#4'Left'#2
+ +'h'#6'Height'#2#25#3'Top'#3#208#0#5'Width'#2'K'#25'BorderSpacing.InnerBorder'
+ +#2#4#7'Caption'#6#6'Cancel'#11'ModalResult'#2#2#8'TabOrder'#2#1#0#0#9'TCombo'
+ +'Box'#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 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 dra'
+ +'wing (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'BevelOute'
+ +'r'#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'TLa'
+ +'bel'#6'Label3'#4'Left'#2#7#6'Height'#2#17#3'Top'#2'7'#5'Width'#3#185#0#7'Ca'
+ +'ption'#6#26'Volumes to remove from end'#11'ParentColor'#8#0#0#9'TSpinEdit'#9
+ +'StartEdit'#4'Left'#3#224#0#6'Height'#2#15#3'Top'#2#13#5'Width'#2'J'#8'MaxVa'
+ +'lue'#4#127#150#152#0#8'TabOrder'#2#0#0#0#9'TSpinEdit'#7'EndEdit'#4'Left'#3
+ +#224#0#6'Height'#2#15#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'T'
+ +'op'#2#11#5'Width'#3'Q'#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'Exp'
+ +'ort as 32-bit real'#6#13'Apply formula'#6#14'ASL conversion'#0#8'OnChange'#7
+ +#13'Combo4DChange'#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#4#0#0#9'TComb'
+ +'oBox'#7'Combo3D'#4'Left'#2'0'#6'Height'#2#20#3'Top'#2#11#5'Width'#3'P'#1#10
+ +'ItemHeight'#2#0#13'Items.Strings'#1#6#13'Change format'#6#22'Reorient to or'
+ +'thogonal'#6#17'Reorient and crop'#0#5'Style'#7#14'csDropDownList'#8'TabOrde'
+ +'r'#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'ClientWid'
+ +'th'#3#19#1#8'TabOrder'#2#6#0#9'TComboBox'#8'ASLCombo'#4'Left'#2#16#6'Height'
+ +#2#20#3'Top'#2#11#5'Width'#3#250#0#10'ItemHeight'#2#0#13'Items.Strings'#1#6
+ +'#Subtract pairs - first image tagged'#6'$Subtract pairs - first image contr'
+ +'ol'#6#15'Subtract Custom'#6#19'Add (odd+even) BOLD'#0#5'Style'#7#14'csDropD'
+ +'ownList'#8'TabOrder'#2#0#0#0#0#6'TPanel'#12'FormulaPanel'#4'Left'#2'/'#6'He'
+ +'ight'#2'r'#3'Top'#2'8'#5'Width'#3#17#1#10'BevelOuter'#7#6'bvNone'#11'Border'
+ +'Style'#7#8'bsSingle'#12'ClientHeight'#2'r'#11'ClientWidth'#3#17#1#8'TabOrde'
+ +'r'#2#7#0#6'TLabel'#6'Label5'#4'Left'#2#31#6'Height'#2#17#3'Top'#2#17#5'Widt'
+ +'h'#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'taCenter'#7'Caption'#6#5'Power'#11'ParentColor'#8#0#0#14'T'
+ +'FloatSpinEdit'#9'ScaleEdit'#4'Left'#2#127#6'Height'#2#15#3'Top'#2#11#5'Widt'
+ +'h'#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'TabO'
+ +'rder'#2#0#5'Value'#5#0#176#27'l'#160#175#15#161#235'?'#0#0#14'TFloatSpinEdi'
+ +'t'#9'PowerEdit'#4'Left'#2#127#6'Height'#2#15#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'TabOrder'#2#1#5'Valu'
+ +'e'#5#0#176#27'l'#160#175#15#161#235'?'#0#0#0#0
]);
\ No newline at end of file
diff --git a/dcm2nii/niftiutil.pas b/dcm2nii/niftiutil.pas
index aaca33c..b28ab97 100755
--- a/dcm2nii/niftiutil.pas
+++ b/dcm2nii/niftiutil.pas
@@ -8,8 +8,15 @@ gzio2, process, //FileUtil,
{$ELSE}
gziod, ShellAPI,Windows,Forms,
{$ENDIF}
- SysUtils,Classes,define_types,filename,dicomtypes,prefs,dialogs_msg;
+ SysUtils,Classes,define_types,filename,dicomtypes,prefs,dialogs_msg, nifti_foreign, nifti_types;
{$H+}
+type
+ TNIIopts = RECORD //peristimulus plot
+ bs: boolean;
+ gzBytes: Int64; // K_gzBytes_headerAndImageCompressed, K_gzBytes_onlyImageCompressed, K_gzBytes_headerAndImageUncompressed= 0;
+ ImgName: string;
+ end;
+
const
kNIIImgOffset = 352; //header is 348 bytes, but 352 is divisible by 8...
function MaskImgs(lC1template, lC1source: string; lPrefs: TPrefs ; lThresh: single): string;
@@ -22,15 +29,16 @@ procedure CustomFilename (var lFilename: string);
function SumTPM (lSrcName,lDestName: string; lPrefs: TPrefs; lTissueTypes2Average: integer):string;
//function SameHdrDim (lAHdr,lBHdr: TNIFTIhdr): boolean;
function SaveHdr (var lFilename: ANSIstring; var lInHdr: TNIFTIhdr ; lSwap,lSPM2:boolean): boolean;
-function NIFTIhdr_LoadHdr (var lFilename: string; var lHdr: TNIFTIHdr; var lByteSwap: boolean): boolean;
+function NIFTIhdr_LoadHdr (var lFilename: string; var lHdr: TNIFTIHdr; var lOpts: TNIIopts): boolean;
+
procedure NIFTIhdr_SlicesToCoord (var lHdr: TNIFTIhdr; lXslice,lYslice,lZslice: integer; var lXmm,lYmm,lZmm: single);
function ChangeNIfTISubformat(lHdrName: string; var lHdr: TNIFTIhdr; lPrefs: TPrefs): boolean;
procedure SaveHdrRAM (var lFilename: ANSIstring; var lInHdr,lOutHdr: TNIFTIhdr ; lSwap,lSPM2:boolean);
-function SaveNIfTICore (var lOutImgName: string; var lvBuffer: bytep; lVolOffset: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs; var lByteSwap: boolean): string;
-function SaveNIfTICoreCrop (var lOutImgName: string; var lvBuffer: bytep; lVolOffset,lStartClip,lEndClip: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs; var lByteSwap: boolean): string;
-function NIFTIhdr_LoadImg (var lFilename: string; var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lByteSwap: boolean): boolean;
-procedure NIFTIhdr_UnswapImg (var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lByteSwap: boolean); //ensures image data is in native space
-function NIFTIhdr_LoadImgRaw (LoadHdr: boolean; var lFilename: string; var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lByteSwap: boolean): boolean;
+function SaveNIfTICore (var lOutImgName: string; var lvBuffer: bytep; lVolOffset: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs): string;
+function SaveNIfTICoreCrop (var lOutImgName: string; var lvBuffer: bytep; lVolOffset,lStartClip,lEndClip: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs): string;
+function NIFTIhdr_LoadImg (var lFilename: string; var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lOpts: TNIIopts): boolean;
+//procedure NIFTIhdr_UnswapImg (var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lByteSwap: boolean); //ensures image data is in native space
+function NIFTIhdr_LoadImgRaw (LoadHdr: boolean; var lFilename: string; var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lOpts: TNIIopts): boolean;
function NII_force32 (lSrcName,lDestName: string; lPrefs: TPrefs):string;
function Rescale_4Dtissuemaps (lSrcName,lDestName: string; lPrefs: TPrefs; lMakeSym: boolean):string;
function Merge4DFiles (lLowSliceName,lHighSliceName,lDestName: string; lNumberofLowSlicesToCopy: integer; lPrefs: TPrefs):string;
@@ -50,50 +58,6 @@ begin
result := lNameWOExt+'_'+PadStr(lVol,length(inttostr(lnVol))) +lExt;
end;
-procedure NIFTIhdr_UnswapImg (var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lByteSwap: boolean); //ensures image data is in native space
-//returns data in native endian
-//sets 'ByteSwap' flag to false. E.G. a big-endian image will be saved as little-endian on little endian machines
-var
- lInc,lImgSamples : integer;
- //2f : SingleP;
- l32i : LongIntP;
- l16i : SmallIntP;
-begin
- if not lByteSwap then exit;
- case lHdr.datatype of
- kDT_UNSIGNED_CHAR : begin
- lByteSwap := false; //single byte data - no need to byte swap...
- exit;
- end;
- kDT_SIGNED_SHORT,kDT_SIGNED_INT,kDT_FLOAT: ;//supported format
- else begin
- dcmMsg('niftiutil UnSwapImg error: datatype not supported.');
- exit;
- end;
- end; //case
- lImgSamples := lHdr.Dim[1] *lHdr.Dim[2]*lHdr.Dim[3]*NonspatialDimensionsNII(lHdr);
- if lImgSamples < 1 then
- exit;
- case lHdr.datatype of
- kDT_SIGNED_SHORT: begin
- l16i := SmallIntP(@lImgBuffer^[lImgOffset+1]);
- for lInc := 1 to lImgSamples do
- l16i^[lInc] := Swap(l16i^[lInc]);
- end; //l16i
- kDT_SIGNED_INT,kDT_FLOAT: begin
- //note: for the purposes of byte swapping, floats and long ints are the same
- l32i := LongIntP(@lImgBuffer^[lImgOffset+1]);
- for lInc := 1 to lImgSamples do
- Swap4(l32i^[lInc]);
- end;//32i
- (*kDT_FLOAT: begin
- l32f := SingleP(@lImgBuffer^[lImgOffset+1]);
- for lInc := 1 to lImgSamples do
- pswap4r(l32f^[lInc]); //faster as procedure than function see www.optimalcode.com
- end; //32f*)
- end; //case
- lByteSwap := false;
-end;
procedure NIFTIhdr_SwapBytes (var lAHdr: TNIFTIhdr ); //Swap Byte order for the Analyze type
var
@@ -158,7 +122,7 @@ procedure Uint16 (var lvBuffer: bytep; lVolOffset: integer; var lInHdr: TNIFTIh
// 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;
+ lmax,lv,lnv: integer;
lTempB: ByteP;
l16ui : WordP;
//l16i: SmallIntP;
@@ -234,33 +198,41 @@ end; //Uint16
function getPigzNameWithPath: string;
//returns path to pigz executable, e.g. '/Users/rorden/downloads/pigz-master/pigz';
var
- temp, exename: string;
+ i: integer;
+ exename: string;
+ {$IFDEF DARWIN} temp: string;{$ENDIF}
begin
{$IFDEF ENDIAN_BIG}
Msg('pigz not available with PowerPC computers');
result := '';
exit;
{$ENDIF}
+ for i := 1 to 2 do begin
{$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}
+ if i = 1 then
+ exename := 'pigz'
+ else
+ exename := 'pigz_mricron';
+ {$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';
+ if i = 1 then
+ exename := 'pigz.exe'
+ else
+ exename := 'pigz_mricron.exe';
{$ENDIF}
- //result := ExtractFilePath(Application.ExeName)+'pigz';
result := ExtractFilePath( paramstr(0))+exename;
if fileexists(result) then exit;
{$IFDEF DARWIN}
@@ -268,6 +240,11 @@ begin
result := ExtractFilePath(paramstr(0));
result := LeftStr(result, Pos((ExtractFileName(paramstr(0))+'.app'), result)-1)+exename;
if fileexists(result) then exit;
+ {$ENDIF}
+ end; //for i:= 1 to 2
+
+
+ {$IFDEF DARWIN}
{$IFDEF GUI}
dcmMsg('File compression error: pigz does not exist in you path or '+result+' or '+temp);
{$ELSE}
@@ -279,7 +256,6 @@ begin
{$ELSE}
dcmMsg('File compression error: to use "pigz" place it in the same folder as '+ paramstr(0));
{$ENDIF}
-
{$ENDIF}
result := '';
end;
@@ -351,7 +327,7 @@ begin
//Acmd := Acmd +' -v -k';//verbose, keep files
if abs(processes) > 1 then
Acmd := Acmd + ' -p '+inttostr( abs(processes) );
- Acmd := Acmd +' '+lImgName;
+ Acmd := Acmd +' "'+lImgName+'"';
dcmMsg('External compression: '+AppName+' '+Acmd);
Acmd := AppName+' '+Acmd;
ExecNewProcess(AppName, ACmd, (processes > 0));
@@ -359,7 +335,7 @@ end;
{$ENDIF}
-function SaveNIfTICore (var lOutImgName: string; var lvBuffer: bytep; lVolOffset: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs; var lByteSwap: boolean): string;
+function SaveNIfTICore (var lOutImgName: string; var lvBuffer: bytep; lVolOffset: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs): 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
@@ -369,7 +345,9 @@ var
lNoGZName,lHdrName,lImgName: string;
l3dHdr,lOutHdr : TNIFTIHdr;
lHdrBupRA: bytep;
+ lByteSwap: boolean;
begin
+ lByteSwap := false;
lNoGZName := (lOutImgName);
StripGZExt(lNoGZName); //we want to convert filename.nii.gz -> filename.hdr not -> filename.nii.hdr
StripNIIVOIExt(lNoGZName);//we want to convert filename.nii.voi to filename.hdr
@@ -385,7 +363,7 @@ begin
for lVol := 1 to lInHdr.dim[4] do begin
//1st - save header
lHdrName := AddFileNum(lVol,lInHdr.dim[4],lNoGZName);
- result := SaveNIfTICore (lHdrName, lvBuffer, lVolStart, l3dHdr, lPref,lByteswap);
+ result := SaveNIfTICore (lHdrName, lvBuffer, lVolStart, l3dHdr, lPref);
lVolStart := lVolStart + lVolBytes;
//SaveNiftiCore new filename, new offset
end; //for each vol
@@ -462,7 +440,7 @@ begin
result := lImgName;
end;
-function SaveNIfTICoreCrop (var lOutImgName: string; var lvBuffer: bytep; lVolOffset,lStartClip,lEndClip: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs; var lByteSwap: boolean): string;
+function SaveNIfTICoreCrop (var lOutImgName: string; var lvBuffer: bytep; lVolOffset,lStartClip,lEndClip: integer; var lInHdr: TNIFTIhdr; var lPrefs: TPrefs): string;
var
lVolStart,lVolBytes: integer;
lClipName: string;
@@ -480,7 +458,7 @@ begin
lClipHdr.dim[4] := lInHdr.dim[4]-lStartClip-lEndClip;
lVolStart := lVolOffset + (lStartClip*lVolBytes);
lClipName := ChangeFilePrefix (lOutImgName,'x');
- result := SaveNIfTICore (lClipName, lvBuffer, lVolStart, lClipHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lClipName, lvBuffer, lVolStart, lClipHdr, lPrefs);
end;
function SubBound (lVal,lMin: integer): integer;
@@ -496,51 +474,90 @@ begin
result := SubBound(lA.dim[4],1)*SubBound(lA.dim[5],1)*SubBound(lA.dim[6],1)*SubBound(lA.dim[7],1);
end;
-function NIFTIhdr_LoadImgRaw (LoadHdr: boolean; var lFilename: string; var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lByteSwap: boolean): boolean;
+procedure NIFTIhdr_UnswapImgX (var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lByteSwap: boolean); //ensures image data is in native space
+//returns data in native endian
+//sets 'ByteSwap' flag to false. E.G. a big-endian image will be saved as little-endian on little endian machines
+var
+ lInc,lImgSamples : integer;
+ //2f : SingleP;
+ l32i : LongIntP;
+ l16i : SmallIntP;
+begin
+ if not lByteSwap then exit;
+ case lHdr.datatype of
+ kDT_UNSIGNED_CHAR : begin
+ lByteSwap := false; //single byte data - no need to byte swap...
+ exit;
+ end;
+ kDT_SIGNED_SHORT,kDT_SIGNED_INT,kDT_FLOAT: ;//supported format
+ else begin
+ dcmMsg('niftiutil UnSwapImg error: datatype not supported.');
+ exit;
+ end;
+ end; //case
+ lImgSamples := lHdr.Dim[1] *lHdr.Dim[2]*lHdr.Dim[3]*NonspatialDimensionsNII(lHdr);
+ if lImgSamples < 1 then
+ exit;
+ case lHdr.datatype of
+ kDT_SIGNED_SHORT: begin
+ l16i := SmallIntP(@lImgBuffer^[lImgOffset+1]);
+ for lInc := 1 to lImgSamples do
+ l16i^[lInc] := Swap(l16i^[lInc]);
+ end; //l16i
+ kDT_SIGNED_INT,kDT_FLOAT: begin
+ //note: for the purposes of byte swapping, floats and long ints are the same
+ l32i := LongIntP(@lImgBuffer^[lImgOffset+1]);
+ for lInc := 1 to lImgSamples do
+ Swap4(l32i^[lInc]);
+ end;//32i
+ (*kDT_FLOAT: begin
+ l32f := SingleP(@lImgBuffer^[lImgOffset+1]);
+ for lInc := 1 to lImgSamples do
+ pswap4r(l32f^[lInc]); //faster as procedure than function see www.optimalcode.com
+ end; //32f*)
+ end; //case
+ lByteSwap := false;
+end;
+
+function NIFTIhdr_LoadImgRaw (LoadHdr: boolean; var lFilename: string; var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lOpts: TNIIopts ): boolean;
//ImgBuffer always offset by kNIIImgOffset- this allows rapid nii.gz creation
//loads img to byteP - if this returns successfully you must freemem(lImgBuffer)
var
- lExt,lImgName: string;
lVol,lFileBytes,lImgBytes: integer;
lBuf: ByteP;
- lGZin: boolean;
lInF: File;
begin
result := false;
if loadHdr then begin
- if not NIFTIhdr_LoadHdr (lFilename, lHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lHdr, lOpts) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
end;//if we load the header from disk...
- lExt := UpCaseExt(lFilename);
- lGZin := ExtGZ(lFilename);
- if lExt = '.VOI' then
- lGZin := true;
lImgOffset := kNIIImgOffset;// (=352) bytes for creating .nii.gz files
lVol := NonspatialDimensionsNII(lHdr);//lHdr.dim[4];
if lVol < 1 then
lVol := 1;
lImgBytes := lHdr.dim[1]*lHdr.dim[2]*lHdr.dim[3]*lVol*(lHdr.bitpix div 8);
- if lExt ='.HDR' then
- lImgName := changefileext(lFilename,'.img')
- else
- lImgName := lFilename;
- if not fileexists(lImgName) then begin
- dcmMsg('LoadImg Error: Unable to find '+lImgName);
+ if not fileexists(lOpts.ImgName) then begin
+ dcmMsg('LoadImg Error: Unable to find '+lOpts.ImgName);
exit;
end;
- if (not lGZin) and (FSize (lImgName) < ( lImgBytes+round(lHdr.vox_offset))) then begin
- dcmMsg('LoadImg Error: File smaller than expected '+lImgName);
+ if (lOpts.gzBytes = K_gzBytes_headerAndImageUncompressed) and (FSize (lOpts.ImgName) < ( lImgBytes+round(lHdr.vox_offset))) then begin
+ dcmMsg('LoadImg Error: File smaller than expected '+lOpts.ImgName);
exit;
end;
lFileBytes := lImgBytes+ lImgOffset;
GetMem(lImgBuffer,lFileBytes);
- if lGZin then begin
+ if (lOpts.gzBytes <> K_gzBytes_headerAndImageUncompressed) then begin
lBuf := @lImgBuffer^[lImgOffset+1];
- UnGZip (lImgName,lBuf, round(lHdr.vox_offset),lImgBytes);
+
+ if lOpts.gzBytes = K_gzBytes_headerAndImageCompressed then
+ UnGZip (lOpts.ImgName,lBuf, round(lHdr.vox_offset),lImgBytes)
+ else
+ UnGZip2 (lOpts.ImgName,lBuf, 0,lImgBytes, round(lHdr.vox_offset));
end else begin
- AssignFile(lInF, lImgName);
+ AssignFile(lInF, lOpts.ImgName);
Reset(lInF,1);
Seek(lInF,round(lHdr.vox_offset));
Filemode := 0; //ReadONly
@@ -548,12 +565,13 @@ begin
CloseFile(lInF);
end;
Filemode := 2; //Read/Write
+ NIFTIhdr_UnswapImgX(lHdr, lImgBuffer, lImgOffset,lOpts.bs);
result := true;
end; //NIFTIhdr_LoadImgRaw
-function NIFTIhdr_LoadImg (var lFilename: string; var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lByteSwap: boolean): boolean;
+function NIFTIhdr_LoadImg (var lFilename: string; var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lOpts: TNIIOpts): boolean;
begin
- result := NIFTIhdr_LoadImgRaw (true, lFilename, lHdr, lImgBuffer, lImgOffset, lByteSwap);
+ result := NIFTIhdr_LoadImgRaw (true, lFilename, lHdr, lImgBuffer, lImgOffset, lOpts);
end;
(*function NIFTIhdr_LoadImg (var lFilename: string; var lHdr: TNIFTIHdr; var lImgBuffer: byteP; var lImgOffset: integer; var lByteSwap: boolean): boolean;
//ImgBuffer always offset by kNIIImgOffset- this allows rapid nii.gz creation
@@ -623,15 +641,15 @@ var
lImgBuffer: byteP;
lImgOffset: integer;
lOutImgName: string;
- lByteSwap: boolean;
+ lOpts: TNIIOpts;
begin
result := false;
- if not NIFTIhdr_LoadImg (lHdrName, lHdr, lImgBuffer, lImgOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lHdrName, lHdr, lImgBuffer, lImgOffset,lOpts) then exit;
dcmMsg('Changing subformat of '+lHdrName);
lOutImgName := ChangeFilePrefix (lHdrName,'f');
if lPrefs.CustomRename then
CustomFilename(lOutImgName);
- if SaveNIfTICore (lOutImgName, lImgBuffer, lImgOffset+1, lHdr, lPrefs,lByteSwap) ='' then exit;
+ if SaveNIfTICore (lOutImgName, lImgBuffer, lImgOffset+1, lHdr, lPrefs) ='' then exit;
Freemem(lImgBuffer);
result := true; //11/2007
ExitCode := 0;
@@ -646,17 +664,27 @@ begin
lZmm := (lHdr.srow_z[0]*lXslice)+ (lHdr.srow_z[1]*lYslice)+(lHdr.srow_z[2]*lzslice);
end;
-
-
-function NIFTIhdr_LoadHdr (var lFilename: string; var lHdr: TNIFTIHdr; var lByteSwap: boolean): boolean;
+function NIFTIhdr_LoadHdr (var lFilename: string; var lHdr: TNIFTIHdr; var lOpts: TNIIOpts): 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,lFileSz: Longint;
+ lForeignSwapEndian: boolean;
+ lExt: string; //1494
begin
Result := false; //assume error
+ lOpts.gzBytes := K_gzBytes_headerAndImageUncompressed;
+ lForeignSwapEndian := false;
if lFilename = '' then exit;
+ lOpts.Imgname := lFilename;
lExt := UpCaseExt(lFilename);
if lExt = '.IMG' then
- lFilename := changeFileExt(lFilename,'.hdr');
+ lFilename := changeFileExt(lFilename,'.hdr');
+ if (lExt = '.BRIK') or (lExt = '.BRIK.GZ') then
+ lFilename := changeFileExt(lFilename,'.HEAD');
+ lExt := UpCaseExt(lFilename);
+ if lExt = '.HDR' then
+ lOpts.Imgname := changeFileExt(lFilename,'.img');
lHdrSz := sizeof(TniftiHdr);
lFileSz := FSize (lFilename);
if lFileSz = 0 then begin
@@ -668,10 +696,15 @@ begin
exit;
end;
FileMode := 0; { Set file access to read only }
- if (lExt = '.NII.GZ') or (lExt = '.VOI') then begin//1388
- lBuff := @lHdr;
- UnGZip(lFileName,lBuff,0,lHdrSz); //1388
- end else begin //if gzip
+ if (lExt = '.MGH') or (lExt = '.MGZ') or (lExt = '.MHD') or (lExt = '.MHA') or (lExt = '.NRRD') or (lExt = '.NHDR') or (lExt = '.HEAD') then begin
+ lOpts.Imgname := lFilename; //will change header name to image name if required
+ result := readForeignHeader( lOpts.Imgname, lHdr,lOpts.gzBytes, lForeignSwapEndian); //we currently ignore result!
+ end else begin //native NIfTI
+ if (lExt = '.NII.GZ') or (lExt = '.VOI') then begin//1388
+ lBuff := @lHdr;
+ UnGZip(lFileName,lBuff,0,lHdrSz); //1388
+ lOpts.gzBytes := K_gzBytes_headerAndImageCompressed;
+ end else begin //if gzip
{$I-}
AssignFile(lHdrFile, lFileName);
FileMode := 0; { Set file access to read only }
@@ -685,15 +718,16 @@ begin
BlockRead(lHdrFile, lHdr, lHdrSz);
CloseFile(lHdrFile);
end;
+ end;//nifti
FileMode := 2;
if (IOResult <> 0) then exit;
lReportedSz := lHdr.HdrSz;
lSwappedReportedSz := lReportedSz;
swap4(lSwappedReportedSz);
if lReportedSz = lHdrSz then begin
- lByteSwap := false;
+ lOpts.bs := false;
end else if lSwappedReportedSz = lHdrSz then begin
- lByteSwap := true;
+ lOpts.bs := true;
NIFTIhdr_SwapBytes (lHdr);
end else begin
dcmMsg('Warning: the header file is not in NIfTi format [the first 4 bytes do not have the value 348]. Assuming big-endian data.');
@@ -705,6 +739,9 @@ begin
end;
if lHdr.Dim[4] < 1 then
lHdr.Dim[4] := 1;
+ if lForeignSwapEndian then
+ lOpts.bs := true;
+
result := true;
end; //func Analyzehdr_LoadHdr
@@ -918,7 +955,7 @@ end; //proc NIFTIhdr_ClearHdr
procedure DICOM2AnzHdr (var lBHdr: TNIFTIhdr; lAnonymize: boolean; var lFilename: string; var lDICOMdata: DicomData);
var lInc,lLen: integer;
- lStr,lFilenameWOPath: string;
+ lStr: string;
begin
NIFTIhdr_ClearHdr(lBHdr);
if not lAnonymize then begin
@@ -937,11 +974,11 @@ if not lAnonymize then begin
lBHdr.patient_id[lInc] := lDicomData.PatientID[lInc]; *)
//next: put PatientName into Descrip array
- lLen := length(lDicomData.PatientName);
+ (*lLen := length(lDicomData.PatientName);
if lLen > 80 then lLen := 80; //80=size of descrip array
if lLen > 0 then
for lInc := 1 to lLen do
- lBHdr.descrip[lInc] := lDicomData.PatientName[lInc];
+ lBHdr.descrip[lInc] := lDicomData.PatientName[lInc];*)
//next: put StudyDate into exp_date array
(* lLen := length(lDicomData.StudyDate);
if lLen > 10 then lLen := 10; //10=size of exp_date array
@@ -962,14 +999,18 @@ if not lAnonymize then begin
lBHdr.generated[lInc] := lDicomData.modality[lInc];*)
end; //Not anonymized
//next: put TR into db_Name array
- lStr := '?TR:'+floattostrf(lDicomData.TR,ffFixed,8,3)+' TE:'+floattostrf(lDicomData.TE,ffFixed,8,2);
+ lStr := 'TE='+floattostr(lDicomData.TE) +';sec='+realtostr(lDicomData.SecSinceMidnight,4);
+ if not lAnonymize then
+ lStr := lStr+';name='+lDicomData.PatientName[lInc] ;
lLen := length(lStr);
- if lLen > 18 then lLen := 18; //10=size of generated array
- if lLen > 0 then
- for lInc := 1 to lLen do
- lBHdr.db_name[lInc] := lStr[lInc];
-
-
+ if lLen > 80 then lLen := 80;
+ for lInc := 1 to lLen do
+ lBHdr.descrip[lInc] := lStr[lInc];{80 spaces}
+ lStr := lDicomData.ImageComments;
+ lLen := length(lStr);
+ if lLen > 24 then lLen := 24; //10=size of generated array
+ for lInc := 1 to lLen do
+ lBHdr.aux_file[lInc] := lStr[lInc];//up to 24
if lDICOMdata.XYZdim[4] > 1 then
lBHdr.Dim[0] := 4 //4D Data June 2006
@@ -1023,10 +1064,10 @@ var
l16is : SmallIntP;
l8is,lSrcBuffer,lBuffUnaligned,lBuffAligned: bytep;
lSrcHdr,lDestHdr: TNIFTIhdr;
- lByteSwap: boolean;
+ lOpts: TNIIOpts;
begin
result := '';
- if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lByteSwap) then exit;
+ if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lOpts) then exit;
case lSrcHdr.datatype of
kDT_UNSIGNED_CHAR : ;
kDT_SIGNED_SHORT: ;
@@ -1047,8 +1088,7 @@ begin
lVol := lDestHdr.Dim[4];
lVox := lDestHdr.Dim[1]*lDestHdr.Dim[2]*lDestHdr.Dim[3]*lVol;
//load dataset
- if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap) then exit;
- NIFTIhdr_UnswapImg(lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap);//interpolation requires data is in native endian
+ if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lOpts) then exit;
l8is := (@lSrcBuffer^[lSrcOffset+1]);
GetMem(lBuffUnaligned ,(4*lVox) + 16+kNIIImgOffset);
{$IFDEF FPC}
@@ -1073,7 +1113,7 @@ begin
for lPos := 1 to lVox do
l32f^[lPos] := l32is^[lPos];
end;
- result := SaveNIfTICore (lDestName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lDestName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs);
Freemem(lBuffUnaligned);
Freemem(lSrcBuffer);
end;
@@ -1114,11 +1154,11 @@ var
l16is : SmallIntP;
l8is,lSrcBuffer,lBuffUnaligned,lBuffAligned: bytep;
lSrcHdr,lDestHdr: TNIFTIhdr;
- lByteSwap: boolean;
+ lOpts: TNIIOpts;
lSumName: string;
begin
result := '';
- if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lByteSwap) then exit;
+ if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lOpts) then exit;
case lSrcHdr.datatype of
kDT_UNSIGNED_CHAR : ;
kDT_SIGNED_SHORT: ;
@@ -1136,8 +1176,7 @@ begin
lVol := lDestHdr.Dim[4];
lVox := lDestHdr.Dim[1]*lDestHdr.Dim[2]*lDestHdr.Dim[3]*lVol;
//load dataset
- if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap) then exit;
- NIFTIhdr_UnswapImg(lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap);//interpolation requires data is in native endian
+ if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lOPts) then exit;
l8is := (@lSrcBuffer^[lSrcOffset+1]);
GetMem(lBuffUnaligned ,(4*lVox) + 16+kNIIImgOffset);
{$IFDEF FPC}
@@ -1196,7 +1235,7 @@ begin
for lPos := 1 to lVox do
if l32f^[lPos] < kMin then
l32f^[lPos] := kMin; *)
- result := SaveNIfTICore (lDestName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lDestName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs);
//optional ... SumMap
if lVol > 1 then begin //for 4D data...
@@ -1210,7 +1249,7 @@ begin
end; //4D
lDestHdr.Dim[4] := 1;
lSumName := ChangeFilePrefix (lDestName,'sum');
- result := SaveNIfTICore (lSumName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lSumName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs);
//... end SumMap
Freemem(lBuffUnaligned);
Freemem(lSrcBuffer);
@@ -1227,11 +1266,11 @@ var
l16is : SmallIntP;
l8is,lSrcBuffer,lBuffUnaligned,lBuffAligned: bytep;
lSrcHdr,lDestHdr: TNIFTIhdr;
- lByteSwap: boolean;
+ lOpts: TNIIOpts;
//lSumName: string;
begin
result := '';
- if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lByteSwap) then exit;
+ if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lOpts) then exit;
case lSrcHdr.datatype of
kDT_UNSIGNED_CHAR,kDT_SIGNED_SHORT,kDT_SIGNED_INT,kDT_FLOAT: ;
else begin
@@ -1245,8 +1284,7 @@ begin
lDestHdr.Dim[4] := 1;
lVox := lDestHdr.Dim[1]*lDestHdr.Dim[2]*lDestHdr.Dim[3];
//load dataset
- if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap) then exit;
- NIFTIhdr_UnswapImg(lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap);//interpolation requires data is in native endian
+ if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lOpts) then exit;
l8is := (@lSrcBuffer^[lSrcOffset+1]);
lnVol := NonspatialDimensionsNII(lSrcHdr);
if lnVol > lTissueTypes2Average then
@@ -1283,7 +1321,7 @@ begin
for lPos := 1 to lVox do
l32f^[lPos] := l32f^[lPos]+l32fs^[lPos+(lVol*lVox)];
end;
- result := SaveNIfTICore (lDestName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lDestName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs);
lDestHdr.Dim[4] := 1;
//result := SaveNIfTICore (lSumName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs,lByteSwap);
@@ -1321,12 +1359,12 @@ var
lVolOffset,lSliceBytes,lV,lLoOffset,lHiOffset,lVol,lVox: integer;
l8iHi,l8iLo,lLoBuffer,lHiBuffer {,lBuffUnaligned,lBuffAligned}: bytep;
lLoHdr,lHiHdr: TNIFTIhdr;
- lByteSwapLo,lByteSwapHi: boolean;
+ lOptsLo,lOptsHi: TNIIOpts;
lBPP: integer;
begin
result := '';
- if not NIFTIhdr_LoadHdr (lLowSliceName, lLoHdr, lByteSwapLo) then exit;
- if not NIFTIhdr_LoadHdr (lHighSliceName, lHiHdr, lByteSwapHi) then exit;
+ if not NIFTIhdr_LoadHdr (lLowSliceName, lLoHdr, lOptsLo) then exit;
+ if not NIFTIhdr_LoadHdr (lHighSliceName, lHiHdr, lOptsHi) then exit;
if lNumberofLowSlicesToCopy < 1 then
exit;
if not SameHdrDim(lLoHdr, lHiHdr,true,true) then
@@ -1345,11 +1383,8 @@ begin
lVol := lHiHdr.Dim[4];
lSliceBytes:= lHiHdr.Dim[1]*lHiHdr.Dim[2] * lBPP;
//load dataset
- if not NIFTIhdr_LoadImg (lLowSliceName, lLoHdr, lLoBuffer, lLoOffset,lByteSwapLo) then exit;
- NIFTIhdr_UnswapImg(lLoHdr, lLoBuffer, lLoOffset,lByteSwapLo);//interpolation requires data is in native endian
- if not NIFTIhdr_loadImg (lHighSliceName, lhiHdr, lhiBuffer, lhiOffset,lByteSwaphi) then exit;
- NIFTIhdr_UnswapImg(lhiHdr, lhiBuffer, lhiOffset,lByteSwaphi);//interpolation requires data is in native endian
-
+ if not NIFTIhdr_LoadImg (lLowSliceName, lLoHdr, lLoBuffer, lLoOffset,lOptsLo) then exit;
+ if not NIFTIhdr_loadImg (lHighSliceName, lhiHdr, lhiBuffer, lhiOffset,lOptsHi) then exit;
l8iLo := (@lLoBuffer^[lLoOffset+1]);
l8iHi := (@lHiBuffer^[lHiOffset+1]);
@@ -1358,7 +1393,7 @@ begin
for lVox := 1 to (lSliceBytes*lNumberofLowSlicesToCopy) do
l8iHi^[lVox+lVolOffset] := l8iLo^[lVox+lVolOffset];
end;
- result := SaveNIfTICore (lDestName, lhiBuffer, kNIIImgOffset+1, lHiHdr, lPrefs,lByteSwapHi);
+ result := SaveNIfTICore (lDestName, lhiBuffer, kNIIImgOffset+1, lHiHdr, lPrefs);
Freemem(lhiBuffer);
Freemem(lloBuffer);
end;
@@ -1369,12 +1404,12 @@ var
lVolOffset,lVolBytes,l3DOffset,l4DOffset,lVox: integer;
l8i4D,l8i3D,l3DBuffer,l4DBuffer {,lBuffUnaligned,lBuffAligned}: bytep;
l3DHdr,l4DHdr: TNIFTIhdr;
- lByteSwap3D,lByteSwap4D: boolean;
+ lOpts3D,lOpts4D: TNIIOpts;
lBPP: integer;
begin
result := '';
- if not NIFTIhdr_LoadHdr (l3DSliceName, l3DHdr, lByteSwap3D) then exit;
- if not NIFTIhdr_LoadHdr (l4DSliceName, l4DHdr, lByteSwap4D) then exit;
+ if not NIFTIhdr_LoadHdr (l3DSliceName, l3DHdr, lOpts3D) then exit;
+ if not NIFTIhdr_LoadHdr (l4DSliceName, l4DHdr, lOpts4D) then exit;
if lVol2Copy < 1 then
exit;
if not SameHdrDim(l3DHdr, l4DHdr,false,true) then
@@ -1393,27 +1428,24 @@ begin
// lVol := l4DHdr.Dim[4];
lVolBytes:= l4DHdr.Dim[1]*l4DHdr.Dim[2]*l4DHdr.Dim[3]* lBPP;
//load dataset
- if not NIFTIhdr_LoadImg (l3DSliceName, l3DHdr, l3DBuffer, l3DOffset,lByteSwap3D) then exit;
- NIFTIhdr_UnswapImg(l3DHdr, l3DBuffer, l3DOffset,lByteSwap3D);//interpolation requires data is in native endian
- if not NIFTIhdr_loadImg (l4DSliceName, l4DHdr, l4DBuffer, l4DOffset,lByteSwap4D) then exit;
- NIFTIhdr_UnswapImg(l4DHdr, l4DBuffer, l4DOffset,lByteSwap4D);//interpolation requires data is in native endian
-
+ if not NIFTIhdr_LoadImg (l3DSliceName, l3DHdr, l3DBuffer, l3DOffset,lOpts3D) then exit;
+ if not NIFTIhdr_loadImg (l4DSliceName, l4DHdr, l4DBuffer, l4DOffset,lOpts4D) then exit;
l8i3D := (@l3DBuffer^[l3DOffset+1]);
l8i4D := (@l4DBuffer^[l4DOffset+1]);
lVolOffset := (lVol2Copy - 1) * (lVolBytes);
for lVox := 1 to (lVolBytes) do
l8i4D^[lVox+lVolOffset] := l8i3D^[lVox];
- result := SaveNIfTICore (lDestName, l4DBuffer, kNIIImgOffset+1, l4DHdr, lPrefs,lByteSwap4D);
+ result := SaveNIfTICore (lDestName, l4DBuffer, kNIIImgOffset+1, l4DHdr, lPrefs);
Freemem(l4DBuffer);
Freemem(l3DBuffer);
end;
-function NIFTIhdr_LoadImg8bit (var lSrcName: string; var lSrcHdr: TNIFTIHdr; var lSrcBuffer: bytep; var lSrcOffset: integer; var lByteSwap: boolean): boolean;
+function NIFTIhdr_LoadImg8bit (var lSrcName: string; var lSrcHdr: TNIFTIHdr; var lSrcBuffer: bytep; var lSrcOffset: integer; var lOPts: TNIIOPts): boolean;
begin
result := false;
- if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lOpts) then exit;
if lSrcHdr.datatype <> kDT_UNSIGNED_CHAR then begin
dcmMsg('Only able to read 8-bit data.');
exit;
@@ -1426,22 +1458,20 @@ function MaskImages(lMaskName: string; lFiles: TStrings; lPrefs: TPrefs; lVol: i
var
lFileOffset,lMaskOffset,lInc,lVox,lPos,lOK: integer;
lMaskHdr,lFileHdr: TNIFTIHdr;
- lMaskSwap,lFileSwap: boolean;
+ lMaskOpts,lFileOpts: TNIIOpts;
lFilename: string;
lMaskBuffer,lFileBuffer,l8if: bytep;
l32fm,l32fmean, l32fmeanpre: singlep;
begin
result := '';
- if not NIFTIhdr_LoadHdr (lMaskName, lMaskHdr, lMaskSwap) then exit;
+ if not NIFTIhdr_LoadHdr (lMaskName, lMaskHdr, lMaskOpts) then exit;
if lMaskHdr.datatype <> kDT_FLOAT then begin
dcmMsg('This function only works with 32-bit float data.');
exit;
end;
lVox := lMaskHdr.Dim[1]*lMaskHdr.Dim[2]*lMaskHdr.Dim[3];
if lFiles.Count < 1 then exit;
- if not NIFTIhdr_LoadImg (lMaskName, lMaskHdr, lMaskBuffer, lMaskOffset,lMaskSwap) then exit;
- NIFTIhdr_UnswapImg(lMaskHdr, lMaskBuffer, lMaskOffset,lMaskSwap);//interpolation requires data is in native endian
- //fx( ((lVol-1)* (lVox*4) ) );
+ if not NIFTIhdr_LoadImg (lMaskName, lMaskHdr, lMaskBuffer, lMaskOffset,lMaskOpts) then exit;
l32fm := SingleP(@lMaskBuffer^[lMaskOffset+1+ ((lVol-1)* (lVox*4) )]);
//l32fo := SingleP(@lBuffAligned^[kNIIImgOffset+lPos] );
GetMem(l32fmean ,(4*lVox));
@@ -1453,7 +1483,7 @@ begin
lOK := 0;
for lInc := 1 to lFiles.Count do begin
lFilename := lFiles.Strings[lInc-1];
- if not NIFTIhdr_LoadImg8bit (lFileName, lFileHdr, lFilebuffer, lFileOffset,lFileSwap) then begin
+ if not NIFTIhdr_LoadImg8bit (lFileName, lFileHdr, lFilebuffer, lFileOffset,lFileOpts) then begin
dcmMsg('Serious error reading '+lFilename);
exit;
end;
@@ -1471,7 +1501,7 @@ begin
end;
lFilename := ChangeFilePrefix (lFilename,'z');
if lSaveThresh then
- result := SaveNIfTICore (lFilename, lFileBuffer, lFileOffset+1, lFileHdr, lPrefs,lFileSwap);
+ result := SaveNIfTICore (lFilename, lFileBuffer, lFileOffset+1, lFileHdr, lPrefs);
inc(lOK);
end;
Freemem(lFilebuffer);
@@ -1485,11 +1515,11 @@ begin
for lPos := 1 to lVox do
l32fm^[lPos] := l32fmean^[lPos]/lOK;
lFilename := ChangeFilePrefix (lMaskName,'mean'+inttostr(lVol));
- result := SaveNIfTICore (lFilename, lMaskBuffer, lMaskOffset+1, lMaskHdr, lPrefs,lMaskSwap);
+ result := SaveNIfTICore (lFilename, lMaskBuffer, lMaskOffset+1, lMaskHdr, lPrefs);
for lPos := 1 to lVox do
l32fm^[lPos] := l32fmeanpre^[lPos]/lOK;
lFilename := ChangeFilePrefix (lMaskName,'meanpre'+inttostr(lVol));
- result := SaveNIfTICore (lFilename, lMaskBuffer, lMaskOffset+1, lMaskHdr, lPrefs,lMaskSwap);
+ result := SaveNIfTICore (lFilename, lMaskBuffer, lMaskOffset+1, lMaskHdr, lPrefs);
end;
Freemem(l32fmean);
Freemem(lMaskBuffer);
@@ -1522,7 +1552,7 @@ var
lHname : array [1..kMaps] of string;
lH: array [1..kMaps] of TNIFTIHdr;
lMax,lMaxV,lV,lVox,lMap,lCharPos: integer;
- lHSwap: boolean;
+ lHOpts: TNIIOpts;
//lFilename: string;
lHBuffer,lH8i: array [1..kMaps] of bytep;
lHOffset: array [1..kMaps] of integer;
@@ -1544,7 +1574,7 @@ begin
end;
for lMap := 1 to kMaps do begin
- if not NIFTIhdr_LoadImg8bit (lHname[lMap], lH[lMap], lHBuffer[lMap], lHOffset[lMap],lHSwap) then begin
+ if not NIFTIhdr_LoadImg8bit (lHname[lMap], lH[lMap], lHBuffer[lMap], lHOffset[lMap],lHOpts) then begin
dcmMsg('Serious error reading '+lHname[lMap]);
exit;
end;
@@ -1574,7 +1604,7 @@ begin
lH[1].scl_slope := 1;
lH[1].scl_inter := 0;
lHname[1][lCharPos] := 'b';
- result := SaveNIfTICore (lHname[1], lHBuffer[1], lHOffset[1]+1, lH[1], lPrefs,lHSwap);
+ result := SaveNIfTICore (lHname[1], lHBuffer[1], lHOffset[1]+1, lH[1], lPrefs);
for lMap := 1 to kMaps do
Freemem(lHBuffer[lMap]);
end;
@@ -1634,10 +1664,10 @@ var
l16is : SmallIntP;
l8is,lSrcBuffer: bytep;
lSrcOffset,lVox,lPos: integer;
- lByteSwap: boolean;
+ lOpts: TNIIOpts;
begin
result := false;
- if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lByteSwap) then exit;
+ if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lOpts) then exit;
case lSrcHdr.datatype of
kDT_UNSIGNED_CHAR : ;
kDT_SIGNED_SHORT: ;
@@ -1650,8 +1680,7 @@ begin
end; //case
lVox := lSrcHdr.Dim[1]*lSrcHdr.Dim[2]*lSrcHdr.Dim[3];
//load dataset
- if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap) then exit;
- NIFTIhdr_UnswapImg(lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap);//interpolation requires data is in native endian
+ if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lOpts) then exit;
l8is := (@lSrcBuffer^[lSrcOffset+1]);
GetMem(l32f ,lVox * sizeof(single));
//lPos := 1;
@@ -1689,7 +1718,7 @@ label
var
lH,lT: TNIFTIHdr;
lV,lVox,lHOffset: integer;
- lHSwap: boolean;
+ lHOpts: TNIIOpts;
l32fs : SingleP;
l8is,lHBuffer: bytep;
lOutname: string;
@@ -1705,7 +1734,7 @@ begin
exit;
end;
//if not NIFTIhdr_LoadImgAs32float (lsource, lH, lHBuffer, lHOffset,lHSwap) then begin
- if not NIFTIhdr_LoadImg8bit (lsource, lH, lHBuffer, lHOffset,lHSwap) then begin
+ if not NIFTIhdr_LoadImg8bit (lsource, lH, lHBuffer, lHOffset,lHOpts) then begin
dcmMsg('Serious error reading '+lsource);
exit;
end;
@@ -1728,7 +1757,7 @@ begin
lH.scl_inter := 0;
lOutname := ChangeFilePrefix(lsource,'m');
dcmMsg(lsource +' masked with '+ltemplate +' = '+lOutname);
- result := SaveNIfTICore (loutname, lHBuffer, lHOffset+1, lH, lPrefs,lHSwap);
+ result := SaveNIfTICore (loutname, lHBuffer, lHOffset+1, lH, lPrefs);
666:
Freemem(l32fs);
Freemem(lHBuffer);
diff --git a/dcm2nii/nii_3dto4d.pas b/dcm2nii/nii_3dto4d.pas
index 0e2e59f..8ff4074 100755
--- 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,dialogs_msg;
+ SysUtils,define_types,dicomtypes,niftiutil,prefs,classes,dialogs_msg, nifti_types;
function Stack3Dto4D(var lStr: TStringList; lOverwrite: boolean; lPrefs: TPrefs): boolean;
function ExtractNIFTIHdrs(var lStr: TStringList): boolean;
@@ -102,16 +102,16 @@ var
lHdr : TNIFTIhdr;
lByteSwap: boolean;
lVol,lnVol : integer;
+ lO: TNIIOpts;
begin
result := false;
lnVol := lStr.Count;
if lnVol < 1 then
exit;
SortStrPadded(lStr);
- NIFTIhdr_LoadHdr (lHdrName, lHdr,lByteSwap);
for lVol := 1 to lnVol do begin
lHdrName := lStr[lVol-1];
- if not NIFTIhdr_LoadHdr (lHdrName, lHdr,lByteSwap) then
+ if not NIFTIhdr_LoadHdr (lHdrName, lHdr,lO) then
dcmMsg('Unable to find '+lHdrName)
else
dcmMsg(NIIstr(lHdrName,lHdr));
@@ -129,7 +129,7 @@ var
lInOffset,lnVol,l4DVolBytes,l3DVolBytes,lIn3DBytes,l4DBytes,lVol,lInPos,lOutPos,lSlice: integer;
lHdrName,lOutImgName: string;
lHdr1,lHdr2,lOutHdr : TNIFTIhdr;
- lByteSwap: boolean;
+ lO: TNIIOpts;
lPrefs4D: TPrefs;
begin
result := false;
@@ -140,10 +140,10 @@ begin
end;
SortStrPadded(lStr);
lHdrName := lStr[0];
- NIFTIhdr_LoadHdr (lHdrName, lHdr1,lByteSwap);
+ NIFTIhdr_LoadHdr (lHdrName, lHdr1,lO);
for lVol := 1 to lnVol do begin
lHdrName := lStr[lVol-1];
- if not NIFTIhdr_LoadHdr (lHdrName, lHdr2,lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lHdrName, lHdr2,lO) then begin
dcmMsg('Stack 3D to 4D unable to find '+lHdrName);
exit;
end;
@@ -170,7 +170,7 @@ begin
for lVol := 1 to lnVol do begin
lHdrName := lStr[lVol-1];
dcmMsg( inttostr(lVol)+': '+lHdrName);
- if not NIFTIhdr_LoadImg (lHdrName, lHdr2, lIBuffer, lInOffset,lByteSwap) then begin
+ if not NIFTIhdr_LoadImg (lHdrName, lHdr2, lIBuffer, lInOffset,lO) then begin
dcmMsg('3D -> 4D error loading image '+lHdrName);
goto 123;
end;
@@ -181,7 +181,7 @@ begin
lPrefs4D := lPrefs;
lPrefs4D.fourD := true;
dcmMsg('4D image '+lOutImgName);
- if SaveNIfTICore (lOutImgName, lOutBuffer, kNIIImgOffset+1, lOutHdr, lPrefs4D,lByteSwap) = '' then begin
+ if SaveNIfTICore (lOutImgName, lOutBuffer, kNIIImgOffset+1, lOutHdr, lPrefs4D) = '' then begin
dcmMsg('3D -> 4D Error');
goto 123;
end;
diff --git a/dcm2nii/nii_4dto3d.pas b/dcm2nii/nii_4dto3d.pas
index dda2b03..e2ebf44 100755
--- a/dcm2nii/nii_4dto3d.pas
+++ b/dcm2nii/nii_4dto3d.pas
@@ -6,7 +6,7 @@ interface
uses
{$IFDEF FPC}gzio2,{$ENDIF}
- SysUtils,define_types,dicomtypes,niftiutil,prefs,nii_orient,nii_crop;
+ SysUtils,define_types,dicomtypes,niftiutil,prefs,nii_orient,nii_crop, nifti_types;
//function Convert4Dto3D(var lHdrName: string; var lHdr: TNIFTIhdr; lByteSwap,lSPM2in,lSingleNIIFile,lGZ :boolean ): boolean;
//function Clip4D(var lHdrName: string; var lHdr: TNIFTIhdr; lByteSwap,lSPM2in,lSingleNIIFile,lGZ,lOverwrite: boolean; lStartIn,lEndIn: integer ): string;
@@ -26,8 +26,9 @@ var
lExt,lOutname: string;
lHdr: TNIFTIhdr;
lFormat,lStartIn,lEndIn, lMinStartIn: integer;
- lByteSwap,lReorder: boolean;
+ lReorder: boolean;
lPref: TPrefs;
+ lO: TNIIOpts;
begin
lPref := lPrefs;
result := false;
@@ -35,7 +36,7 @@ begin
lEndIn := 0;
lReorder := false;
lExt := UpCaseExt(lFilename);
- if not NIFTIhdr_LoadHdr (lFilename, lHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
@@ -143,13 +144,13 @@ var
lImgBuffer: byteP;
lImgOffset: integer;
lOutImgName: string;
- lByteSwap: boolean;
+ lO: TNIIOpts;
begin
result := '';
- if not NIFTIhdr_LoadImg (lHdrName, lHdr, lImgBuffer, lImgOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lHdrName, lHdr, lImgBuffer, lImgOffset,lO) then exit;
dcmMsg('4D Clipping '+lHdrName);
lOutImgName := ChangeFilePrefix (lHdrName,'f');
- result := SaveNIfTICoreCrop (lOutImgName, lImgBuffer, lImgOffset+1,lStartIn,lEndIn, lHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICoreCrop (lOutImgName, lImgBuffer, lImgOffset+1,lStartIn,lEndIn, lHdr, lPrefs);
Freemem(lImgBuffer);
end;
@@ -160,10 +161,10 @@ var
lImgOffset,lSliceBytes,lIn3DBytes,l4DBytes,lVol,lInPos,lOutPos,lSlice: integer;
lOutImgName: string;
lOutHdr : TNIFTIhdr;
- lByteSwap: boolean;
+ lO: TNIIOpts;
begin
result := false;
- if not NIFTIhdr_LoadImg (lHdrName, lHdr, lInBuffer, lImgOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lHdrName, lHdr, lInBuffer, lImgOffset,lO) then exit;
if (lHdr.dim[4] < 2) or (lHdr.dim[3] < 2) then
exit;
if lOverwrite then
@@ -188,7 +189,7 @@ begin
end;//for lslice
end; //for lvol
dcmMsg(lOutImgName);
- if SaveNIfTICore (lOutImgName, lOutBuffer, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap) = '' then begin
+ if SaveNIfTICore (lOutImgName, lOutBuffer, kNIIImgOffset+1, lOutHdr, lPrefs) = '' then begin
dcmMsg('Reorder Error');
Freemem(lInBuffer);
Freemem(lOutBuffer);
diff --git a/dcm2nii/nii_asl.pas b/dcm2nii/nii_asl.pas
index 66113ec..8d029a0 100755
--- a/dcm2nii/nii_asl.pas
+++ b/dcm2nii/nii_asl.pas
@@ -7,7 +7,7 @@ interface
uses
//{$IFDEF FPC}gzio2,{$ENDIF}
- SysUtils,define_types,dicomtypes,niftiutil,prefs,dialogs_msg;
+ SysUtils,define_types,dicomtypes,niftiutil,prefs,dialogs_msg, nifti_types;
function ASL_subtract(var lHdrName: string; lOverwrite: boolean; lFunction : integer; lPrefs: TPrefs): boolean;
//ASL_subtract(var lHdrName: string; lOverwrite: boolean; lFunction : integer; lPrefs: TPrefs)
@@ -101,7 +101,7 @@ begin
result := true;
end;
//start 32-bit float versions
-function SaveMean32 (var lHdrName: string;var lInHdr: TNIFTIhdr; lBuffAligned: bytep;lImgBuffer : SingleP ;lPrefs: TPrefs; lByteSwap:boolean ): string;
+function SaveMean32 (var lHdrName: string;var lInHdr: TNIFTIhdr; lBuffAligned: bytep;lImgBuffer : SingleP ;lPrefs: TPrefs ): string;
var
lOutHdr : TNIFTIhdr;
lOutImgName: string;
@@ -126,7 +126,7 @@ begin
end;
lOutHdr.dim[4] := 1;
- result := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs);
end; //SaveMean32
@@ -146,7 +146,8 @@ var
lImgSamples,l4DVox,lInc: integer;
lCSVname,lResultStr,lOutImgName: string;
lInHdr, lOutHdr : TNIFTIhdr;
- lSplitOddEven,lCustom,lSubtract,lOddMinusEven,lByteSwap: boolean;
+ lO: TNIIOpts;
+ lSplitOddEven,lCustom,lSubtract,lOddMinusEven: boolean;
lBuffer,lSrcBuffer, lBuffUnaligned,lBuffAligned: bytep;
lOdd,lEven: single;
lOddVol,lEvenVol: integer;
@@ -158,7 +159,7 @@ begin
lOddMinusEven := lFunction = 1;
lSubtract := (lFunction <> 3);
result := false;
- if not NIFTIhdr_LoadHdr (lHdrName, lInHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lHdrName, lInHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lHdrName);
exit;
end;
@@ -174,7 +175,7 @@ begin
exit;
end;
- if not NIFTIhdr_LoadImg (lHdrName, lInHdr, lSrcBuffer, lImgOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lHdrName, lInHdr, lSrcBuffer, lImgOffset,lO) then exit;
lBuffer := (@lSrcBuffer^[lImgOffset+1]);
l32Buf := SingleP(lBuffer );
if lOverwrite then
@@ -218,10 +219,7 @@ begin
{$ENDIF}
lInc := 1;
lImgBuffer := SingleP(@lBuffAligned^[kNIIImgOffset+lInc]);
- if lByteSwap then
- for lInc := 1 to l4DVox do
- pswap4r(l32Buf^[lInc]); //faster as procedure than function see www.optimalcode.com
-
+
if lSplitOddEven then begin
//compute odd
for lVol := 1 to lOutHdr.dim[4] do begin
@@ -234,8 +232,8 @@ begin
lImgBuffer^[lOutVolOffset+lInc] := lOdd;
end; //for lImgSamples
end; //for lvol
- lresultStr := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
- lresultStr := SaveMean32 (lOutImgName, lOutHdr, lBuffAligned,lImgBuffer,lPrefs,lByteSwap);
+ lresultStr := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs);
+ lresultStr := SaveMean32 (lOutImgName, lOutHdr, lBuffAligned,lImgBuffer,lPrefs);
//compute even
lOutImgName := ChangeFilePrefix (lHdrName,'even');
for lVol := 1 to lOutHdr.dim[4] do begin
@@ -318,9 +316,9 @@ end else begin //not custom or lSplitOddEven
end; //add
end; //for lvol
end;
- lresultStr := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ lresultStr := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs);
//next make mean
- lresultStr := SaveMean32 (lOutImgName, lOutHdr, lBuffAligned,lImgBuffer,lPrefs,lByteSwap);
+ lresultStr := SaveMean32 (lOutImgName, lOutHdr, lBuffAligned,lImgBuffer,lPrefs);
666:
Freemem(lSrcBuffer);
Freemem(lBuffUnaligned);
@@ -331,7 +329,7 @@ end; //ASL_subtract32
//end 32bit versions
-function SaveMean (var lHdrName: string;var lInHdr: TNIFTIhdr; lInBuffer : SmallIntP; lPrefs: TPrefs; lByteSwap:boolean ): string;
+function SaveMean (var lHdrName: string;var lInHdr: TNIFTIhdr; lInBuffer : SmallIntP; lPrefs: TPrefs ): string;
var
lOutHdr : TNIFTIhdr;
lOutImgName: string;
@@ -368,7 +366,7 @@ begin
lOutHdr.dim[4] := 1;
lOutHdr.datatype := kDT_FLOAT;
lOutHdr.bitpix := 32;
- result := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs);
freemem( lBuffUnaligned);
end; //SaveMean
@@ -417,7 +415,8 @@ var
lImgSamples,l4DVox,lInc: integer;
lCSVname,lResultStr,lOutImgName: string;
lInHdr, lOutHdr : TNIFTIhdr;
- lSplitOddEven,lCustom,lSubtract,lOddMinusEven,lByteSwap: boolean;
+ lO: TNIIOpts;
+ lSplitOddEven,lCustom,lSubtract,lOddMinusEven: boolean;
lBuffer,lSrcBuffer, lBuffUnaligned,lBuffAligned: bytep;
lOdd,lEven: integer;
lImgBuffer,l16Buf : SmallIntP;
@@ -428,7 +427,7 @@ begin
lOddMinusEven := lFunction = 1;
lSubtract := (lFunction <> 3);
result := false;
- if not NIFTIhdr_LoadHdr (lHdrName, lInHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lHdrName, lInHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lHdrName);
exit;
end;
@@ -448,7 +447,7 @@ begin
exit;
end;
- if not NIFTIhdr_LoadImg (lHdrName, lInHdr, lSrcBuffer, lImgOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lHdrName, lInHdr, lSrcBuffer, lImgOffset,lO) then exit;
lBuffer := (@lSrcBuffer^[lImgOffset+1]);
l16Buf := SmallIntP(lBuffer );
if lOverwrite then
@@ -492,9 +491,6 @@ begin
{$ENDIF}
lInc := 1;
lImgBuffer := SmallIntP(@lBuffAligned^[kNIIImgOffset+lInc]);
- if lByteSwap then
- for lInc := 1 to l4DVox do
- l16Buf^[lInc] := Swap(l16Buf^[lInc]) ;
if lSplitOddEven then begin
//compute odd
for lVol := 1 to lOutHdr.dim[4] do begin
@@ -507,8 +503,8 @@ if lSplitOddEven then begin
lImgBuffer^[lOutVolOffset+lInc] := lOdd;
end; //for lImgSamples
end; //for lvol
- lresultStr := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
- lresultStr := SaveMean (lOutImgName, lOutHdr, lImgBuffer,lPrefs,lByteSwap);
+ lresultStr := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs);
+ lresultStr := SaveMean (lOutImgName, lOutHdr, lImgBuffer,lPrefs);
//compute even
lOutImgName := ChangeFilePrefix (lHdrName,'even');
for lVol := 1 to lOutHdr.dim[4] do begin
@@ -591,9 +587,9 @@ end else begin //not custom or lSplitOddEven
end; //add
end; //for lvol
end;
- lresultStr := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ lresultStr := SaveNIfTICore (lOutImgName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs);
//next make mean
- lresultStr := SaveMean (lOutImgName, lOutHdr, lImgBuffer,lPrefs,lByteSwap);
+ lresultStr := SaveMean (lOutImgName, lOutHdr, lImgBuffer,lPrefs);
666:
Freemem(lSrcBuffer);
Freemem(lBuffUnaligned);
diff --git a/dcm2nii/nii_crop.pas b/dcm2nii/nii_crop.pas
index a493647..a013fb8 100755
--- a/dcm2nii/nii_crop.pas
+++ b/dcm2nii/nii_crop.pas
@@ -12,7 +12,7 @@ interface
uses
{$IFDEF FPC}gzio2,{$ENDIF}
//distr,
- SysUtils,define_types,dicomtypes,niftiutil,GraphicsMathLibrary,prefs;
+ SysUtils,define_types,dicomtypes,niftiutil,GraphicsMathLibrary,prefs, nifti_types;
//function Int16LogPtoZNIfTI32Z(lFilename: string; lPrefs: TPrefs): string;
function CropNIfTI(lFilename: string; lPrefs: TPrefs): string;//returns output filename if successful
function Float32NIfTI(lFilename: string; lPrefs: TPrefs): string;
@@ -32,11 +32,11 @@ var
lOutname: string;
l4DBytes,lInOffset,l1: integer;
lInBuffer,lOutBuffer: bytep;
- lByteSwap: boolean;
+ lO: TNIIOpts;
begin
result := '';
//lExt := UpCaseExt(lFilename);
- if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
@@ -52,14 +52,14 @@ begin
lOutHdr.scl_slope := 1;
lOutHdr.scl_inter := 0;
l4DBytes := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]*lInHdr.dim[4]*(lInHdr.bitpix div 8);
- if not NIFTIhdr_LoadImg (lFileName, lInHdr, lInBuffer, lInOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lFileName, lInHdr, lInBuffer, lInOffset,lO) then exit;
GetMem(lOutBuffer,l4DBytes+kNIIImgOffset);
//lOutPos := kNIIImgOffset + 1;
l1 := 1;
Move(lInBuffer^[lInOffset+l1],lOutBuffer^[kNIIImgOffset + l1],l4DBytes);
lOutname := ChangeFilePrefix (lFileName,'r');
dcmMsg(lOutName);
- if SaveNIfTICore (lOutName, lOutBuffer, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap) = '' then begin
+ if SaveNIfTICore (lOutName, lOutBuffer, kNIIImgOffset+1, lOutHdr, lPrefs) = '' then begin
dcmMsg('Remove scale error');
Freemem(lInBuffer);
Freemem(lOutBuffer);
@@ -81,10 +81,11 @@ var
l32Buf,lImgBuffer: singlep;
l16Buf : SmallIntP;
lByteSwap: boolean;
+ lO: TNIIOpts;
begin
result := '';
lExt := UpCaseExt(lFilename);
- if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
@@ -100,7 +101,7 @@ begin
lOutHdr.datatype := kDT_FLOAT;
lOutHdr.bitpix := 32;
lImgSamples := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]*lInHdr.dim[4];
- if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lO) then exit;
//Msg('Automatically Cropping image');
lBuffer := (@lSrcBuffer^[lImgOffset+1]);
GetMem(lBuffUnaligned ,(sizeof(single)*lImgSamples) + 16+kNIIImgOffset);
@@ -165,7 +166,7 @@ begin
end;
end;
lOutname := ChangeFilePrefix (lFileName,'f');
- result := SaveNIfTICore (lOutName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lOutName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs);
Freemem(lBuffUnaligned);
Freemem(lSrcBuffer);
end;
@@ -180,11 +181,11 @@ var
lSrcBuffer,lBuffer, lBuffUnaligned,lBuffAligned: bytep;
l32Buf,lImgBuffer: singlep;
l16Buf : SmallIntP;
- lByteSwap: boolean;
+ lO: TNIIOpts;
begin
result := '';
lExt := UpCaseExt(lFilename);
- if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
@@ -204,7 +205,7 @@ begin
lOutHdr.datatype := kDT_FLOAT;
lOutHdr.bitpix := 32;
lImgSamples := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]*lInHdr.dim[4];
- if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lO) then exit;
//Msg('Automatically Cropping image');
lBuffer := (@lSrcBuffer^[lImgOffset+1]);
GetMem(lBuffUnaligned ,(sizeof(single)*lImgSamples) + 16+kNIIImgOffset);
@@ -222,30 +223,19 @@ begin
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]);
+
+ 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];
@@ -256,7 +246,7 @@ begin
end;
end; //case
lOutname := ChangeFilePrefix (lFileName,'f');
- result := SaveNIfTICore (lOutName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lOutName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs);
Freemem(lBuffUnaligned);
Freemem(lSrcBuffer);
end;
@@ -641,7 +631,7 @@ var
//lWordX: Word;
//lSPM2: boolean;
lOutF,lInF: File;
- lByteSwap: boolean;
+ lO: TNIIOpts;
begin
result := '';
if (lDorsalCrop = 0) and (lVentralCrop = 0)
@@ -658,7 +648,7 @@ begin
end;
result := '';
lExt := UpCaseExt(lFilename);
- if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
@@ -674,7 +664,7 @@ begin
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;
+ if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lO) then exit;
//dcmMsg('Automatically Cropping image');
lBuffer := (@lSrcBuffer^[lImgOffset+1]);
//next compute size of cropped volume
@@ -726,7 +716,7 @@ begin
end; //for Z
end; //for Vol
lOutname := ChangeFilePrefix (lFileName,'c');
- result := SaveNIfTICore (lOutName, lSrcBuffer, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lOutName, lSrcBuffer, kNIIImgOffset+1, lOutHdr, lPrefs);
Freemem(lSrcBuffer);
end;
@@ -745,11 +735,11 @@ var
l16Buf : SmallIntP;
//lOutF,lInF: File;
lACrop,lPCrop,lDorsalCrop,lVentralCrop,lLCrop,lRCrop: integer;
- lByteSwap: boolean;
+ lO: TNIIOpts;
begin
result := '';
lExt := UpCaseExt(lFilename);
- if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
@@ -776,7 +766,7 @@ begin
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;
+ if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lO) then exit;
//dcmMsg('Automatically Cropping image');
lBuffer := (@lSrcBuffer^[lImgOffset+1]);
GetMem(lBuffUnaligned ,(sizeof(single)*lImgSamples) + 16);
@@ -793,20 +783,14 @@ begin
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
+ //convert integer to float
for lInc := 1 to lImgSamples do
lImgBuffer^[lInc] := Conv4r4i(l32Buf^[lInc]);
end; //32-bit int
@@ -814,10 +798,7 @@ 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
+ 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
@@ -886,7 +867,7 @@ begin
end; //for Y
end; //for Z
lOutname := ChangeFilePrefix (lFileName,'c');
- result := SaveNIfTICore (lOutName, lSrcBuffer, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lOutName, lSrcBuffer, kNIIImgOffset+1, lOutHdr, lPrefs);
Freemem(lSrcBuffer);
end;
@@ -941,11 +922,11 @@ var
//l32Buf,
lImgBuffer: singlep;
l16Buf : SmallIntP;
- lByteSwap: boolean;
+ lO: TNIIOpts;
begin
result := '';
lExt := UpCaseExt(lFilename);
- if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lInHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
@@ -960,7 +941,7 @@ begin
lOutHdr.scl_slope := 1;
lOutHdr.scl_inter := 0;
lImgSamples := lInHdr.dim[1]*lInHdr.dim[2]*lInHdr.dim[3]*lInHdr.dim[4];
- if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lFileName, lInHdr, lSrcBuffer, lImgOffset,lO) then exit;
lBuffer := (@lSrcBuffer^[lImgOffset+1]);
GetMem(lBuffUnaligned ,(sizeof(single)*lImgSamples) + 16+kNIIImgOffset);
{$IFDEF FPC}
@@ -971,9 +952,6 @@ begin
lInc := 1;
lImgBuffer := SingleP(@lBuffAligned^[kNIIImgOffset+lInc]);
l16Buf := SmallIntP(lBuffer );
- if lByteSwap then
- for lInc := 1 to lImgSamples do
- l16Buf^[lInc] := Swap(l16Buf^[lInc]);
lMax := l16Buf^[1];
for lInc := 1 to lImgSamples do
if l16Buf^[lInc] > lMax then
@@ -991,7 +969,7 @@ begin
for lInc := 1 to lImgSamples do
lImgBuffer^[lInc] := ((l16Buf^[lInc]-2048)/2048)*pi;
lOutname := ChangeFilePrefix (lFileName,'rad');
- result := SaveNIfTICore (lOutName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lOutName, lBuffAligned, kNIIImgOffset+1, lOutHdr, lPrefs);
end;
Freemem(lBuffUnaligned);
Freemem(lSrcBuffer);
diff --git a/dcm2nii/nii_math.pas b/dcm2nii/nii_math.pas
index 0c02869..c7f7f92 100755
--- a/dcm2nii/nii_math.pas
+++ b/dcm2nii/nii_math.pas
@@ -5,13 +5,14 @@ interface
uses
//nii_types,nii_write,
niftiutil,dicomtypes,prefs,
- define_types, sysutils, dialogsx,GraphicsMathLibrary;
+ define_types, sysutils, dialogsx,GraphicsMathLibrary, nifti_types;
type
TNIFTIimg = record
HdrName: string;
Hdr: TNIFTIhdr;
- ByteSwap: boolean;
+ Opts: TNIIOpts;
+ //ByteSwap: boolean;
Offset: integer;
Buffer,i8: bytep;
f32: singlep;
@@ -41,7 +42,7 @@ function LoadHdrNII(lFilename: string; var lNII: TNIfTIimg): boolean;
begin
result := false;
lNII.HdrName := lFilename;
- if not NIFTIhdr_LoadHdr (lNII.HdrName, lNII.Hdr, lNII.ByteSwap) then begin;
+ if not NIFTIhdr_LoadHdr (lNII.HdrName, lNII.Hdr, lNII.Opts) then begin;
ShowMsg('Header load error '+lFilename);
exit;
end;
@@ -66,11 +67,10 @@ begin
result := false;
if not LoadHdrNII(lFilename,lNII) then
exit;
- if not NIFTIhdr_LoadImgRaw (False,lNII.HdrName, lNII.Hdr, lNII.Buffer, lNII.Offset,lNII.ByteSwap) then begin
+ if not NIFTIhdr_LoadImgRaw (False,lNII.HdrName, lNII.Hdr, lNII.Buffer, lNII.Offset,lNII.Opts) then begin
ShowMsg('Image load error '+lFilename);
exit;
end;
- NIFTIhdr_UnswapImg(lNII.Hdr,lNII.Buffer,lNII.Offset,lNII.ByteSwap);
lNII.f32 := SingleP(@lNII.Buffer^[lNII.Offset+1]);
lNII.i32 := LongintP(@lNII.Buffer^[lNII.Offset+1]);
lNII.i16 := SmallIntP(@lNII.Buffer^[lNII.Offset+1]);
@@ -259,7 +259,6 @@ begin
lOut.Hdr.datatype := kDT_SIGNED_SHORT;
lOut.Hdr.scl_slope := 1;
lOut.Hdr.scl_inter := 0;
- lOut.ByteSwap := false;
CreateEmptyImgNII(lOut.Hdr, lOut);
//translate values
lMin16 := round(lMin);
@@ -287,7 +286,7 @@ begin
//SetDefaultPrefs (lPrefs);
//lOName := lAName;
//lPrefs.gzip := true;
- SaveNIfTICore (lOName, lOut.Buffer, kNIIImgOffset+1, lOut.Hdr, lPrefs,lOut.ByteSwap);
+ SaveNIfTICore (lOName, lOut.Buffer, kNIIImgOffset+1, lOut.Hdr, lPrefs);
result := true;
666:
FreeNII(lA);
@@ -357,7 +356,6 @@ begin
lOut.Hdr := lA.Hdr;
force3DNII(lOut);
lOut.Hdr.datatype := kDT_FLOAT;
- lOut.ByteSwap := false;
CreateEmptyImgNII(lOut.Hdr, lOut);
for lV := 1 to lVox do
lOut.f32^[lV] := 0;
@@ -397,7 +395,7 @@ begin
else if lSaveOutput then begin
lOName := ChangeFilePrefix(lAName,'Xrms');
//SetDefaultPrefs (lPrefs);
- SaveNIfTICore (lOName, lOut.Buffer, kNIIImgOffset+1, lOut.Hdr, lPrefs,lOut.ByteSwap);
+ SaveNIfTICore (lOName, lOut.Buffer, kNIIImgOffset+1, lOut.Hdr, lPrefs);
end;
if lCount > 0 then
result := lSum/lCount;
@@ -435,7 +433,6 @@ begin
force3DNII(lOut);
lOut.hdr.dim[3] := lOut.hdr.dim[3] + lSlices;
lOut.Hdr.datatype := kDT_FLOAT;
- lOut.ByteSwap := false;
CreateEmptyImgNII(lOut.Hdr, lOut);
lI := 0;
//lOffset := 0;
@@ -463,7 +460,7 @@ begin
lOName := ChangeFilePrefix(lAName,'x');
//SetDefaultPrefs (lPrefs);
- if SaveNIfTICore (lOName, lOut.Buffer, kNIIImgOffset+1, lOut.Hdr, lPrefs,lOut.ByteSwap) <> '' then
+ if SaveNIfTICore (lOName, lOut.Buffer, kNIIImgOffset+1, lOut.Hdr, lPrefs) <> '' then
result := true;
666:
FreeNII(lA);
@@ -536,7 +533,6 @@ begin
lOut.hdr.pixdim[1] := lOut.hdr.pixdim[1] * 2;
lOut.hdr.pixdim[2] := lOut.hdr.pixdim[2] * 2;
RescaleHdr(lOut.hdr,2,2,1);
- lOut.ByteSwap := false;
CreateEmptyImgNII(lOut.Hdr, lOut);
case lA.Hdr.datatype of
kDT_UNSIGNED_CHAR: begin
@@ -589,7 +585,7 @@ begin
end;//float
end;// datatype
lOName := ChangeFilePrefix(lAName,'d');
- if SaveNIfTICore (lOName, lOut.Buffer, kNIIImgOffset+1, lOut.Hdr, lPrefs,lOut.ByteSwap) <> '' then
+ if SaveNIfTICore (lOName, lOut.Buffer, kNIIImgOffset+1, lOut.Hdr, lPrefs) <> '' then
result := true;
666:
FreeNII(lA);
diff --git a/dcm2nii/nii_orient.pas b/dcm2nii/nii_orient.pas
index 4088e2b..38b1a2e 100755
--- 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,dialogs_msg;
+ SysUtils,define_types,dicomtypes,niftiutil,GraphicsMathLibrary,prefs,dialogs_msg, nifti_types;
function Reorient(var lHdrName: string; var lHdr: TNIFTIhdr; lPrefs: TPrefs; lOverwrite,lForce: boolean): string;
//function SuperReorient(var lHdrName: string; lPrefs: TPrefs):string;
@@ -267,7 +267,8 @@ var
lVol,lNumVol,lXInc, lYInc, lZInc,lBPP: integer;
lInPos,lVolBytes,lOutPos,lInOffset: integer;
lBufferIn,lBufferOut,lIBuffer,lOBuffer: bytep;
- lByteSwap,lFlipX,lFlipY,lFlipZ: boolean;
+ lOpts: TNIIOpts;
+ lFlipX,lFlipY,lFlipZ: boolean;
lOutF,lInF: File;
begin
result := '';
@@ -379,7 +380,7 @@ begin
lOutHdr.qoffset_x,lOutHdr.qoffset_y,lOutHdr.qoffset_z,
dx, dy, dz,lOutHdr.pixdim[0] {QFac});
//read input
- if not NIFTIhdr_LoadImg (lHdrName, lHdr, lIBuffer, lInOffset,lByteSwap) then exit;
+ if not NIFTIhdr_LoadImg (lHdrName, lHdr, lIBuffer, lInOffset,lOpts) then exit;
lNumVol := lOutHdr.dim[4];
if lNumVol < 1 then //hopefully this nevee happens
@@ -426,9 +427,9 @@ begin
lOutName := ChangeFilePrefix (lHdrName,lPrefix);
dcmMsg('Reorienting as '+lOutName);
if lKeepOrigHdr then
- result := SaveNIfTICore (lOutName, lOBuffer, kNIIImgOffset+1, lHdr, lPrefs,lByteSwap)
+ result := SaveNIfTICore (lOutName, lOBuffer, kNIIImgOffset+1, lHdr, lPrefs)
else
- result := SaveNIfTICore (lOutName, lOBuffer, kNIIImgOffset+1, lOutHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lOutName, lOBuffer, kNIIImgOffset+1, lOutHdr, lPrefs);
Freemem(lOBuffer);
end;//ReorientCore
@@ -695,11 +696,11 @@ function LRFlip(lFilename: string; lPrefs: TPrefs): boolean;
//reslice an image so it is in canonical space
var
lHdr: TNIFTIhdr;
- lByteSwap: boolean;
+ lO: TNIIOPts;
lInMat,lRotMat: TMatrix;
begin
result := false;
- if not NIFTIhdr_LoadHdr (lFilename, lHdr, lByteSwap) then begin
+ if not NIFTIhdr_LoadHdr (lFilename, lHdr, lO) then begin
dcmMsg('Unable to read as NifTI/Analyze' + lFilename);
exit;
end;
diff --git a/dcm2nii/nii_reslice.pas b/dcm2nii/nii_reslice.pas
index 01e841c..ea8b366 100755
--- 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,dialogs_msg;
+ niftiutil,define_types,sysutils,dicomtypes,prefs,dialogs_msg, nifti_types;
//function ResliceImgNIfTI (lTargetImgName,lSrcImgName,lOutputName: string): boolean;
function Reslice2Targ (lSrcName,lTargetName,lDestName: string; lPrefs: TPrefs):string;
@@ -232,11 +232,11 @@ var
l8i,l8is,lSrcBuffer,lBuffUnaligned,lBuffAligned: bytep;
lMat: TMatrix;
lTargHdr,lSrcHdr,lDestHdr: TNIFTIhdr;
- lByteSwap: boolean;
+ lS,lT: TNIIOpts;
begin
result := '';
- if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lByteSwap) then exit;
- if not NIFTIhdr_LoadHdr (lTargetName, lTargHdr, lByteSwap) then exit;
+ if not NIFTIhdr_LoadHdr (lSrcname, lSrcHdr, lS) then exit;
+ if not NIFTIhdr_LoadHdr (lTargetName, lTargHdr, lT) then exit;
case lSrcHdr.datatype of
kDT_UNSIGNED_CHAR : lBPP := 1;
kDT_SIGNED_SHORT: lBPP := 2;
@@ -261,8 +261,7 @@ begin
lZ := lDestHdr.Dim[3];
lDestHdr.Dim[4] := 1;
//load dataset
- if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap) then exit;
- NIFTIhdr_UnswapImg(lSrcHdr, lSrcBuffer, lSrcOffset,lByteSwap);//interpolation requires data is in native endian
+ if not NIFTIhdr_LoadImg (lSrcName, lSrcHdr, lSrcBuffer, lSrcOffset,lS) then exit;
l8is := (@lSrcBuffer^[lSrcOffset+1]);
GetMem(lBuffUnaligned ,(lBPP*lX*lY*lZ) + 16+kNIIImgOffset);
{$IFDEF FPC}
@@ -409,7 +408,7 @@ begin
kDT_FLOAT: while (lPos <= (lX*lY*lZ)) and (l32f^[lPos] = 0) do inc(lPos);
end; //case
if lPos <= (lX*lY*lZ) then begin //image not empty
- result := SaveNIfTICore (lDestName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs,lByteSwap);
+ result := SaveNIfTICore (lDestName, lBuffAligned, kNIIImgOffset+1, lDestHdr, lPrefs);
end else begin
dcmMsg('no voxels in output');
end;
diff --git a/dcm2nii/paramstrs.pas b/dcm2nii/paramstrs.pas
index a4fae11..d737cae 100755
--- a/dcm2nii/paramstrs.pas
+++ b/dcm2nii/paramstrs.pas
@@ -182,6 +182,7 @@ begin
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('-t Text report (patient and scan details): Y,N = '+Bool2YN(lPrefs.txtReport));
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);
@@ -311,6 +312,8 @@ begin
'P': CharBool(lStr[1],lPrefs.AppendProtocolName);
'R': CharBool(lStr[1],lPrefs.enablereorient);
'S': CharBool(lStr[1],lPrefs.SPM2);
+ 'T': CharBool(lStr[1],lPrefs.txtReport);
+
'V': CharBool(lStr[1],lPrefs.EveryFile);
'X': CharBool(lStr[1],lPrefs.Autocrop);
'B': begin //load INI file
@@ -339,6 +342,8 @@ begin
lPrefs.AppendAcqSeries := true;
end;
if direxists(lStr) then begin
+ if (lStr[length(lStr)] = PathDelim) and (length(lStr) > 1) then //and
+ delete(lStr, length(lStr), 1); //delete trialing separator
RecursiveFolderSearch(lStr,lOutDir,lPrefs,0);
lPrefs.NameAppend := '';
end else if fileexists(lStr) then begin
diff --git a/dcm2nii/parconvert.pas b/dcm2nii/parconvert.pas
index 392c6ba..97e2377 100755
--- a/dcm2nii/parconvert.pas
+++ b/dcm2nii/parconvert.pas
@@ -3,7 +3,7 @@ unit parconvert;
interface
uses
{$IFDEF FPC}gzio2, {$ENDIF}
-define_types,SysUtils,dicom,dicomtypes,filename,nii_4dto3d,niftiutil,nii_orient, nii_crop,GraphicsMathLibrary,prefs,dialogs_msg;
+define_types,SysUtils,dicom,dicomtypes,filename,nii_4dto3d,niftiutil,nii_orient, nii_crop,GraphicsMathLibrary,prefs,dialogs_msg, nifti_types;
function LoadFileListPARREC (var lInFilename, lOutDir: string; var lPrefs: TPrefs): boolean;
implementation
diff --git a/dcm2nii/pref_form.lfm b/dcm2nii/pref_form.lfm
index 830f7fc..b4542d1 100755
--- a/dcm2nii/pref_form.lfm
+++ b/dcm2nii/pref_form.lfm
@@ -1,33 +1,33 @@
object PrefsForm: TPrefsForm
- Left = 401
- Height = 424
- Top = 198
- Width = 464
+ Left = 570
+ Height = 332
+ Top = 216
+ Width = 600
HorzScrollBar.Page = 463
VertScrollBar.Page = 323
ActiveControl = DateCheck
BorderIcons = [biSystemMenu]
Caption = 'Preferences'
- ClientHeight = 424
- ClientWidth = 464
- Constraints.MaxHeight = 424
- Constraints.MaxWidth = 464
- Constraints.MinHeight = 389
- Constraints.MinWidth = 464
+ ClientHeight = 332
+ ClientWidth = 600
+ Constraints.MaxHeight = 332
+ Constraints.MaxWidth = 600
+ Constraints.MinHeight = 332
+ Constraints.MinWidth = 600
Position = poDesktopCenter
- LCLVersion = '0.9.30'
+ LCLVersion = '1.0.12.0'
object Label1: TLabel
- Left = 129
+ Left = 120
Height = 17
- Top = 291
+ Top = 184
Width = 188
Caption = 'Recursive folder search depth'
ParentColor = False
end
object OutDirLabel: TLabel
- Left = 43
+ Left = 24
Height = 17
- Top = 352
+ Top = 256
Width = 19
Caption = 'c:\'
ParentColor = False
@@ -36,10 +36,10 @@ object PrefsForm: TPrefsForm
Left = 8
Height = 160
Top = 8
- Width = 448
+ Width = 184
Caption = 'Output Filename'
ClientHeight = 138
- ClientWidth = 440
+ ClientWidth = 176
TabOrder = 0
object DateCheck: TCheckBox
Left = 22
@@ -81,16 +81,16 @@ object PrefsForm: TPrefsForm
Left = 22
Height = 18
Top = 105
- Width = 132
+ Width = 131
Caption = 'Acquisition Series'
OnChange = FilenameChecks
TabOrder = 4
end
end
object OKbtn: TButton
- Left = 360
+ Left = 488
Height = 25
- Top = 392
+ Top = 288
Width = 75
BorderSpacing.InnerBorder = 4
Caption = 'OK'
@@ -98,9 +98,9 @@ object PrefsForm: TPrefsForm
TabOrder = 1
end
object CancelBtn: TButton
- Left = 272
+ Left = 400
Height = 25
- Top = 392
+ Top = 288
Width = 75
BorderSpacing.InnerBorder = 4
Caption = 'Cancel'
@@ -108,34 +108,34 @@ object PrefsForm: TPrefsForm
TabOrder = 2
end
object NotAnonymizeCheck: TCheckBox
- Left = 35
+ Left = 202
Height = 18
- Top = 172
+ Top = 16
Width = 233
Caption = 'Save patient name in NIfTI header'
TabOrder = 3
end
object ReorientCheck: TCheckBox
- Left = 35
+ Left = 202
Height = 18
- Top = 202
- Width = 338
+ Top = 80
+ Width = 336
Caption = 'Reorient large images to nearest orthogonal plane'
TabOrder = 4
end
object RecursiveSpin: TSpinEdit
- Left = 38
+ Left = 24
Height = 16
- Top = 288
+ Top = 184
Width = 77
MaxValue = 10
TabOrder = 5
end
object OutputCombo: TComboBox
- Left = 35
+ Left = 24
Height = 20
- Top = 320
- Width = 253
+ Top = 216
+ Width = 296
ItemHeight = 0
Items.Strings = (
'Save to source folder'
@@ -148,27 +148,27 @@ object PrefsForm: TPrefsForm
TabOrder = 6
end
object CollapseCheck: TCheckBox
- Left = 35
+ Left = 202
Height = 18
Hint = 'Sort images regardless of source directory. Slower, required if series segmented across folders'
- Top = 232
- Width = 122
+ Top = 112
+ Width = 121
Caption = 'Collapse folders'
TabOrder = 7
end
object Stack3DImagesWithSameAcqNum: TCheckBox
- Left = 35
+ Left = 202
Height = 18
Hint = 'Sort images regardless of source directory. Slower, required if series segmented across folders'
- Top = 262
- Width = 316
+ Top = 144
+ Width = 314
Caption = 'Stack 3D images with same acquistion number'
TabOrder = 8
end
object TextEditorBtn: TButton
- Left = 38
+ Left = 8
Height = 25
- Top = 392
+ Top = 288
Width = 123
BorderSpacing.InnerBorder = 4
Caption = 'Text Edit'
@@ -176,9 +176,9 @@ object PrefsForm: TPrefsForm
TabOrder = 9
end
object WritePrefsOnQuit: TCheckBox
- Left = 284
+ Left = 344
Height = 18
- Top = 230
+ Top = 112
Width = 138
Caption = 'Write prefs on quit'
Checked = True
@@ -186,4 +186,12 @@ object PrefsForm: TPrefsForm
TabOrder = 10
Visible = False
end
+ object TxtReportCheck: TCheckBox
+ Left = 202
+ Height = 18
+ Top = 48
+ Width = 282
+ Caption = 'Save text report (scan and patient details)'
+ TabOrder = 11
+ end
end
diff --git a/dcm2nii/pref_form.lrs b/dcm2nii/pref_form.lrs
index a18876b..c6cdb9f 100755
--- a/dcm2nii/pref_form.lrs
+++ b/dcm2nii/pref_form.lrs
@@ -1,56 +1,59 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TPrefsForm','FORMDATA',[
- 'TPF0'#10'TPrefsForm'#9'PrefsForm'#4'Left'#3#145#1#6'Height'#3#168#1#3'Top'#3
- +#198#0#5'Width'#3#208#1#18'HorzScrollBar.Page'#3#207#1#18'VertScrollBar.Page'
+ 'TPF0'#10'TPrefsForm'#9'PrefsForm'#4'Left'#3':'#2#6'Height'#3'L'#1#3'Top'#3
+ +#216#0#5'Width'#3'X'#2#18'HorzScrollBar.Page'#3#207#1#18'VertScrollBar.Page'
+#3'C'#1#13'ActiveControl'#7#9'DateCheck'#11'BorderIcons'#11#12'biSystemMenu'
- +#0#7'Caption'#6#11'Preferences'#12'ClientHeight'#3#168#1#11'ClientWidth'#3
- +#208#1#21'Constraints.MaxHeight'#3#168#1#20'Constraints.MaxWidth'#3#208#1#21
- +'Constraints.MinHeight'#3#133#1#20'Constraints.MinWidth'#3#208#1#8'Position'
- +#7#15'poDesktopCenter'#10'LCLVersion'#6#6'0.9.30'#0#6'TLabel'#6'Label1'#4'Le'
- +'ft'#3#129#0#6'Height'#2#17#3'Top'#3'#'#1#5'Width'#3#188#0#7'Caption'#6#29'R'
- +'ecursive folder search depth'#11'ParentColor'#8#0#0#6'TLabel'#11'OutDirLabe'
- +'l'#4'Left'#2'+'#6'Height'#2#17#3'Top'#3'`'#1#5'Width'#2#19#7'Caption'#6#3'c'
- +':\'#11'ParentColor'#8#0#0#9'TGroupBox'#11'FilenameBox'#4'Left'#2#8#6'Height'
- +#3#160#0#3'Top'#2#8#5'Width'#3#192#1#7'Caption'#6#15'Output Filename'#12'Cli'
- +'entHeight'#3#138#0#11'ClientWidth'#3#184#1#8'TabOrder'#2#0#0#9'TCheckBox'#9
- +'DateCheck'#4'Left'#2#22#6'Height'#2#18#3'Top'#2#8#5'Width'#2'|'#7'Caption'#6
- +#16'Acquisition Date'#8'OnChange'#7#14'FilenameChecks'#8'TabOrder'#2#0#0#0#9
- +'TCheckBox'#14'InputNameCheck'#4'Left'#2#22#6'Height'#2#18#3'Top'#2'!'#5'Wid'
- +'th'#2'r'#7'Caption'#6#14'Input Filename'#8'OnChange'#7#14'FilenameChecks'#8
- +'TabOrder'#2#1#0#0#9'TCheckBox'#13'ProtocolCheck'#4'Left'#2#22#6'Height'#2#18
- +#3'Top'#2'9'#5'Width'#2'q'#7'Caption'#6#13'Protocol Name'#8'OnChange'#7#14'F'
- +'ilenameChecks'#8'TabOrder'#2#2#0#0#9'TCheckBox'#16'PatientNameCheck'#4'Left'
- +#2#22#6'Height'#2#18#3'Top'#2'Q'#5'Width'#2'h'#7'Caption'#6#12'Patient Name'
- +#8'OnChange'#7#14'FilenameChecks'#8'TabOrder'#2#3#0#0#9'TCheckBox'#11'Series'
- +'Check'#4'Left'#2#22#6'Height'#2#18#3'Top'#2'i'#5'Width'#3#132#0#7'Caption'#6
+ +#0#7'Caption'#6#11'Preferences'#12'ClientHeight'#3'L'#1#11'ClientWidth'#3'X'
+ +#2#21'Constraints.MaxHeight'#3'L'#1#20'Constraints.MaxWidth'#3'X'#2#21'Const'
+ +'raints.MinHeight'#3'L'#1#20'Constraints.MinWidth'#3'X'#2#8'Position'#7#15'p'
+ +'oDesktopCenter'#10'LCLVersion'#6#8'1.0.12.0'#0#6'TLabel'#6'Label1'#4'Left'#2
+ +'x'#6'Height'#2#17#3'Top'#3#184#0#5'Width'#3#188#0#7'Caption'#6#29'Recursive'
+ +' folder search depth'#11'ParentColor'#8#0#0#6'TLabel'#11'OutDirLabel'#4'Lef'
+ +'t'#2#24#6'Height'#2#17#3'Top'#3#0#1#5'Width'#2#19#7'Caption'#6#3'c:\'#11'Pa'
+ +'rentColor'#8#0#0#9'TGroupBox'#11'FilenameBox'#4'Left'#2#8#6'Height'#3#160#0
+ +#3'Top'#2#8#5'Width'#3#184#0#7'Caption'#6#15'Output Filename'#12'ClientHeigh'
+ +'t'#3#138#0#11'ClientWidth'#3#176#0#8'TabOrder'#2#0#0#9'TCheckBox'#9'DateChe'
+ +'ck'#4'Left'#2#22#6'Height'#2#18#3'Top'#2#8#5'Width'#2'|'#7'Caption'#6#16'Ac'
+ +'quisition Date'#8'OnChange'#7#14'FilenameChecks'#8'TabOrder'#2#0#0#0#9'TChe'
+ +'ckBox'#14'InputNameCheck'#4'Left'#2#22#6'Height'#2#18#3'Top'#2'!'#5'Width'#2
+ +'r'#7'Caption'#6#14'Input Filename'#8'OnChange'#7#14'FilenameChecks'#8'TabOr'
+ +'der'#2#1#0#0#9'TCheckBox'#13'ProtocolCheck'#4'Left'#2#22#6'Height'#2#18#3'T'
+ +'op'#2'9'#5'Width'#2'q'#7'Caption'#6#13'Protocol Name'#8'OnChange'#7#14'File'
+ +'nameChecks'#8'TabOrder'#2#2#0#0#9'TCheckBox'#16'PatientNameCheck'#4'Left'#2
+ +#22#6'Height'#2#18#3'Top'#2'Q'#5'Width'#2'h'#7'Caption'#6#12'Patient Name'#8
+ +'OnChange'#7#14'FilenameChecks'#8'TabOrder'#2#3#0#0#9'TCheckBox'#11'SeriesCh'
+ +'eck'#4'Left'#2#22#6'Height'#2#18#3'Top'#2'i'#5'Width'#3#131#0#7'Caption'#6
+#18'Acquisition Series'#8'OnChange'#7#14'FilenameChecks'#8'TabOrder'#2#4#0#0
- +#0#7'TButton'#5'OKbtn'#4'Left'#3'h'#1#6'Height'#2#25#3'Top'#3#136#1#5'Width'
+ +#0#7'TButton'#5'OKbtn'#4'Left'#3#232#1#6'Height'#2#25#3'Top'#3' '#1#5'Width'
+#2'K'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#2'OK'#11'ModalResult'#2
- +#1#8'TabOrder'#2#1#0#0#7'TButton'#9'CancelBtn'#4'Left'#3#16#1#6'Height'#2#25
- +#3'Top'#3#136#1#5'Width'#2'K'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6
- +#6'Cancel'#11'ModalResult'#2#2#8'TabOrder'#2#2#0#0#9'TCheckBox'#17'NotAnonym'
- +'izeCheck'#4'Left'#2'#'#6'Height'#2#18#3'Top'#3#172#0#5'Width'#3#233#0#7'Cap'
- +'tion'#6'!Save patient name in NIfTI header'#8'TabOrder'#2#3#0#0#9'TCheckBox'
- +#13'ReorientCheck'#4'Left'#2'#'#6'Height'#2#18#3'Top'#3#202#0#5'Width'#3'R'#1
+ +#1#8'TabOrder'#2#1#0#0#7'TButton'#9'CancelBtn'#4'Left'#3#144#1#6'Height'#2#25
+ +#3'Top'#3' '#1#5'Width'#2'K'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#6
+ +'Cancel'#11'ModalResult'#2#2#8'TabOrder'#2#2#0#0#9'TCheckBox'#17'NotAnonymiz'
+ +'eCheck'#4'Left'#3#202#0#6'Height'#2#18#3'Top'#2#16#5'Width'#3#233#0#7'Capti'
+ +'on'#6'!Save patient name in NIfTI header'#8'TabOrder'#2#3#0#0#9'TCheckBox'
+ +#13'ReorientCheck'#4'Left'#3#202#0#6'Height'#2#18#3'Top'#2'P'#5'Width'#3'P'#1
+#7'Caption'#6'1Reorient large images to nearest orthogonal plane'#8'TabOrder'
- +#2#4#0#0#9'TSpinEdit'#13'RecursiveSpin'#4'Left'#2'&'#6'Height'#2#16#3'Top'#3
- +' '#1#5'Width'#2'M'#8'MaxValue'#2#10#8'TabOrder'#2#5#0#0#9'TComboBox'#11'Out'
- +'putCombo'#4'Left'#2'#'#6'Height'#2#20#3'Top'#3'@'#1#5'Width'#3#253#0#10'Ite'
- +'mHeight'#2#0#13'Items.Strings'#1#6#21'Save to source folder'#6#29'Prompt us'
- +'er for output folder'#6#17'Always save to...'#0#8'OnChange'#7#17'OutputComb'
- +'oChange'#9'OnMouseUp'#7#18'OutputComboMouseUp'#5'Style'#7#14'csDropDownList'
- +#8'TabOrder'#2#6#0#0#9'TCheckBox'#13'CollapseCheck'#4'Left'#2'#'#6'Height'#2
- +#18#4'Hint'#6'_Sort images regardless of source directory. Slower, required '
- +'if series segmented across folders'#3'Top'#3#232#0#5'Width'#2'z'#7'Caption'
- +#6#16'Collapse folders'#8'TabOrder'#2#7#0#0#9'TCheckBox'#27'Stack3DImagesWit'
- +'hSameAcqNum'#4'Left'#2'#'#6'Height'#2#18#4'Hint'#6'_Sort images regardless '
- +'of source directory. Slower, required if series segmented across folders'#3
- +'Top'#3#6#1#5'Width'#3'<'#1#7'Caption'#6'+Stack 3D images with same acquisti'
- +'on number'#8'TabOrder'#2#8#0#0#7'TButton'#13'TextEditorBtn'#4'Left'#2'&'#6
- +'Height'#2#25#3'Top'#3#136#1#5'Width'#2'{'#25'BorderSpacing.InnerBorder'#2#4
- +#7'Caption'#6#9'Text Edit'#7'OnClick'#7#18'TextEditorBtnClick'#8'TabOrder'#2
- +#9#0#0#9'TCheckBox'#16'WritePrefsOnQuit'#4'Left'#3#28#1#6'Height'#2#18#3'Top'
- +#3#230#0#5'Width'#3#138#0#7'Caption'#6#19'Write prefs on quit'#7'Checked'#9#5
- +'State'#7#9'cbChecked'#8'TabOrder'#2#10#7'Visible'#8#0#0#0
+ +#2#4#0#0#9'TSpinEdit'#13'RecursiveSpin'#4'Left'#2#24#6'Height'#2#16#3'Top'#3
+ +#184#0#5'Width'#2'M'#8'MaxValue'#2#10#8'TabOrder'#2#5#0#0#9'TComboBox'#11'Ou'
+ +'tputCombo'#4'Left'#2#24#6'Height'#2#20#3'Top'#3#216#0#5'Width'#3'('#1#10'It'
+ +'emHeight'#2#0#13'Items.Strings'#1#6#21'Save to source folder'#6#29'Prompt u'
+ +'ser for output folder'#6#17'Always save to...'#0#8'OnChange'#7#17'OutputCom'
+ +'boChange'#9'OnMouseUp'#7#18'OutputComboMouseUp'#5'Style'#7#14'csDropDownLis'
+ +'t'#8'TabOrder'#2#6#0#0#9'TCheckBox'#13'CollapseCheck'#4'Left'#3#202#0#6'Hei'
+ +'ght'#2#18#4'Hint'#6'_Sort images regardless of source directory. Slower, re'
+ +'quired if series segmented across folders'#3'Top'#2'p'#5'Width'#2'y'#7'Capt'
+ +'ion'#6#16'Collapse folders'#8'TabOrder'#2#7#0#0#9'TCheckBox'#27'Stack3DImag'
+ +'esWithSameAcqNum'#4'Left'#3#202#0#6'Height'#2#18#4'Hint'#6'_Sort images reg'
+ +'ardless of source directory. Slower, required if series segmented across fo'
+ +'lders'#3'Top'#3#144#0#5'Width'#3':'#1#7'Caption'#6'+Stack 3D images with sa'
+ +'me acquistion number'#8'TabOrder'#2#8#0#0#7'TButton'#13'TextEditorBtn'#4'Le'
+ +'ft'#2#8#6'Height'#2#25#3'Top'#3' '#1#5'Width'#2'{'#25'BorderSpacing.InnerBo'
+ +'rder'#2#4#7'Caption'#6#9'Text Edit'#7'OnClick'#7#18'TextEditorBtnClick'#8'T'
+ +'abOrder'#2#9#0#0#9'TCheckBox'#16'WritePrefsOnQuit'#4'Left'#3'X'#1#6'Height'
+ +#2#18#3'Top'#2'p'#5'Width'#3#138#0#7'Caption'#6#19'Write prefs on quit'#7'Ch'
+ +'ecked'#9#5'State'#7#9'cbChecked'#8'TabOrder'#2#10#7'Visible'#8#0#0#9'TCheck'
+ +'Box'#14'TxtReportCheck'#4'Left'#3#202#0#6'Height'#2#18#3'Top'#2'0'#5'Width'
+ +#3#26#1#7'Caption'#6'+Save text report (scan and patient details)'#8'TabOrde'
+ +'r'#2#11#0#0#0
]);
diff --git a/dcm2nii/pref_form.pas b/dcm2nii/pref_form.pas
index 503dc7f..c1af936 100755
--- a/dcm2nii/pref_form.pas
+++ b/dcm2nii/pref_form.pas
@@ -14,6 +14,7 @@ type
{$H+}
{ TPrefsForm }
TPrefsForm = class(TForm)
+ TxtReportCheck: TCheckBox;
// WritePrefsOnQuit: TCheckBox;
// TextEditorBtn: TButton;
Stack3DImagesWithSameAcqNum: TCheckBox;
@@ -78,6 +79,7 @@ begin
CollapseCheck.checked := lPrefs.CollapseFolders;
ReorientCheck.Checked := (lPrefs.MinReorientMatrix < 32000);
NotAnonymizeCheck.Checked := not lPrefs.Anonymize;
+ TxtReportCheck.Checked := lPrefs.TxtReport;
RecursiveSpin.Value := lPrefs.RecursiveFolderDepth;
OutDirLabel.Caption := lPrefs.OutDir;
if (lPrefs.OutDirMode < 0) or (lPrefs.OutDirMode >= OutputCombo.Items.count) then
@@ -103,6 +105,7 @@ begin
end else
lPrefs.MinReorientMatrix := MaxInt;
lPrefs.Anonymize := not NotAnonymizeCheck.Checked;
+ lPrefs.TxtReport:= TxtReportCheck.Checked;
lPrefs.RecursiveFolderDepth := RecursiveSpin.Value;
lPrefs.OutDir := OutDirLabel.Caption;
lPrefs.OutDirMode := OutputCombo.ItemIndex;
@@ -161,6 +164,8 @@ begin
FilenameBox.Caption := 'Output Filename ('+ OutputFilename(lDicomImgName,lDicomData,lPrefs)+')';
end;
+
+
procedure TPrefsForm.SetOutput;
begin
SetOutDirLabel;
diff --git a/dcm2nii/prefs.pas b/dcm2nii/prefs.pas
index 36682ff..74972ea 100755
--- a/dcm2nii/prefs.pas
+++ b/dcm2nii/prefs.pas
@@ -19,7 +19,7 @@ type
AppendDate,AppendAcqSeries,AppendProtocolName,AppendPatientName,AppendFilename,
everyfile,fourD,Swizzle4D,Stack3DImagesWithSameAcqNum,customRename,
CollapseFolders,AutoCrop, UseGE_0021_104F, PhilipsPrecise,Verbose,
- DebugMode,DebugMode2,UntestedFeatures,UINT16toFLOAT32: boolean;
+ DebugMode,DebugMode2,UntestedFeatures,UINT16toFLOAT32, TxtReport: boolean;
BeginClip, LastClip,SiemensDTIUse0019If00181020atleast,
SiemensDTINoAngulationCorrectionIf00181020atleast,
@@ -118,6 +118,7 @@ begin
DebugMode := false;
DebugMode2 := false;
UntestedFeatures := false;
+ TxtReport := false;
Verbose := false;
SingleNIIFile := true;
Gzip := true;
@@ -211,6 +212,8 @@ begin
IniBool(lRead,lIniFile,'DebugMode',lPrefs.DebugMode);
IniBool(lRead,lIniFile,'UntestedFeatures',lPrefs.UntestedFeatures);
+ IniBool(lRead,lIniFile,'TxtReport',lPrefs.TxtReport);
+
IniBool(lRead,lIniFile,'UINT16toFLOAT32',lPrefs.UINT16toFLOAT32);
IniBool(lRead,lIniFile,'Verbose',lPrefs.Verbose);
IniBool(lRead,lIniFile,'Anonymize',lPrefs.Anonymize);
diff --git a/drop.patch b/drop.patch
new file mode 100644
index 0000000..b394fec
--- /dev/null
+++ b/drop.patch
@@ -0,0 +1,75 @@
+diff -uwNr --exclude=.svn --exclude=Makefile --exclude=Makefile.fpc --exclude=Makefile.compiled --exclude='*.rst' --exclude='*.po' lazarus/lcl/interfaces/carbon/carbonobject.inc lazarus.w/lcl/interfaces/carbon/carbonobject.inc
+--- lazarus/lcl/interfaces/carbon/carbonobject.inc 2013-11-16 10:59:07.000000000 +0000
+++ lazarus.w/lcl/interfaces/carbon/carbonobject.inc 2013-11-16 22:03:34.000000000 +0000
+@@ -449,6 +449,62 @@
+ end;
+
+ {------------------------------------------------------------------------------
+ Name: CarbonApp_DragReceive
+ Handles dropping files on application
+ ------------------------------------------------------------------------------}
+function CarbonApp_DragReceive(theWindow: WindowRef; handlerRefCon: UnivPtr; theDrag: DragRef): OSErr; {$IFDEF darwin}mwpascal;{$ENDIF}
+var
+ theItemRef: DragItemRef;
+ theFlavorData: HFSFlavor;
+ theDataSize: Size;
+ theFilename: pchar;
+ theFileRef: FSRef;
+ numItems: UInt16;
+ Files: array of string;
+ itemNum: UInt16;
+begin
+ SetLength(Files, 0);
+
+ numItems := 0;
+
+ if CountDragItems(theDrag, numItems) <> noErr then exit;
+
+ if numItems > 0 then
+ for itemNum := 1 to numItems do
+ begin
+ if GetDragItemReferenceNumber(theDrag, itemNum, theItemRef) <> noErr then continue;
+ theDataSize := sizeof(theFlavorData);
+ if GetFlavorData(theDrag, theItemRef, kDragFlavorTypeHFS, @theFlavorData, theDataSize, 0) <> noErr then continue;
+
+ FSpMakeFSRef(theFlavorData.fileSpec, theFileRef);
+
+ theFilename := stralloc(1024); //PATH_MAX = 1024
+
+ FSRefMakePath(theFileRef, theFilename, StrBufSize(theFilename));
+
+ try
+ SetLength(Files, Length(Files) + 1);
+ Files[High(Files)] := theFilename;
+ finally
+ StrDispose(theFilename);
+ end;
+ end;
+
+ if Length(Files) > 0 then
+ begin
+ if Application <> nil then
+ begin
+ if Application.MainForm <> nil then
+ Application.MainForm.IntfDropFiles(Files);
+
+ Application.IntfDropFiles(Files);
+ end;
+ end;
+
+ Result := noErr;
+end;
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_Quit
+ Handles application quit
+ ------------------------------------------------------------------------------}
+@@ -1213,6 +1269,8 @@
+ InstallApplicationEventHandler(RegisterEventHandler(@CarbonApp_LazWake),
+ 1, @TmpSpec, nil, @FAEventHandlerRef[5]);
+
+ InstallReceiveHandler(@CarbonApp_DragReceive, nil, nil);
+
+ FOpenEventHandlerUPP := NewAEEventHandlerUPP(AEEventHandlerProcPtr(@CarbonApp_Open));
+ FQuitEventHandlerUPP := NewAEEventHandlerUPP(AEEventHandlerProcPtr(@CarbonApp_Quit));
+ OSError(
diff --git a/drop_patch.txt b/drop_patch.txt
new file mode 100644
index 0000000..56d4705
--- /dev/null
+++ b/drop_patch.txt
@@ -0,0 +1,1620 @@
+{%MainUnit carbonint.pas}
+
+{******************************************************************************
+ All utility method implementations of the TCarbonWidgetSet class are here.
+
+
+ ******************************************************************************
+ Implementation
+ ******************************************************************************
+
+ *****************************************************************************
+ This file is part of the Lazarus Component Library (LCL)
+
+ See the file COPYING.modifiedLGPL.txt, included in this distribution,
+ for details about the license.
+ *****************************************************************************
+}
+
+{ TCarbonWidgetSet }
+
+{
+ This event handler will fix the focus indication in AXApplication for
+ standard controls where it gets it wrong. Necessary to support accessibility
+ for TMemo / TEdit for example
+}
+function AppAccessibilityEventHandler(inHandlerCallRef: EventHandlerCallRef;
+ inEvent: EventRef;
+ {%H-}inUserData: Pointer): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
+var
+ lAXRole, lInputStr: CFStringRef;
+ lInputAXObject: AXUIElementRef;
+ EventKind: UInt32;
+ lInputPasStr: string;
+ lElement, lElement2: AXUIElementRef;
+ lAXArray: CFMutableArrayRef;
+begin
+ Result := CallNextEventHandler(inHandlerCallRef, inEvent);
+
+ GetEventParameter(inEvent, kEventParamAccessibleObject,
+ typeCFTypeRef, nil, SizeOf(AXUIElementRef), nil, @lInputAXObject);
+
+ EventKind := GetEventKind(inEvent);
+ case EventKind of
+ kEventAccessibleGetNamedAttribute:
+ begin
+ GetEventParameter(inEvent, kEventParamAccessibleAttributeName,
+ typeCFStringRef, nil, SizeOf(CFStringRef), nil, @lInputStr);
+
+ lInputPasStr := CFStringToStr(lInputStr);
+
+ if lInputPasStr = 'AXFocusedUIElement' then
+ begin
+ // First interfere only if the element returned is in our black list
+ // for example: memo border
+ GetEventParameter(inEvent, kEventParamAccessibleAttributeValue,
+ typeCFTypeRef, nil, SizeOf(AXUIElementRef), nil, @lElement);
+
+ AXUIElementCopyAttributeValue(lElement, CFSTR('AXRoleDescription'), lAXRole{%H-});
+ lInputPasStr := CFStringToStr(lAXRole);
+ if lInputPasStr = 'memoborder' then
+ begin
+ AXUIElementCopyAttributeValue(lElement, CFSTR('AXChildren'), lAXArray{%H-});
+ lElement2 := CFArrayGetValueAtIndex(lAXArray, 0);
+ SetEventParameter(inEvent, kEventParamAccessibleAttributeValue, typeCFTypeRef,
+ SizeOf(AXUIElementRef), @lElement2);
+
+ Result := noErr;
+ Exit;
+ end;
+ end;
+ end; // kEventAccessibleGetNamedAttribute
+ end; // case EventKind of
+end;
+
+{
+The only drawback to making your own event loop dispatching calls in the main
+application thread is that you won't get the standard application event handler
+installed. Specifically, the RunApplicationEventLoop function installs handlers
+to do the following:
+* Allow clicks in the menu bar to begin menu tracking
+* Dispatch Apple events by calling AEProcessAppleEvent
+* Respond to quit Apple events by quitting RunApplicationEventLoop.
+
+One way to work around this limitation is by creating a dummy custom event
+handler. When you are ready to process events, create the dummy event yourself,
+post it to the queue and then call RunApplicationEventLoop (to install the
+standard application event handler). The dummy event handler can then process
+the events manually. For an example of using this method, see Technical
+Q&A 1061 in Developer Documentation Technical Q&As.
+
+}
+
+// From: Technical Q&A 1061 in Developer Documentation Technical Q&As
+// MWE: modified to fit the LCL, but the basic idea comes from Q&A 1061
+
+function QuitEventHandler(inHandlerCallRef: EventHandlerCallRef;
+ inEvent: EventRef;
+ {%H-}inUserData: Pointer): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
+ // This event handler is used to override the kEventClassApplication
+ // kEventAppQuit event while inside our event loop (EventLoopEventHandler).
+ // It simply calls through to the next handler and, if that handler returns
+ // noErr (indicating that the application is doing to quit), it sets
+ // a Boolean to tell our event loop to quit as well.
+ // MWE: in our case, terminates the app also
+begin
+ Result := CallNextEventHandler(inHandlerCallRef, inEvent);
+ if Result <> noErr then Exit;
+
+ if (Widgetset <> nil) and TCarbonWidgetSet(Widgetset).FTerminating then Exit;
+
+ TCarbonWidgetSet(Widgetset).FTerminating := True;
+
+ if Application = nil then Exit;
+ Application.Terminate;
+end;
+
+
+function EventLoopEventHandler({%H-}inHandlerCallRef: EventHandlerCallRef;
+ {%H-}inEvent: EventRef;
+ inUserData: Pointer): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
+ // This code contains the standard Carbon event dispatch loop,
+ // as per "Inside Macintosh: Handling Carbon Events", Listing 3-10,
+ // except:
+ //
+ // o this loop supports yielding to cooperative threads based on the
+ // application maintaining the gNumberOfRunningThreads global
+ // variable, and
+ //
+ // o it also works around a problem with the Inside Macintosh code
+ // which unexpectedly quits when run on traditional Mac OS 9.
+ //
+ // See RunApplicationEventLoopWithCooperativeThreadSupport for
+ // an explanation of why this is inside a Carbon event handler.
+ //
+ // The code in Inside Mac has a problem in that it quits the
+ // event loop when ReceiveNextEvent returns an error. This is
+ // wrong because ReceiveNextEvent can return eventLoopQuitErr
+ // when you call WakeUpProcess on traditional Mac OS. So, rather
+ // than relying on an error from ReceiveNextEvent, this routine tracks
+ // whether the application is really quitting by installing a
+ // customer handler for the kEventClassApplication/kEventAppQuit
+ // Carbon event. All the custom handler does is call through
+ // to the previous handler and, if it returns noErr (which indicates
+ // the application is quitting, it sets quitNow so that our event
+ // loop quits.
+ //
+ // Note that this approach continues to support QuitApplicationEventLoop,
+ // which is a simple wrapper that just posts a kEventClassApplication/
+ // kEventAppQuit event to the event loop.
+
+var
+ QuitUPP: EventHandlerUPP;
+ QuitHandler: EventHandlerRef;
+ TmpSpec: EventTypeSpec;
+ Loop: TApplicationMainLoop = nil;
+begin
+ // Get our TApplicationMainLoop
+ Result := noErr;
+ if (not Assigned(inUserData)) or TCarbonWidgetSet(inUserData).FUserTerm then Exit;
+ Loop := TCarbonWidgetSet(inUserData).FAppLoop;
+ if not Assigned(Loop) then Exit;
+
+ // Install our override on the kEventClassApplication, kEventAppQuit event.
+ QuitUPP := NewEventHandlerUPP(EventHandlerProcPtr(Pointer(@QuitEventHandler)));
+ //todo: raise exception ??
+ if QuitUPP = nil then Exit;
+
+ try
+ TmpSpec := MakeEventSpec(kEventClassApplication, kEventAppQuit);
+ if not InstallApplicationEventHandler(QuitUPP, 1, @TmpSpec, nil, @QuitHandler) then Exit;
+ try
+ // Run our event loop until quitNow is set.
+ Loop;
+ finally
+ MacOSAll.RemoveEventHandler(QuitHandler);
+ end;
+ finally
+ DisposeEventHandlerUPP(QuitUPP);
+ end;
+
+(*
+ theTarget := GetEventDispatcherTarget;
+ repeat
+ if MNumberOfRunningThreads = 0
+ then timeToWaitForEvent := kEventDurationForever
+ else timeToWaitForEvent := kEventDurationNoWait;
+
+ Result := ReceiveNextEvent(0, nil, timeToWaitForEvent, true, theEvent);
+ if Result = noErr
+ then begin
+ SendEventToEventTarget(theEvent, theTarget);
+ ReleaseEvent(theEvent);
+ end;
+ if MNumberOfRunningThreads > 0
+ then YieldToAnyThread;
+ until quitNow;
+*)
+end;
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_CommandProcess
+ Handles main menu and context menus commands
+ ------------------------------------------------------------------------------}
+function CarbonApp_CommandProcess(ANextHandler: EventHandlerCallRef;
+ AEvent: EventRef;
+ {%H-}AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
+var
+ Command: HICommandExtended;
+ CarbonMenu: TCarbonMenu;
+ Msg: TLMessage;
+ S: LongWord;
+ AllowMenu: Boolean;
+ Focused: HWND;
+ HotChar: Char;
+const SName = 'CarbonApp_CommandProcess';
+begin
+ {$IFDEF VerboseAppEvent}
+ DebugLn('CarbonApp_CommandProcess');
+ {$ENDIF}
+
+ if not OSError(
+ GetEventParameter(AEvent, kEventParamDirectObject,
+ typeHICommand, nil, SizeOf(HICommand), nil, @Command),
+ SName, 'GetEventParameter') then
+ begin
+ {$IFDEF VerboseMenu}
+ DebugLn('CarbonApp_CommandProcess MenuRef: ' + DbgS(Command.menuRef) +
+ ' Item: ' + DbgS(Command.menuItemIndex) + ' CommandID: ' + DbgS(Command.commandID) +
+ ' Attrs: ' + DbgS(Command.attributes));
+ {$ENDIF}
+
+ // check command and send "click" message to menu item
+ if (Command.commandID = MENU_FOURCC) and
+ (Command.attributes and kHICommandFromMenu > 0) and
+ (Command.menuRef <> nil) then
+ begin
+ if not OSError(GetMenuItemProperty(Command.menuRef, Command.menuItemIndex,
+ LAZARUS_FOURCC, WIDGETINFO_FOURCC, SizeOf(TCarbonMenu), S{%H-}, @CarbonMenu),
+ SName, 'GetMenuItemProperty') then
+ begin
+ {$IFDEF VerboseMenu}
+ DebugLn('CarbonApp_CommandProcess CarbonMenu: ' + DbgS(CarbonMenu));
+ {$ENDIF}
+ if CarbonMenu <> nil then
+ begin
+ Hotchar:=CarbonMenu.GetShortCutKey;
+ { CommandProcess is fired before a keyboard event }
+ { we must check if the control has default system handlers on the hot-key used }
+ { if so, CommandProcess is not processed, and the key values event are sent }
+ { to the control by the system. }
+ { }
+ { Another possible solution of the problem, is to Post another custom event }
+ { to the loop, and report LCL about Menu pressed after the event arrives, }
+ { though it might seem, like interface is lagging }
+ if (CarbonMenu.Parent.Dismissed<>kHIMenuDismissedBySelection) and (HotChar<>#0) then
+ begin
+ AllowMenu := True;
+ Focused:=GetFocus;
+ if (Focused<>0) and (TObject(Focused) is TCarbonControl) then
+ begin
+ TCarbonControl(Focused).AllowMenuProcess(HotChar, GetCarbonShiftState, AllowMenu);
+ if not AllowMenu then
+ begin
+ Result:=eventNotHandledErr;
+ CarbonMenu.Parent.Dismissed:=0;
+ Exit;
+ end;
+ end;
+ end;
+
+ if CarbonMenu.Parent.Dismissed=kHIMenuDismissedBySelection then begin
+ FillChar(Msg{%H-}, SizeOf(Msg), 0);
+ Msg.msg := LM_ACTIVATE;
+ CarbonMenu.LCLMenuItem.Dispatch(Msg);
+ if assigned(CarbonMenu.Parent) then // if parent not closed
+ CarbonMenu.Parent.Dismissed:=0;
+ Result := noErr;
+ Exit;
+ end else
+ Result:=CallNextEventHandler(ANextHandler, AEvent);
+
+ end;
+ end;
+ end;
+ end;
+
+ Result := CallNextEventHandler(ANextHandler, AEvent);
+end;
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_Shown
+ Handles application show
+ ------------------------------------------------------------------------------}
+function CarbonApp_Shown(ANextHandler: EventHandlerCallRef;
+ AEvent: EventRef;
+ {%H-}AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
+begin
+ {$IFDEF VerboseAppEvent}
+ DebugLn('CarbonApp_Shown');
+ {$ENDIF}
+
+ Result := CallNextEventHandler(ANextHandler, AEvent);
+
+ Application.IntfAppRestore;
+end;
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_Hidden
+ Handles application hide
+ ------------------------------------------------------------------------------}
+function CarbonApp_Hidden(ANextHandler: EventHandlerCallRef;
+ AEvent: EventRef;
+ {%H-}AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
+begin
+ {$IFDEF VerboseAppEvent}
+ DebugLn('CarbonApp_Hidden');
+ {$ENDIF}
+
+ Result := CallNextEventHandler(ANextHandler, AEvent);
+
+ Application.IntfAppMinimize;
+end;
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_Deactivated
+ Handles application deactivation
+ ------------------------------------------------------------------------------}
+function CarbonApp_Deactivated(ANextHandler: EventHandlerCallRef;
+ AEvent: EventRef;
+ {%H-}AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
+begin
+ {$IFDEF VerboseAppEvent}
+ DebugLn('CarbonApp_Deactivate');
+ {$ENDIF}
+
+ Result := CallNextEventHandler(ANextHandler, AEvent);
+
+ Application.IntfAppDeactivate;
+end;
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_Activated
+ Handles application activation
+ ------------------------------------------------------------------------------}
+function CarbonApp_Activated(ANextHandler: EventHandlerCallRef;
+ AEvent: EventRef;
+ {%H-}AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
+begin
+ {$IFDEF VerboseAppEvent}
+ DebugLn('CarbonApp_Activate');
+ {$ENDIF}
+
+ Result := CallNextEventHandler(ANextHandler, AEvent);
+
+ Application.IntfAppActivate;
+end;
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_Activated
+ Handles application activation
+ ------------------------------------------------------------------------------}
+function CarbonApp_LazWake(ANextHandler: EventHandlerCallRef;
+ AEvent: EventRef;
+ {%H-}AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
+begin
+ {$IFDEF VerboseAppEvent}
+ DebugLn('CarbonApp_LazWake');
+ {$ENDIF}
+
+ Result := CallNextEventHandler(ANextHandler, AEvent);
+
+ if IsMultiThread then
+ begin
+ // a thread is waiting -> synchronize
+ CheckSynchronize;
+ end;
+end;
+
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_Open
+ Handles application open
+ ------------------------------------------------------------------------------}
+function CarbonApp_Open(var AEvent: AppleEvent; var {%H-}Reply: AppleEvent;
+ {%H-}Data: SInt32): OSErr; {$IFDEF darwin}mwpascal;{$ENDIF}
+var
+ DocList: AEDescList;
+ FileCount: Integer;
+ FileIdx: Integer;
+ Keyword: AEKeyword;
+ FileDesc: AEDesc;
+ FileRef: FSRef;
+ FileURL: CFURLRef;
+ FileCFStr: CFStringRef;
+ Files: Array of String;
+const
+ SName = 'OpenDocEventHandler';
+begin
+ {$IFDEF VerboseAppEvent}
+ DebugLn('CarbonApp_Open');
+ {$ENDIF}
+
+ if OSError(AEGetParamDesc(AEvent, keyDirectObject, typeAEList, DocList{%H-}),
+ SName, 'AEGetParamDesc') then Exit;
+
+ try
+ if OSError(AECountItems(DocList, FileCount{%H-}), SName, 'AECountItems') then Exit;
+
+
+ SetLength(Files, 0);
+
+ for FileIdx := 1 to FileCount do
+ begin
+ if OSError(AEGetNthDesc(DocList, FileIdx, typeFSRef, @Keyword, FileDesc{%H-}),
+ SName, 'AEGetNthDesc') then Continue;
+
+ if OSError(AEGetDescData(FileDesc, @FileRef, SizeOf(FSRef)),
+ SName, 'AEGetDescData') then Continue;
+
+ if OSError(AEDisposeDesc(FileDesc),
+ SName, 'AEDisposeDesc') then Continue;
+
+ FileURL := CFURLCreateFromFSRef(kCFAllocatorDefault, FileRef);
+ FileCFStr := CFURLCopyFileSystemPath(FileURL, kCFURLPOSIXPathStyle);
+ try
+ SetLength(Files, Length(Files) + 1);
+ Files[High(Files)] := CFStringToStr(FileCFStr);
+ finally
+ FreeCFString(FileURL);
+ FreeCFString(FileCFStr);
+ end;
+ end;
+
+ if Length(Files) > 0 then
+ begin
+ if Application <> nil then
+ begin
+ if Application.MainForm <> nil then
+ Application.MainForm.IntfDropFiles(Files);
+
+ Application.IntfDropFiles(Files);
+ end;
+ end;
+ finally
+ AEDisposeDesc(DocList);
+ end;
+
+ Result := noErr;
+end;
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_DragReceive
+ Handles dropping files on application
+ ------------------------------------------------------------------------------}
+function CarbonApp_DragReceive(theWindow: WindowRef; handlerRefCon: UnivPtr; theDrag: DragRef): OSErr; {$IFDEF darwin}mwpascal;{$ENDIF}
+var
+ theItemRef: DragItemRef;
+ theFlavorData: HFSFlavor;
+ theDataSize: Size;
+ theFilename: pchar;
+ theFileRef: FSRef;
+ numItems: UInt16;
+ Files: array of string;
+ itemNum: UInt16;
+begin
+ SetLength(Files, 0);
+
+ numItems := 0;
+
+ if CountDragItems(theDrag, numItems) <> noErr then exit;
+
+ if numItems > 0 then
+ for itemNum := 1 to numItems do
+ begin
+ if GetDragItemReferenceNumber(theDrag, itemNum, theItemRef) <> noErr then continue;
+ theDataSize := sizeof(theFlavorData);
+ if GetFlavorData(theDrag, theItemRef, kDragFlavorTypeHFS, @theFlavorData, theDataSize, 0) <> noErr then continue;
+
+ FSpMakeFSRef(theFlavorData.fileSpec, theFileRef);
+
+ theFilename := stralloc(1024); //PATH_MAX = 1024
+
+ FSRefMakePath(theFileRef, theFilename, StrBufSize(theFilename));
+
+ try
+ SetLength(Files, Length(Files) + 1);
+ Files[High(Files)] := theFilename;
+ finally
+ StrDispose(theFilename);
+ end;
+ end;
+
+ if Length(Files) > 0 then
+ begin
+ if Application <> nil then
+ begin
+ if Application.MainForm <> nil then
+ Application.MainForm.IntfDropFiles(Files);
+
+ Application.IntfDropFiles(Files);
+ end;
+ end;
+
+ Result := noErr;
+end;
+
+{------------------------------------------------------------------------------
+ Name: CarbonApp_Quit
+ Handles application quit
+ ------------------------------------------------------------------------------}
+function CarbonApp_Quit(var {%H-}AEvent: AppleEvent; var {%H-}Reply: AppleEvent;
+ {%H-}Data: SInt32): OSErr; {$IFDEF darwin}mwpascal;{$ENDIF}
+begin
+ {$IFDEF VerboseAppEvent}
+ DebugLn('CarbonApp_Quit');
+ {$ENDIF}
+
+ if (Application <> nil) and (Application.MainForm <> nil) then
+ begin
+ Application.MainForm.Close;
+ end;
+
+ Result := noErr;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.AppInit
+ Params: ScreenInfo
+
+ Initialize Carbon Widget Set
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.AppInit(var ScreenInfo: TScreenInfo);
+var
+ ScreenDC: HDC;
+begin
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppInit');
+ {$ENDIF}
+
+ WakeMainThread := @OnWakeMainThread;
+
+ // fill the screen info
+ ScreenDC := GetDC(0);
+ try
+ ScreenInfo.PixelsPerInchX := GetDeviceCaps(ScreenDC, LOGPIXELSX);
+ ScreenInfo.PixelsPerInchY := GetDeviceCaps(ScreenDC, LOGPIXELSY);
+ ScreenInfo.ColorDepth := GetDeviceCaps(ScreenDC, BITSPIXEL);
+ finally
+ ReleaseDC(0, ScreenDC);
+ end;
+
+ fMainEventQueue:=GetMainEventQueue;
+
+
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.AppRun
+ Params: ALoop
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.AppRun(const ALoop: TApplicationMainLoop);
+ // A reimplementation of RunApplicationEventLoop that supports
+ // yielding time to cooperative threads. It relies on the
+ // rest of your application to maintain a global variable,
+ // gNumberOfRunningThreads, that reflects the number of threads
+ // that are ready to run.
+var
+ DummyEvent: EventRef;
+ EventSpec: EventTypeSpec;
+ EventLoopUPP, AccessibilityUPP: EventHandlerUPP;
+ EventLoopHandler, AccessibilityHandle: EventHandlerRef;
+begin
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppRun');
+ {$ENDIF}
+ FAppLoop:=ALoop;
+ DummyEvent := nil;
+
+ // Accessibility for AXApplication
+ AccessibilityUPP := NewEventHandlerUPP(EventHandlerProcPtr(Pointer(@AppAccessibilityEventHandler)));
+ EventSpec := MakeEventSpec(kEventClassAccessibility, kEventAccessibleGetNamedAttribute);
+ InstallApplicationEventHandler(AccessibilityUPP, 1, @EventSpec, Self, @AccessibilityHandle);
+
+ // Create a UPP for EventLoopEventHandler and QuitEventHandler
+
+ EventLoopUPP := NewEventHandlerUPP(EventHandlerProcPtr(
+ Pointer(@EventLoopEventHandler)));
+ if EventLoopUPP = nil then
+ RaiseGDBException('TCarbonWidgetSet.InitMainLoop no eventhandler');
+
+ // Install EventLoopEventHandler, create a dummy event and post it,
+ // and then call RunApplicationEventLoop. The rationale for this
+ // is as follows: We want to unravel RunApplicationEventLoop so
+ // that we can can yield to cooperative threads. In fact, the
+ // core code for RunApplicationEventLoop is pretty easy (you
+ // can see it above in EventLoopEventHandler). However, if you
+ // just execute this code you miss out on all the standard event
+ // handlers. These are relatively easy to reproduce (handling
+ // the quit event and so on), but doing so is a pain because
+ // a) it requires a bunch boilerplate code, and b) if Apple
+ // extends the list of standard event handlers, your application
+ // wouldn't benefit. So, we execute our event loop from within
+ // a Carbon event handler that we cause to be executed by
+ // explicitly posting an event to our event loop. Thus, the
+ // standard event handlers are installed while our event loop runs.
+
+ EventSpec := MakeEventSpec(LCLCarbonEventClass, LCLCarbonEventKindMain);
+ if not InstallApplicationEventHandler(EventLoopUPP, 1, @EventSpec, Self,
+ @EventLoopHandler) then Exit;
+ try
+ if CreateEvent(nil, EventSpec.eventClass, EventSpec.eventKind, 0,
+ kEventAttributeNone, DummyEvent) <> noErr
+ then
+ RaiseGDBException('TCarbonWidgetSet.InitMainLoop create first dummy event failed');
+
+ try
+ {if SetEventParameter(DummyEvent, MakeFourCC('Loop'),
+ MakeFourCC('TAML'), SizeOf(ALoop),
+ @ALoop) <> noErr
+ then
+ RaiseGDBException('TCarbonWidgetSet.InitMainLoop setparam to first event failed');}
+
+ //DebuglnThrea dLog('TCarbonWidgetSet.AppRun '+dbgs(GetMainEventQueue));
+ if PostEventToQueue(FMainEventQueue, DummyEvent,
+ kEventPriorityHigh) <> noErr
+ then
+ RaiseGDBException('TCarbonWidgetSet.AppRun post dummy event failed');
+ finally
+ ReleaseEvent(DummyEvent);
+ end;
+
+ SignalFirstAppEvent;
+ if not FUserTerm then
+ begin
+ RunApplicationEventLoop;
+ end;
+ FAppStdEvents:=True;
+
+ finally
+ MacOSAll.RemoveEventHandler(EventLoopHandler);
+ DisposeEventHandlerUPP(EventLoopUPP);
+ end;
+
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppRun END');
+ {$ENDIF}
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.AppProcessMessages
+
+ Handle all pending messages
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.AppProcessMessages;
+var
+ Target: EventTargetRef;
+ Event: EventRef;
+ CurEventClass: TEventInt;
+ CurEventKind: TEventInt;
+begin
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppProcessMessages');
+ {$ENDIF}
+
+ if not FAppStdEvents then InstallStandardEventHandler(GetApplicationEventTarget);
+
+ Target := GetEventDispatcherTarget;
+ CurEventClass.Chars[4] := #0;
+ CurEventKind.Chars[4] := #0;
+ repeat
+ FreePendingWidgets;
+ if ReceiveNextEvent(0, nil, kEventDurationNoWait, True,
+ Event{%H-}) <> noErr then Break;
+
+ CurEventClass.Int := GetEventClass(Event);
+ CurEventKind.Int := GetEventKind(Event);
+
+ {$IFDEF DebugEventLoop}
+ DebugLn('EventClass: "',CurEventClass.Chars,'" EventKind: ',IntToStr(CurEventKind.Int));
+ {$ENDIF}
+
+ if CurEventClass.Chars = LCLCarbonEventClass then
+ begin
+ // internal carbon intf message
+ {$IFDEF DebugEventLoop}
+ DebugLn('EventKind: ',CurEventKind.Chars);
+ {$ENDIF}
+ if (CurEventKind.Chars = LCLCarbonEventKindUser) then
+ begin
+ end;
+ end;
+
+ SendEventToEventTarget(Event, Target);
+ ReleaseEvent(Event);
+
+ if Clipboard <> nil then
+ if Clipboard.OwnerShips > 0 then Clipboard.CheckOwnerShip;
+
+ until Application.Terminated;
+
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppProcessMessages END');
+ {$ENDIF}
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.AppWaitMessage
+
+ Passes execution control to Carbon
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.AppWaitMessage;
+var
+ Event: EventRef;
+begin
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppWaitMessage');
+ {$ENDIF}
+
+ // Simply wait forever for the next event.
+ // Don't pull it, so we can handle it later.
+ OSError(ReceiveNextEvent(0, nil, kEventDurationForever, False, Event{%H-}),
+ Self, 'AppWaitMessage', 'ReceiveNextEvent');
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.Create
+
+ Constructor for the class
+ ------------------------------------------------------------------------------}
+constructor TCarbonWidgetSet.Create;
+begin
+ CarbonWidgetSet := Self;
+ inherited Create;
+ FTerminating := False;
+ fMenuEnabled := True;
+
+ FTimerMap := TMap.Create(its4, SizeOf(TWSTimerProc));
+ FCurrentCursor := 0;
+ FMainMenu := 0;
+ FCaptureWidget := 0;
+
+ RegisterEvents;
+
+ { if using Cocoa, we need an autorelease pool
+ and we also need to initialize NSApplication }
+ {$ifdef CarbonUseCocoa}
+ pool := NSAutoreleasePool.Create;
+
+ NSApplicationLoad();
+ {$endif}
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.Destroy
+
+ Destructor for the class
+ ------------------------------------------------------------------------------}
+destructor TCarbonWidgetSet.Destroy;
+begin
+ CaretWidgetSetReleased;
+
+ FreeAndNil(FTimerMap);
+ DisposeAEEventHandlerUPP(FOpenEventHandlerUPP);
+ DisposeAEEventHandlerUPP(FQuitEventHandlerUPP);
+
+ inherited Destroy;
+ CarbonWidgetSet := nil;
+
+ // if using Cocoa, release autorelease the pool
+ {$ifdef CarbonUseCocoa}
+ if pool <> nil then pool.Free;
+ {$endif}
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.RawImage_DescriptionFromCarbonBitmap
+
+ Creates a rawimage description for a carbonbitmap
+ ------------------------------------------------------------------------------}
+function TCarbonWidgetSet.RawImage_DescriptionFromCarbonBitmap(out ADesc: TRawImageDescription; ABitmap: TCarbonBitmap): Boolean;
+var
+ Prec, Shift, BPR: Byte;
+ AlphaInfo: CGImageAlphaInfo;
+begin
+ ADesc.Init;
+
+ case ABitmap.BitmapType of
+ cbtMono, cbtGray: ADesc.Format := ricfGray;
+ else
+ ADesc.Format := ricfRGBA;
+ end;
+
+ ADesc.Width := CGImageGetWidth(ABitmap.CGImage);
+ ADesc.Height := CGImageGetHeight(ABitmap.CGImage);
+
+ //ADesc.PaletteColorCount := 0;
+
+ ADesc.BitOrder := riboReversedBits;
+ ADesc.ByteOrder := riboMSBFirst;
+
+ BPR := CGImageGetBytesPerRow(ABitmap.CGImage) and $FF;
+ if BPR and $F = 0 then ADesc.LineEnd := rileDQWordBoundary // 128bit aligned
+ else if BPR and $7 = 0 then ADesc.LineEnd := rileQWordBoundary // 64bit aligned
+ else if BPR and $3 = 0 then ADesc.LineEnd := rileWordBoundary // 32bit aligned
+ else if BPR and $1 = 0 then ADesc.LineEnd := rileByteBoundary // 8bit aligned
+ else ADesc.LineEnd := rileTight;
+
+ ADesc.LineOrder := riloTopToBottom;
+ ADesc.BitsPerPixel := CGImageGetBitsPerPixel(ABitmap.CGImage);
+
+ ADesc.MaskBitOrder := riboReversedBits;
+ ADesc.MaskBitsPerPixel := 1;
+ ADesc.MaskLineEnd := rileByteBoundary;
+ // ADesc.MaskShift := 0;
+
+ Prec := CGImageGetBitsPerComponent(ABitmap.CGImage) and $FF;
+ AlphaInfo := CGImageGetAlphaInfo(ABitmap.CGImage);
+
+ if AlphaInfo <> kCGImageAlphaOnly
+ then begin
+ ADesc.RedPrec := Prec;
+ ADesc.GreenPrec := Prec;
+ ADesc.BluePrec := Prec;
+ end;
+
+ // gray or mono
+ if ADesc.Format = ricfGray then begin
+ ADesc.Depth := 1;
+ Exit;
+ end;
+
+ // alpha
+ case AlphaInfo of
+ kCGImageAlphaNone,
+ kCGImageAlphaNoneSkipLast,
+ kCGImageAlphaNoneSkipFirst: begin
+ ADesc.Depth := Prec * 3;
+ // ADesc.AlphaPrec := 0;
+ end;
+ else
+ ADesc.Depth := Prec * 4;
+ ADesc.AlphaPrec := Prec;
+ end;
+
+ case AlphaInfo of
+ kCGImageAlphaNone,
+ kCGImageAlphaNoneSkipLast: begin
+ // RGBx
+ Shift := 32 - Prec;
+ ADesc.RedShift := Shift;
+ Dec(Shift, Prec);
+ ADesc.GreenShift := Shift;
+ Dec(Shift, Prec);
+ ADesc.BlueShift := Shift;
+ end;
+ kCGImageAlphaNoneSkipFirst: begin
+ // xRGB
+ Shift := 0;
+ ADesc.BlueShift := Shift;
+ Inc(Shift, Prec);
+ ADesc.GreenShift := Shift;
+ Inc(Shift, Prec);
+ ADesc.RedShift := Shift;
+ end;
+ kCGImageAlphaPremultipliedFirst,
+ kCGImageAlphaFirst: begin
+ // ARGB
+ Shift := 32 - Prec;
+ ADesc.AlphaShift := Shift;
+ Dec(Shift, Prec);
+ ADesc.RedShift := Shift;
+ Dec(Shift, Prec);
+ ADesc.GreenShift := Shift;
+ Dec(Shift, Prec);
+ ADesc.BlueShift := Shift;
+ end;
+ kCGImageAlphaPremultipliedLast,
+ kCGImageAlphaLast: begin
+ // RGBA
+ Shift := 32 - Prec;
+ ADesc.RedShift := Shift;
+ Dec(Shift, Prec);
+ ADesc.GreenShift := Shift;
+ Dec(Shift, Prec);
+ ADesc.BlueShift := Shift;
+ Dec(Shift, Prec);
+ ADesc.AlphaShift := Shift;
+ end;
+ kCGImageAlphaOnly: begin
+ // A
+ //ADesc.AlphaShift := 0;
+ end;
+ end;
+
+ Result := True;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.RawImage_FromCarbonBitmap
+
+ Creates a rawimage description for a carbonbitmap
+ ------------------------------------------------------------------------------}
+function TCarbonWidgetSet.RawImage_FromCarbonBitmap(out ARawImage: TRawImage; ABitmap, AMask: TCarbonBitmap; ARect: PRect = nil): Boolean;
+var Width, Height: Integer;
+ R: TRect;
+ WorkData: PByte = nil;
+ MaskData: PByte = nil;
+ MaskDataSize, WorkDataSize: PtrUInt;
+
+ function CreateSub(ARect: TRect; ABmp: TCarbonBitMap; BitsPerPixel: Integer; var ImageDataSize: PtrUInt): PByte;
+ var FullImageData, BytePtr: PByte;
+ SubImageBytesPerRow, DataSize: PtrUInt;
+ ShiftBits, RowCnt, RowByteCnt: Integer;
+ begin
+
+ SubImageBytesPerRow := (((ARect.Right - ARect.Left) * BitsPerPixel) + 7) div 8;
+ if (BitsPerPixel > 1) then
+ SubImageBytesPerRow := ((((Arect.Right - ARect.Left) * (BitsPerPixel div 8)) + $F) and not PtrUInt($F));
+ DataSize := SubImageBytesPerRow {%H-}* (ARect.Bottom - ARect.Top);
+ Result := System.GetMem(DataSize);
+ if (Result = nil) then RaiseMemoryAllocationError;
+
+ BytePtr := Result;
+ ShiftBits := (ARect.Left * BitsPerPixel) mod 8;
+ FullImageData := ABmp.Data + ((ARect.Left * BitsPerPixel) div 8);
+
+ For RowCnt := 0 to ((ARect.Bottom - ARect.Top) - 1) do begin
+ For RowByteCnt := 0 to (SubImageBytesPerRow - 1) do begin
+ BytePtr^ := (Byte((PByte(FullImageData + RowByteCnt)^ Shl ShiftBits)) or
+ (PByte(FullImageData + RowByteCnt + 1)^ Shr (8 - ShiftBits)));
+ Inc(BytePtr);
+ end;
+ Inc(FullImageData, ABmp.BytesPerRow);
+ end;
+ ImageDataSize := DataSize;
+ end;
+
+begin
+ Result := False;
+
+ FillChar(ARawImage{%H-}, SizeOf(ARawImage), 0);
+ ARawImage.Init;
+ RawImage_DescriptionFromCarbonBitmap(ARawImage.Description, ABitmap);
+
+ if ARect = nil
+ then begin
+ Width := ABitmap.Width;
+ Height := ABitmap.Height;
+ end
+ else begin
+ R := ARect^;
+ Width := R.Right - R.Left;
+ Height := R.Bottom - R.Top;
+ end;
+
+ if Width > ABitmap.Width then
+ Width := ABitmap.Width;
+
+ if Height > ABitmap.Height then
+ Height := ABitmap.Height;
+
+ if (Width = ABitmap.Width) and (Height = ABitmap.Height)
+ then begin
+ WorkData := ABitmap.Data;
+ WorkDataSize := ABitmap.DataSize;
+ if AMask <> nil then begin
+ MaskData := AMask.Data;
+ MaskDataSize := AMask.DataSize;
+ end;
+ end
+ else begin
+ WorkData := CreateSub(R, ABitmap, ARawImage.Description.BitsPerPixel, WorkDataSize);
+ if AMask <> nil then
+ MaskData := CreateSub(R, AMask, 1, MaskDataSize);
+ end;
+
+ ARawImage.Description.Width := Width;
+ ARawImage.Description.Height := Height;
+
+ ARawImage.DataSize := WorkDataSize;
+ ReAllocMem(ARawImage.Data, ARawImage.DataSize);
+ if ARawImage.DataSize > 0 then
+ System.Move(WorkData^, ARawImage.Data^, ARawImage.DataSize);
+
+ if (WorkData <> ABitmap.Data) then
+ FreeMem(WorkData);
+
+ Result := True;
+
+ if AMask = nil then
+ begin
+ ARawImage.Description.MaskBitsPerPixel := 0;
+ Exit;
+ end;
+
+ if AMask.Depth > 1
+ then begin
+ DebugLn('[WARNING] RawImage_FromCarbonBitmap: AMask.Depth > 1');
+ Exit;
+ end;
+
+ ARawImage.Description.MaskBitsPerPixel := 1;
+ ARawImage.Description.MaskShift := 0;
+ ARawImage.Description.MaskLineEnd := rileByteBoundary;
+ ARawImage.Description.MaskBitOrder := riboReversedBits;
+
+ ARawImage.MaskSize := MaskDataSize;
+ ReAllocMem(ARawImage.Mask, ARawImage.MaskSize);
+ if ARawImage.MaskSize > 0 then
+ System.Move(MaskData^, ARawImage.Mask^, ARawImage.MaskSize);
+
+ if (MaskData <> AMask.Data) then
+ FreeMem(MaskData);
+
+end;
+
+function TCarbonWidgetSet.RawImage_DescriptionToBitmapType(
+ ADesc: TRawImageDescription;
+ out bmpType: TCarbonBitmapType): Boolean;
+begin
+ Result := False;
+
+ if ADesc.Format = ricfGray
+ then
+ begin
+ if ADesc.Depth = 1 then bmpType := cbtMono
+ else bmpType := cbtGray;
+ end
+ else if ADesc.Depth = 1
+ then bmpType := cbtMono
+ else if ADesc.AlphaPrec <> 0
+ then begin
+ if ADesc.ByteOrder = riboMSBFirst
+ then begin
+ if (ADesc.AlphaShift = 24)
+ and (ADesc.RedShift = 16)
+ and (ADesc.GreenShift = 8 )
+ and (ADesc.BlueShift = 0 )
+ then bmpType := cbtARGB
+ else
+ if (ADesc.AlphaShift = 0)
+ and (ADesc.RedShift = 24)
+ and (ADesc.GreenShift = 16 )
+ and (ADesc.BlueShift = 8 )
+ then bmpType := cbtRGBA
+ else
+ if (ADesc.AlphaShift = 0 )
+ and (ADesc.RedShift = 8 )
+ and (ADesc.GreenShift = 16)
+ and (ADesc.BlueShift = 24)
+ then bmpType := cbtBGRA
+ else Exit;
+ end
+ else begin
+ if (ADesc.AlphaShift = 24)
+ and (ADesc.RedShift = 16)
+ and (ADesc.GreenShift = 8 )
+ and (ADesc.BlueShift = 0 )
+ then bmpType := cbtBGRA
+ else
+ if (ADesc.AlphaShift = 0 )
+ and (ADesc.RedShift = 8 )
+ and (ADesc.GreenShift = 16)
+ and (ADesc.BlueShift = 24)
+ then bmpType := cbtARGB
+ else
+ if (ADesc.AlphaShift = 24 )
+ and (ADesc.RedShift = 0 )
+ and (ADesc.GreenShift = 8)
+ and (ADesc.BlueShift = 16)
+ then bmpType := cbtRGBA
+ else Exit;
+ end;
+ end
+ else begin
+ bmpType := cbtRGB;
+ end;
+
+ Result := True;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.GetImagePixelData
+
+ Used by RawImage_FromDevice. Copies the data from a CGImageRef into a local
+ buffer.
+
+ The buffer is created using GetMem, and the caller is responsible for using
+ FreeMem to free the returned pointer.
+
+ This function throws exceptions in case of errors and may return a nil pointer.
+ ------------------------------------------------------------------------------}
+function TCarbonWidgetSet.GetImagePixelData(AImage: CGImageRef; out bitmapByteCount: PtrUInt): Pointer;
+var
+ bitmapData: Pointer;
+ context: CGContextRef = nil;
+ colorSpace: CGColorSpaceRef;
+ bitmapBytesPerRow, pixelsWide, pixelsHigh: PtrUInt;
+ imageRect: CGRect;
+begin
+ Result := nil;
+
+ // Get image width, height. The entire image is used.
+ pixelsWide := CGImageGetWidth(AImage);
+ pixelsHigh := CGImageGetHeight(AImage);
+ imageRect.origin.x := 0.0;
+ imageRect.origin.y := 0.0;
+ imageRect.size.width := pixelsWide;
+ imageRect.size.height := pixelsHigh;
+
+ // The target format is fixed in ARGB, DQWord alignment, with 32-bits depth and
+ // 8-bits per channel, the default image format on the LCL
+ bitmapBytesPerRow := ((pixelsWide * 4) + $F) and not PtrUInt($F);
+ bitmapByteCount := (bitmapBytesPerRow * pixelsHigh);
+
+ // Use the generic RGB color space.
+ colorSpace := CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ if (colorSpace = nil) then RaiseColorSpaceError;
+
+ // Allocate memory for image data. This is the destination in memory
+ // where any drawing to the bitmap context will be rendered.
+ bitmapData := System.GetMem( bitmapByteCount );
+ if (bitmapData = nil) then RaiseMemoryAllocationError;
+
+ { Creates the bitmap context.
+
+ Regardless of what the source image format is, it will be converted
+ over to the format specified here by CGBitmapContextCreate. }
+ context := CGBitmapContextCreate(bitmapData,
+ pixelsWide,
+ pixelsHigh,
+ 8, // bits per component
+ bitmapBytesPerRow,
+ colorSpace,
+ kCGImageAlphaNoneSkipFirst); // The function fails with kCGImageAlphaFirst
+ if (context = nil) then
+ begin
+ System.FreeMem(bitmapData);
+ RaiseContextCreationError;
+ end;
+
+ // Draw the image to the bitmap context. Once we draw, the memory
+ // allocated for the context for rendering will then contain the
+ // raw image data in the specified color space.
+ CGContextDrawImage(context, imageRect, AImage);
+
+ // Now we can get a pointer to the image data associated with the context.
+ // ToDo: Verify if we should copy this data to a new buffer
+ Result := CGBitmapContextGetData(context);
+
+ { Clean-up }
+ CGColorSpaceRelease(colorSpace);
+ CGContextRelease(context);
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.CreateThemeServices
+ Returns: Theme Services object for Carbon interface
+ ------------------------------------------------------------------------------}
+function TCarbonWidgetSet.CreateThemeServices: TThemeServices;
+begin
+ Result := TCarbonThemeServices.Create;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.PassCmdLineOptions
+
+ Not used
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.PassCmdLineOptions;
+begin
+ inherited PassCmdLineOptions;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.SendCheckSynchronizeMessage
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.SendCheckSynchronizeMessage;
+var
+ EventSpec: EventTypeSpec;
+ DummyEvent: EventRef;
+begin
+ if FMainEventQueue=nil then
+ begin
+ //DebugLnThreadLog('TCarbonWidgetSet.SendCheckSynchronizeMessage FMainEventQueue=nil');
+ exit;
+ end;
+
+ {$IFDEF VerboseObject}
+ DebugLnThreadLog('TCarbonWidgetSet.SendCheckSynchronizeMessage START');
+ {$ENDIF}
+
+ EventSpec := MakeEventSpec(LCLCarbonEventClass,LCLCarbonEventKindWake);
+ DummyEvent:=nil;
+ try
+ if CreateEvent(nil, EventSpec.eventClass, EventSpec.eventKind,
+ 0{GetCurrentEventTime}, kEventAttributeNone, DummyEvent) <> noErr then
+ begin
+ {$IFDEF VerboseObject}
+ DebugLnThreadLog('TCarbonWidgetSet.SendCheckSynchronizeMessage Create event FAILED');
+ {$ENDIF}
+ Exit;
+ end;
+
+ {$IFDEF VerboseObject}
+ DebugLnThreadLog('TCarbonWidgetSet.SendCheckSynchronizeMessage GetMainEventQueue='+dbgs(GetMainEventQueue));
+ {$ENDIF}
+
+ if PostEventToQueue(FMainEventQueue, DummyEvent,
+ kEventPriorityHigh) <> noErr then
+ begin
+ {$IFDEF VerboseObject}
+ DebugLnThreadLog('TCarbonWidgetSet.SendCheckSynchronizeMessage Post event FAILED');
+ {$ENDIF}
+ Exit;
+ end;
+ finally
+ if DummyEvent <> nil then ReleaseEvent(DummyEvent);
+ end;
+
+ {$IFDEF VerboseObject}
+ DebugLnThreadLog('TCarbonWidgetSet.SendCheckSynchronizeMessage END');
+ {$ENDIF}
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.OnWakeMainThread
+ Params: Sender
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.OnWakeMainThread(Sender: TObject);
+begin
+ // the code below would start waiting on the first app event to arrive.
+ // however, if fAppLoop has not been initialized and we're in the main thread
+ // we shouldn't wait for it, since signal is given from the main thread.
+ if (GetThreadID=MainThreadID) and (not Assigned(fAppLoop)) then Exit;
+
+ // wait infinite for the first (dummy) event sent to the main event queue
+ WaitFirstAppEvent;
+ SendCheckSynchronizeMessage;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.RegisterEvents
+ Registers events for Carbon application
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.RegisterEvents;
+var
+ TmpSpec: EventTypeSpec;
+const
+ SName = 'RegisterEvents';
+begin
+ //DebugLn('TCarbonWidgetSet.RegisterEvents');
+ TmpSpec := MakeEventSpec(kEventClassCommand, kEventCommandProcess);
+ InstallApplicationEventHandler(RegisterEventHandler(@CarbonApp_CommandProcess),
+ 1, @TmpSpec, nil, @FAEventHandlerRef[0]);
+
+ TmpSpec := MakeEventSpec(kEventClassApplication, kEventAppShown);
+ InstallApplicationEventHandler(RegisterEventHandler(@CarbonApp_Shown),
+ 1, @TmpSpec, nil, @FAEventHandlerRef[1]);
+
+ TmpSpec := MakeEventSpec(kEventClassApplication, kEventAppHidden);
+ InstallApplicationEventHandler(RegisterEventHandler(@CarbonApp_Hidden),
+ 1, @TmpSpec, nil, @FAEventHandlerRef[2]);
+
+ TmpSpec := MakeEventSpec(kEventClassApplication, kEventAppDeactivated);
+ InstallApplicationEventHandler(RegisterEventHandler(@CarbonApp_Deactivated),
+ 1, @TmpSpec, nil, @FAEventHandlerRef[3]);
+
+ TmpSpec := MakeEventSpec(kEventClassApplication, kEventAppActivated);
+ InstallApplicationEventHandler(RegisterEventHandler(@CarbonApp_Activated),
+ 1, @TmpSpec, nil, @FAEventHandlerRef[4]);
+
+ TmpSpec := MakeEventSpec(LCLCarbonEventClass, LCLCarbonEventKindWake);
+ InstallApplicationEventHandler(RegisterEventHandler(@CarbonApp_LazWake),
+ 1, @TmpSpec, nil, @FAEventHandlerRef[5]);
+
+ InstallReceiveHandler(@CarbonApp_DragReceive, nil, nil);
+
+ FOpenEventHandlerUPP := NewAEEventHandlerUPP(AEEventHandlerProcPtr(@CarbonApp_Open));
+ FQuitEventHandlerUPP := NewAEEventHandlerUPP(AEEventHandlerProcPtr(@CarbonApp_Quit));
+ OSError(
+ AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, FOpenEventHandlerUPP, 0, False),
+ Self, SName, 'AEInstallEventHandler');
+ OSError(
+ AEInstallEventHandler(kCoreEventClass, kAEOpenContents, FOpenEventHandlerUPP, 0, False),
+ Self, SName, 'AEInstallEventHandler');
+ OSError(
+ AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, FQuitEventHandlerUPP, 0, False),
+ Self, SName, 'AEInstallEventHandler');
+end;
+
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.AppTerminate
+
+ Tells Carbon to halt the application
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.AppTerminate;
+var i:integer;
+const
+ SName = 'AppTerminate';
+begin
+ if FTerminating then Exit;
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppTerminate');
+ {$ENDIF}
+ FUserTerm:=True;
+ QuitApplicationEventLoop;
+ for i:=Low(FAEventHandlerRef) to High(FAEventHandlerRef) do
+ OSError(MacOSALL.RemoveEventHandler(FAEventHandlerRef[i]),
+ TClass(Self), SName, 'RemoveEventHandler');
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.AppMinimize
+
+ Minimizes the whole application to the taskbar
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.AppMinimize;
+var
+ Proc: ProcessSerialNumber;
+const
+ SName = 'AppMinimize';
+begin
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppMinimize');
+ {$ENDIF}
+
+ // hide process
+ if OSError(GetCurrentProcess(Proc{%H-}), Self, SName, SGetCurrentProc) then Exit;
+ OSError(ShowHideProcess(Proc, False), Self, SName, SShowHideProc);
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.AppRestore
+
+ Restores the whole minimized application from the taskbar
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.AppRestore;
+var
+ Proc: ProcessSerialNumber;
+const
+ SName = 'AppRestore';
+begin
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppRestore');
+ {$ENDIF}
+
+ // show process
+ if OSError(GetCurrentProcess(Proc{%H-}), Self, SName, SGetCurrentProc) then Exit;
+ OSError(ShowHideProcess(Proc, True), Self, SName, SShowHideProc);
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.AppBringToFront
+
+ Brings the entire application on top of all other non-topmost programs
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.AppBringToFront;
+var
+ Proc: ProcessSerialNumber;
+const SName = 'AppBringToFront';
+begin
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.AppBringToFront');
+ {$ENDIF}
+
+ (*
+ According to Carbon Development Tips & Tricks:
+ 34. How do I bring all my windows to the front?
+ *)
+
+ if OSError(GetCurrentProcess(Proc{%H-}), Self, SName, SGetCurrentProc) then Exit;
+ OSError(SetFrontProcess(Proc), Self, SName, 'SetFrontProcess');
+end;
+
+procedure TCarbonWidgetSet.AppSetIcon(const Small, Big: HICON);
+begin
+ if Big <> 0 then
+ SetApplicationDockTileImage(TCarbonBitmap(Big).CGImage)
+ else
+ RestoreApplicationDockTileImage;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.AppSetTitle
+ Params: ATitle - New application title
+
+ Changes the application title
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.AppSetTitle(const ATitle: string);
+begin
+ // not supported
+end;
+
+function TCarbonWidgetSet.GetLCLCapability(ACapability: TLCLCapability): PtrUInt;
+begin
+ case ACapability of
+ lcCanDrawOutsideOnPaint,
+ lcNeedMininimizeAppWithMainForm,
+ lcApplicationTitle,
+ lcFormIcon,
+ lcReceivesLMClearCutCopyPasteReliably:
+ Result := LCL_CAPABILITY_NO;
+ lcAntialiasingEnabledByDefault:
+ Result := LCL_CAPABILITY_YES;
+ lcAccessibilitySupport: Result := LCL_CAPABILITY_YES;
+ else
+ Result := inherited;
+ end;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.LCLPlatform
+ Returns: lpCarbon - enum value for Carbon widgetset
+ ------------------------------------------------------------------------------}
+function TCarbonWidgetSet.LCLPlatform: TLCLPlatform;
+begin
+ Result:= lpCarbon;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.DCGetPixel
+ Params: CanvasHandle - Canvas handle to get color from
+ X, Y - Position
+ Returns: Color of the specified pixel on the canvas
+ ------------------------------------------------------------------------------}
+function TCarbonWidgetSet.DCGetPixel(CanvasHandle: HDC; X, Y: integer
+ ): TGraphicsColor;
+begin
+ Result := clNone;
+
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.DCGetPixel DC: ' + DbgS(CanvasHandle) + ' X: ' + DbgS(X) + ' Y: ' + DbgS(Y));
+ {$ENDIF}
+
+ if not CheckDC(CanvasHandle, 'DCGetPixel') then Exit;
+
+ Result := TCarbonDeviceContext(CanvasHandle).GetPixel(X, Y);
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.DCSetPixel
+ Params: CanvasHandle - Canvas handle to get color from
+ X, Y - Position
+ AColor - New color for specified position
+
+ Sets the color of the specified pixel on the canvas
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.DCSetPixel(CanvasHandle: HDC; X, Y: integer;
+ AColor: TGraphicsColor);
+begin
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.DCSetPixel DC: ' + DbgS(CanvasHandle) + ' X: ' + DbgS(X) + ' Y: ' + DbgS(Y) + 'Color: ' + DbgS(AColor));
+ {$ENDIF}
+
+ if not CheckDC(CanvasHandle, 'DCSetPixel') then Exit;
+
+ TCarbonDeviceContext(CanvasHandle).SetPixel(X, Y, AColor);
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.DCReDraw
+ Params: CanvasHandle - Canvas handle to redraw
+
+ Redraws (the window of) a canvas
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.DCRedraw(CanvasHandle: HDC);
+begin
+ {$IFDEF VerboseObject}
+ DebugLn('TCarbonWidgetSet.DCRedraw DC: ' + DbgS(CanvasHandle));
+ {$ENDIF}
+
+ if not CheckDC(CanvasHandle, 'DCRedraw') then Exit;
+
+ CGContextFlush(TCarbonContext(CanvasHandle).CGContext);
+end;
+
+procedure TCarbonWidgetSet.DCSetAntialiasing(CanvasHandle: HDC;
+ AEnabled: Boolean);
+begin
+ if not CheckDC(CanvasHandle, 'DCSetAntialiasing') then Exit;
+
+ TCarbonDeviceContext(CanvasHandle).SetAntialiasing(AEnabled);
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.SetDesigning
+ Params: AComponent - Component to set designing
+
+ Not implemented!
+ ------------------------------------------------------------------------------}
+procedure TCarbonWidgetSet.SetDesigning(AComponent: TComponent);
+begin
+
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.IsHelpKey
+ Params: Key -
+ Shift -
+ Returns: If the specified key is determined to show help in Carbon
+ ------------------------------------------------------------------------------}
+function TCarbonWidgetSet.IsHelpKey(Key: Word; Shift: TShiftState): Boolean;
+begin
+ Result := False; // help key is Cmd + ?, will be called directly on key press
+end;
+
+{------------------------------------------------------------------------------
+ Method: TimerCallback
+ Params: inTimer - Timer reference
+ inUserData - User data passed when installing timer
+
+ Calls the timer function associated with specified timer
+ ------------------------------------------------------------------------------}
+procedure TimerCallback(inTimer: EventLoopTimerRef; {%H-}inUserData: UnivPtr);
+var
+ TimerFunc: TWSTimerProc;
+begin
+ {$IFDEF VerboseTimer}
+ DebugLn('TimerCallback');
+ {$ENDIF}
+
+ if CarbonWidgetSet = nil then Exit;
+ if CarbonWidgetSet.FTimerMap.GetData(inTimer, TimerFunc) then
+ begin
+ {$IFDEF VerboseTimer}
+ DebugLn('TimerCallback Timer instaåled, calling func.');
+ {$ENDIF}
+
+ TimerFunc;
+ end;
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.CreateTimer
+ Params: Interval - New timer interval
+ TimerFunc - New timer callback
+ Returns: A Timer id
+
+ Creates new timer with specified interval and callback function
+ ------------------------------------------------------------------------------}
+function TCarbonWidgetSet.CreateTimer(Interval: integer; TimerFunc: TWSTimerProc): THandle;
+var
+ Timer: EventLoopTimerRef;
+begin
+ {$IFDEF VerboseTimer}
+ DebugLn('TCarbonWidgetSet.CreateTimer Interval: ' + DbgS(Interval));
+ {$ENDIF}
+ Result := 0;
+
+ if (Interval > 0) and (TimerFunc <> nil) then
+ begin
+ if OSError(InstallEventLoopTimer(GetMainEventLoop,
+ Interval / 1000, Interval / 1000, // converts msec -> sec
+ EventLoopTimerUPP(@TimerCallback), nil, Timer{%H-}), Self,
+ 'CreateTimer', 'InstallEventLoopTimer') then Exit;
+
+ FTimerMap.Add(Timer, TimerFunc);
+ Result := {%H-}THandle(Timer)
+ end;
+
+ {$IFDEF VerboseTimer}
+ DebugLn('TCarbonWidgetSet.CreateTimer Result: ' + DbgS(Result));
+ {$ENDIF}
+end;
+
+{------------------------------------------------------------------------------
+ Method: TCarbonWidgetSet.Destroy
+ Params: TimerHandle - Timer id to destroy
+ Returns: If the function succeeds
+
+ Destroys specified timer
+ ------------------------------------------------------------------------------}
+function TCarbonWidgetSet.DestroyTimer(TimerHandle: THandle): boolean;
+begin
+ {$IFDEF VerboseTimer}
+ DebugLn('TCarbonWidgetSet.DestroyTimer Handle: ' + DbgS(TimerHandle));
+ {$ENDIF}
+
+ Result := FTimerMap.Delete(TimerHandle);
+
+ if Result then // valid timer
+ OSError(RemoveEventLoopTimer({%H-}EventLoopTimerRef(TimerHandle)), Self,
+ 'DestroyTimer', 'RemoveEventLoopTimer');
+end;
+
+function TCarbonWidgetSet.PrepareUserEvent(Handle: HWND; Msg: Cardinal;
+ wParam: WParam; lParam: LParam; out Target: EventTargetRef): EventRef;
+var
+ EventSpec: EventTypeSpec;
+ AMessage: TLMessage;
+ Widget: TCarbonWidget;
+begin
+ Result := nil;
+ if FMainEventQueue = nil then Exit;
+
+ Widget := TCarbonWidget(Handle);
+
+ if Widget is TCarbonControl then
+ Target := GetControlEventTarget(Widget.Widget)
+ else
+ if Widget is TCarbonWindow then
+ Target := GetWindowEventTarget(TCarbonWindow(Widget).Window)
+ else
+ Exit;
+
+ EventSpec := MakeEventSpec(LCLCarbonEventClass, LCLCarbonEventKindUser);
+ if CreateEvent(nil, EventSpec.eventClass, EventSpec.eventKind,
+ 0, kEventAttributeUserEvent, Result) <> noErr then
+ Exit;
+
+ AMessage.Msg := Msg;
+ AMessage.LParam := lParam;
+ AMessage.WParam := wParam;
+ AMessage.Result := 0;
+ SetEventParameter(Result, MakeFourCC('wmsg'),
+ MakeFourCC('wmsg'), SizeOf(TLMessage),
+ @AMessage);
+end;
diff --git a/imgutil.pas b/imgutil.pas
index 14e5547..50d2b45 100755
--- a/imgutil.pas
+++ b/imgutil.pas
@@ -8,7 +8,7 @@ procedure BatchChangeInterceptSoVOIEqualsZero;
implementation
-uses text,nifti_hdr,nifti_hdr_view,define_types,nifti_img, nifti_img_view;
+uses text,nifti_hdr,nifti_hdr_view,define_types,nifti_img, nifti_img_view, nifti_types;
function UnscaledMean (lOverlayNum: integer): double;
@@ -82,4 +82,4 @@ begin
end;
-end.
+end.
\ No newline at end of file
diff --git a/mricron.ini b/mricron.ini
index 04413e0..0ad9109 100755
--- a/mricron.ini
+++ b/mricron.ini
@@ -1,10 +1,17 @@
[MRU]
-file1=C:\Users\neuropsych\Desktop\dev\crap.nii
-file0=C:\pas\mricron\templates\ch2bet.nii.gz
-file2=C:\Users\neuropsych\Desktop\cT1.nii.gz
-file3=C:\pas\mricron\templates\ch2bet.nii.gz
-file4=
-file5=
+file1=C:\Users\neuropsych\Desktop\fx\afni\ax.BRIK.gz
+file0=C:\Users\neuropsych\Desktop\fx\afni\ax.HEAD
+file2=C:\mricrogl\templates\jhu189.nii.gz
+file3=C:\Users\neuropsych\Desktop\fx\afni\sag.BRIK
+file4=C:\Users\neuropsych\Desktop\fx\xmha_z\cor.mha
+file5=C:\Users\neuropsych\Desktop\fx\nhdr\sag.raw
+file6=C:\pas\mricron\templates\ch2bet.nii.gz
+file7=
+file8=
+file9=
+file10=
+file11=
+file12=
[STR]
FSLBASE=/usr/local/fsl
diff --git a/mricron.lpi b/mricron.lpi
index 94f2cb2..1c29426 100755
--- a/mricron.lpi
+++ b/mricron.lpi
@@ -36,17 +36,15 @@
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
- <Units Count="139">
+ <Units Count="144">
<Unit0>
<Filename Value="mricron.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="mricron"/>
- <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="16" Y="13"/>
+ <CursorPos X="27" Y="13"/>
<UsageCount Value="200"/>
- <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit0>
<Unit1>
@@ -55,7 +53,7 @@
<UnitName Value="Unit1"/>
<TopLine Value="16"/>
<CursorPos X="7" Y="19"/>
- <UsageCount Value="17"/>
+ <UsageCount Value="16"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
@@ -65,10 +63,10 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="nifti_hdr_view"/>
- <EditorIndex Value="3"/>
+ <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
- <TopLine Value="688"/>
- <CursorPos X="1" Y="702"/>
+ <TopLine Value="677"/>
+ <CursorPos X="13" Y="678"/>
<UsageCount Value="200"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
@@ -79,7 +77,7 @@
<UnitName Value="define_types"/>
<TopLine Value="410"/>
<CursorPos X="23" Y="420"/>
- <UsageCount Value="98"/>
+ <UsageCount Value="97"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit3>
<Unit4>
@@ -87,7 +85,7 @@
<UnitName Value="GraphicsMathLibrary"/>
<TopLine Value="326"/>
<CursorPos X="38" Y="349"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
@@ -109,7 +107,7 @@
<UnitName Value="Unit2"/>
<TopLine Value="105"/>
<CursorPos X="1" Y="116"/>
- <UsageCount Value="4"/>
+ <UsageCount Value="3"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit6>
<Unit7>
@@ -119,20 +117,17 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="text"/>
- <EditorIndex Value="4"/>
<WindowIndex Value="0"/>
- <TopLine Value="38"/>
+ <TopLine Value="36"/>
<CursorPos X="1" Y="61"/>
<UsageCount Value="200"/>
- <Loaded Value="True"/>
- <LoadedDesigner Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit7>
<Unit8>
<Filename Value="..\lcl\include\customform.inc"/>
<TopLine Value="315"/>
<CursorPos X="31" Y="325"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit8>
<Unit9>
@@ -155,8 +150,9 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="ROIfilt"/>
+ <WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="25" Y="5"/>
+ <CursorPos X="58" Y="13"/>
<UsageCount Value="200"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit10>
@@ -167,7 +163,7 @@
<UnitName Value="smoothVOI"/>
<TopLine Value="382"/>
<CursorPos X="31" Y="303"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit11>
<Unit12>
@@ -179,20 +175,19 @@
<UnitName Value="nifti_img_view"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
- <TopLine Value="1372"/>
- <CursorPos X="7" Y="1411"/>
+ <TopLine Value="150"/>
+ <CursorPos X="106" Y="151"/>
<UsageCount Value="200"/>
<Loaded Value="True"/>
- <LoadedDesigner Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit12>
<Unit13>
<Filename Value="nifti_img.pas"/>
<UnitName Value="nifti_img"/>
- <EditorIndex Value="7"/>
+ <EditorIndex Value="3"/>
<WindowIndex Value="0"/>
- <TopLine Value="1011"/>
- <CursorPos X="3" Y="1019"/>
+ <TopLine Value="5458"/>
+ <CursorPos X="54" Y="5472"/>
<UsageCount Value="100"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
@@ -202,7 +197,7 @@
<UnitName Value="Distr"/>
<TopLine Value="137"/>
<CursorPos X="22" Y="150"/>
- <UsageCount Value="2"/>
+ <UsageCount Value="1"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit14>
<Unit15>
@@ -234,7 +229,7 @@
<Filename Value="render.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="175"/>
- <UsageCount Value="4"/>
+ <UsageCount Value="3"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit17>
<Unit18>
@@ -257,7 +252,7 @@
<UnitName Value="spread"/>
<TopLine Value="83"/>
<CursorPos X="47" Y="93"/>
- <UsageCount Value="197"/>
+ <UsageCount Value="196"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit19>
<Unit20>
@@ -267,7 +262,7 @@
<UnitName Value="design"/>
<TopLine Value="1"/>
<CursorPos X="45" Y="167"/>
- <UsageCount Value="197"/>
+ <UsageCount Value="196"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit20>
<Unit21>
@@ -287,7 +282,7 @@
<Filename Value="nifti_img_view.lrs"/>
<TopLine Value="2"/>
<CursorPos X="1" Y="1000"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit22>
<Unit23>
@@ -295,7 +290,7 @@
<UnitName Value="logistic"/>
<TopLine Value="1075"/>
<CursorPos X="1" Y="1100"/>
- <UsageCount Value="27"/>
+ <UsageCount Value="26"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit23>
<Unit24>
@@ -314,7 +309,7 @@
<Filename Value="unit1.lfm"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="4"/>
+ <UsageCount Value="3"/>
<DefaultSyntaxHighlighter Value="LFM"/>
</Unit25>
<Unit26>
@@ -322,14 +317,14 @@
<UnitName Value="Grids"/>
<TopLine Value="5919"/>
<CursorPos X="1" Y="5925"/>
- <UsageCount Value="1"/>
+ <UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit26>
<Unit27>
<Filename Value="..\lcl\include\graphic.inc"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="104"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit27>
<Unit28>
@@ -337,14 +332,14 @@
<UnitName Value="LCLProc"/>
<TopLine Value="731"/>
<CursorPos X="1" Y="741"/>
- <UsageCount Value="4"/>
+ <UsageCount Value="3"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit28>
<Unit29>
<Filename Value="nifti_img_view.lfm"/>
<TopLine Value="499"/>
<CursorPos X="7" Y="513"/>
- <UsageCount Value="5"/>
+ <UsageCount Value="4"/>
<DefaultSyntaxHighlighter Value="LFM"/>
</Unit29>
<Unit30>
@@ -352,7 +347,7 @@
<UnitName Value="nifti_hdr"/>
<TopLine Value="172"/>
<CursorPos X="5" Y="188"/>
- <UsageCount Value="90"/>
+ <UsageCount Value="89"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit30>
<Unit31>
@@ -360,7 +355,7 @@
<UnitName Value="gzio2"/>
<TopLine Value="278"/>
<CursorPos X="11" Y="282"/>
- <UsageCount Value="42"/>
+ <UsageCount Value="41"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit31>
<Unit32>
@@ -368,7 +363,7 @@
<UnitName Value="stat"/>
<TopLine Value="318"/>
<CursorPos X="10" Y="329"/>
- <UsageCount Value="19"/>
+ <UsageCount Value="18"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit32>
<Unit33>
@@ -376,7 +371,7 @@
<UnitName Value="Forms"/>
<TopLine Value="799"/>
<CursorPos X="1" Y="806"/>
- <UsageCount Value="1"/>
+ <UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit33>
<Unit34>
@@ -384,7 +379,7 @@
<UnitName Value="LMessages"/>
<TopLine Value="588"/>
<CursorPos X="1" Y="600"/>
- <UsageCount Value="1"/>
+ <UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit34>
<Unit35>
@@ -430,7 +425,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="20" Y="4"/>
- <UsageCount Value="18"/>
+ <UsageCount Value="17"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit38>
<Unit39>
@@ -438,7 +433,7 @@
<UnitName Value="qgraphics"/>
<TopLine Value="30"/>
<CursorPos X="15" Y="38"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit39>
<Unit40>
@@ -446,7 +441,7 @@
<UnitName Value="wgraphics"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="9"/>
- <UsageCount Value="19"/>
+ <UsageCount Value="18"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit40>
<Unit41>
@@ -454,7 +449,7 @@
<UnitName Value="ugraphics"/>
<TopLine Value="1"/>
<CursorPos X="15" Y="1"/>
- <UsageCount Value="90"/>
+ <UsageCount Value="89"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit41>
<Unit42>
@@ -462,7 +457,7 @@
<UnitName Value="nifti_img"/>
<TopLine Value="70"/>
<CursorPos X="26" Y="82"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit42>
<Unit43>
@@ -470,7 +465,7 @@
<UnitName Value="fx8"/>
<TopLine Value="114"/>
<CursorPos X="68" Y="121"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit43>
<Unit44>
@@ -478,28 +473,28 @@
<UnitName Value="fx8"/>
<TopLine Value="119"/>
<CursorPos X="20" Y="146"/>
- <UsageCount Value="18"/>
+ <UsageCount Value="17"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit44>
<Unit45>
<Filename Value="MultiSlice.lfm"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="LFM"/>
</Unit45>
<Unit46>
<Filename Value="MultiSlice.lrs"/>
<TopLine Value="1"/>
<CursorPos X="17" Y="3"/>
- <UsageCount Value="13"/>
+ <UsageCount Value="12"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit46>
<Unit47>
<Filename Value="smoothVOI.lfm"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="LFM"/>
</Unit47>
<Unit48>
@@ -511,7 +506,7 @@
<WindowIndex Value="0"/>
<TopLine Value="385"/>
<CursorPos X="36" Y="391"/>
- <UsageCount Value="186"/>
+ <UsageCount Value="200"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit48>
<Unit49>
@@ -519,7 +514,7 @@
<UnitName Value="RTTICtrls"/>
<TopLine Value="20"/>
<CursorPos X="56" Y="37"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit49>
<Unit50>
@@ -527,7 +522,7 @@
<UnitName Value="FileUtil"/>
<TopLine Value="105"/>
<CursorPos X="35" Y="124"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit50>
<Unit51>
@@ -538,16 +533,16 @@
<ResourceBaseClass Value="Form"/>
<UnitName Value="prefs"/>
<WindowIndex Value="0"/>
- <TopLine Value="10"/>
- <CursorPos X="8" Y="81"/>
- <UsageCount Value="178"/>
+ <TopLine Value="18"/>
+ <CursorPos X="48" Y="26"/>
+ <UsageCount Value="200"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit51>
<Unit52>
<Filename Value="dcm2nii\dcm2niigui.lrs"/>
<TopLine Value="1"/>
<CursorPos X="23" Y="1"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit52>
<Unit53>
@@ -555,7 +550,7 @@
<UnitName Value="JclSysInfo"/>
<TopLine Value="29"/>
<CursorPos X="36" Y="36"/>
- <UsageCount Value="12"/>
+ <UsageCount Value="11"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit53>
<Unit54>
@@ -563,7 +558,7 @@
<UnitName Value="RGBRoutines"/>
<TopLine Value="49"/>
<CursorPos X="49" Y="4"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit54>
<Unit55>
@@ -571,7 +566,7 @@
<UnitName Value="junk"/>
<TopLine Value="33"/>
<CursorPos X="1" Y="46"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit55>
<Unit56>
@@ -579,7 +574,7 @@
<UnitName Value="RGBTypes"/>
<TopLine Value="1"/>
<CursorPos X="44" Y="5"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit56>
<Unit57>
@@ -587,7 +582,7 @@
<UnitName Value="RunTimeTypeInfoControls"/>
<TopLine Value="1"/>
<CursorPos X="23" Y="4"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit57>
<Unit58>
@@ -595,7 +590,7 @@
<UnitName Value="Svn2RevisionInc"/>
<TopLine Value="34"/>
<CursorPos X="40" Y="49"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit58>
<Unit59>
@@ -603,7 +598,7 @@
<UnitName Value="userdir"/>
<TopLine Value="62"/>
<CursorPos X="10" Y="6"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit59>
<Unit60>
@@ -614,7 +609,7 @@
<UnitName Value="perisettings"/>
<TopLine Value="81"/>
<CursorPos X="38" Y="96"/>
- <UsageCount Value="157"/>
+ <UsageCount Value="191"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit60>
<Unit61>
@@ -625,7 +620,7 @@
<UnitName Value="graphx"/>
<TopLine Value="1043"/>
<CursorPos X="29" Y="1055"/>
- <UsageCount Value="157"/>
+ <UsageCount Value="191"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit61>
<Unit62>
@@ -633,7 +628,7 @@
<UnitName Value="metagraph"/>
<TopLine Value="40"/>
<CursorPos X="19" Y="45"/>
- <UsageCount Value="13"/>
+ <UsageCount Value="12"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit62>
<Unit63>
@@ -641,7 +636,7 @@
<UnitName Value="render"/>
<TopLine Value="1045"/>
<CursorPos X="1" Y="1066"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit63>
<Unit64>
@@ -649,7 +644,7 @@
<UnitName Value="RenderThds2"/>
<TopLine Value="308"/>
<CursorPos X="1" Y="333"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit64>
<Unit65>
@@ -657,7 +652,7 @@
<UnitName Value="RGBGraphics"/>
<TopLine Value="241"/>
<CursorPos X="5" Y="255"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit65>
<Unit66>
@@ -665,7 +660,7 @@
<UnitName Value="RGBGraphics"/>
<TopLine Value="151"/>
<CursorPos X="1" Y="165"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit66>
<Unit67>
@@ -673,7 +668,7 @@
<UnitName Value="RGBTypes"/>
<TopLine Value="1"/>
<CursorPos X="131" Y="4"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit67>
<Unit68>
@@ -681,21 +676,21 @@
<UnitName Value="RGBTypes"/>
<TopLine Value="45"/>
<CursorPos X="5" Y="59"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit68>
<Unit69>
<Filename Value="..\share\mango.txt"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="5"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit69>
<Unit70>
<Filename Value="..\share\tempura.txt"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="3"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit70>
<Unit71>
@@ -703,14 +698,14 @@
<UnitName Value="RGBRoutines"/>
<TopLine Value="26"/>
<CursorPos X="1" Y="46"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit71>
<Unit72>
<Filename Value="..\share\mexico.txt"/>
<TopLine Value="20"/>
<CursorPos X="4" Y="23"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit72>
<Unit73>
@@ -718,7 +713,7 @@
<UnitName Value="RTTICtrls"/>
<TopLine Value="18"/>
<CursorPos X="31" Y="33"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit73>
<Unit74>
@@ -726,7 +721,7 @@
<UnitName Value="FileUtil"/>
<TopLine Value="4"/>
<CursorPos X="43" Y="10"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit74>
<Unit75>
@@ -734,7 +729,7 @@
<UnitName Value="cpucount"/>
<TopLine Value="55"/>
<CursorPos X="24" Y="5"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit75>
<Unit76>
@@ -742,7 +737,7 @@
<UnitName Value="nifti_img_view"/>
<TopLine Value="3594"/>
<CursorPos X="20" Y="3617"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit76>
<Unit77>
@@ -750,7 +745,7 @@
<UnitName Value="nifti_hdr"/>
<TopLine Value="160"/>
<CursorPos X="1" Y="174"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit77>
<Unit78>
@@ -758,7 +753,7 @@
<UnitName Value="RGBCarbonRoutines"/>
<TopLine Value="9"/>
<CursorPos X="36" Y="23"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit78>
<Unit79>
@@ -766,7 +761,7 @@
<UnitName Value="RGBGTKRoutines"/>
<TopLine Value="28"/>
<CursorPos X="4" Y="36"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit79>
<Unit80>
@@ -774,7 +769,7 @@
<UnitName Value="LazRGBGraphics"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit80>
<Unit81>
@@ -782,7 +777,7 @@
<UnitName Value="RGBUtils"/>
<TopLine Value="20"/>
<CursorPos X="66" Y="47"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit81>
<Unit82>
@@ -790,7 +785,7 @@
<UnitName Value="RGBGraphics"/>
<TopLine Value="172"/>
<CursorPos X="29" Y="186"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit82>
<Unit83>
@@ -798,15 +793,16 @@
<UnitName Value="render"/>
<TopLine Value="1310"/>
<CursorPos X="1" Y="1328"/>
- <UsageCount Value="12"/>
+ <UsageCount Value="11"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit83>
<Unit84>
<Filename Value="render_composite.pas"/>
<UnitName Value="render_composite"/>
- <TopLine Value="808"/>
- <CursorPos X="46" Y="821"/>
- <UsageCount Value="13"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="7"/>
+ <CursorPos X="23" Y="21"/>
+ <UsageCount Value="12"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit84>
<Unit85>
@@ -814,7 +810,7 @@
<UnitName Value="periplot"/>
<TopLine Value="532"/>
<CursorPos X="20" Y="544"/>
- <UsageCount Value="14"/>
+ <UsageCount Value="13"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit85>
<Unit86>
@@ -822,7 +818,7 @@
<UnitName Value="periutils"/>
<TopLine Value="159"/>
<CursorPos X="1" Y="183"/>
- <UsageCount Value="16"/>
+ <UsageCount Value="15"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit86>
<Unit87>
@@ -830,7 +826,7 @@
<UnitName Value="reslice"/>
<TopLine Value="202"/>
<CursorPos X="46" Y="211"/>
- <UsageCount Value="12"/>
+ <UsageCount Value="11"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit87>
<Unit88>
@@ -838,7 +834,7 @@
<UnitName Value="fmath"/>
<TopLine Value="761"/>
<CursorPos X="30" Y="852"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit88>
<Unit89>
@@ -846,7 +842,7 @@
<UnitName Value="hrf"/>
<TopLine Value="135"/>
<CursorPos X="29" Y="151"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit89>
<Unit90>
@@ -854,7 +850,7 @@
<UnitName Value="regmult"/>
<TopLine Value="119"/>
<CursorPos X="1" Y="115"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit90>
<Unit91>
@@ -863,7 +859,7 @@
<WindowIndex Value="0"/>
<TopLine Value="161"/>
<CursorPos X="6" Y="183"/>
- <UsageCount Value="16"/>
+ <UsageCount Value="15"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit91>
<Unit92>
@@ -874,7 +870,7 @@
<UnitName Value="ReadFloat"/>
<TopLine Value="38"/>
<CursorPos X="38" Y="53"/>
- <UsageCount Value="118"/>
+ <UsageCount Value="152"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit92>
<Unit93>
@@ -882,29 +878,25 @@
<UnitName Value="gzio2"/>
<TopLine Value="756"/>
<CursorPos X="13" Y="797"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit93>
<Unit94>
<Filename Value="common\nifti_hdr.pas"/>
<UnitName Value="nifti_hdr"/>
- <EditorIndex Value="6"/>
<WindowIndex Value="0"/>
- <TopLine Value="978"/>
- <CursorPos X="53" Y="1001"/>
- <UsageCount Value="18"/>
- <Loaded Value="True"/>
+ <TopLine Value="22"/>
+ <CursorPos X="1" Y="36"/>
+ <UsageCount Value="30"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit94>
<Unit95>
<Filename Value="common\define_types.pas"/>
<UnitName Value="define_types"/>
- <EditorIndex Value="1"/>
<WindowIndex Value="0"/>
- <TopLine Value="10"/>
- <CursorPos X="27" Y="21"/>
- <UsageCount Value="36"/>
- <Loaded Value="True"/>
+ <TopLine Value="1310"/>
+ <CursorPos X="1" Y="1317"/>
+ <UsageCount Value="47"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit95>
<Unit96>
@@ -912,7 +904,7 @@
<UnitName Value="cpucount"/>
<TopLine Value="1"/>
<CursorPos X="46" Y="12"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit96>
<Unit97>
@@ -920,7 +912,7 @@
<UnitName Value="userdir"/>
<TopLine Value="35"/>
<CursorPos X="14" Y="43"/>
- <UsageCount Value="17"/>
+ <UsageCount Value="16"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit97>
<Unit98>
@@ -928,7 +920,7 @@
<UnitName Value="Dialogs"/>
<TopLine Value="466"/>
<CursorPos X="43" Y="481"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit98>
<Unit99>
@@ -936,7 +928,7 @@
<UnitName Value="dicomhdr"/>
<TopLine Value="464"/>
<CursorPos X="50" Y="493"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit99>
<Unit100>
@@ -944,14 +936,14 @@
<UnitName Value="RGBGTKRoutines"/>
<TopLine Value="67"/>
<CursorPos X="1" Y="79"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit100>
<Unit101>
<Filename Value="render.lfm"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
<DefaultSyntaxHighlighter Value="LFM"/>
</Unit101>
<Unit102>
@@ -959,36 +951,37 @@
<UnitName Value="GraphicsMathLibrary"/>
<TopLine Value="45"/>
<CursorPos X="15" Y="60"/>
- <UsageCount Value="14"/>
+ <UsageCount Value="13"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit102>
<Unit103>
<Filename Value="reslice_img.pas"/>
<UnitName Value="reslice_img"/>
<WindowIndex Value="0"/>
- <TopLine Value="450"/>
- <CursorPos X="114" Y="462"/>
- <UsageCount Value="17"/>
+ <TopLine Value="1"/>
+ <CursorPos X="46" Y="6"/>
+ <UsageCount Value="16"/>
<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="253"/>
- <CursorPos X="12" Y="257"/>
- <UsageCount Value="11"/>
- <Loaded Value="True"/>
+ <TopLine Value="1"/>
+ <CursorPos X="81" Y="6"/>
+ <UsageCount Value="16"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit104>
<Unit105>
<Filename Value="common\dicomhdr.pas"/>
<UnitName Value="dicomhdr"/>
- <TopLine Value="77"/>
- <CursorPos X="63" Y="94"/>
- <UsageCount Value="9"/>
+ <IsVisibleTab Value="True"/>
+ <EditorIndex Value="5"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="6"/>
+ <CursorPos X="1" Y="10"/>
+ <UsageCount Value="15"/>
+ <Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit105>
<Unit106>
@@ -996,7 +989,7 @@
<UnitName Value="cgiModules"/>
<TopLine Value="1"/>
<CursorPos X="53" Y="19"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit106>
<Unit107>
@@ -1004,14 +997,14 @@
<UnitName Value="reslice_fsl"/>
<TopLine Value="25"/>
<CursorPos X="27" Y="38"/>
- <UsageCount Value="19"/>
+ <UsageCount Value="18"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit107>
<Unit108>
<Filename Value="..\mricrogl\sourcex\mricrogl.lpr"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit108>
<Unit109>
@@ -1019,16 +1012,16 @@
<UnitName Value="OpenGL1x"/>
<TopLine Value="5131"/>
<CursorPos X="10" Y="5142"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit109>
<Unit110>
<Filename Value="imgutil.pas"/>
<UnitName Value="imgutil"/>
<WindowIndex Value="0"/>
- <TopLine Value="45"/>
- <CursorPos X="29" Y="3"/>
- <UsageCount Value="13"/>
+ <TopLine Value="1"/>
+ <CursorPos X="87" Y="11"/>
+ <UsageCount Value="12"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit110>
<Unit111>
@@ -1037,7 +1030,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="98" Y="2"/>
- <UsageCount Value="18"/>
+ <UsageCount Value="17"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit111>
<Unit112>
@@ -1045,15 +1038,16 @@
<UnitName Value="fdr"/>
<TopLine Value="1"/>
<CursorPos X="51" Y="73"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit112>
<Unit113>
<Filename Value="statclustertable.pas"/>
<UnitName Value="statclustertable"/>
- <TopLine Value="279"/>
- <CursorPos X="19" Y="279"/>
- <UsageCount Value="12"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="103"/>
+ <CursorPos X="83" Y="113"/>
+ <UsageCount Value="15"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit113>
<Unit114>
@@ -1061,14 +1055,14 @@
<UnitName Value="reorient"/>
<TopLine Value="54"/>
<CursorPos X="35" Y="56"/>
- <UsageCount Value="14"/>
+ <UsageCount Value="13"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit114>
<Unit115>
<Filename Value="C:\lazarus\fpc\2.2.2\source\rtl\objpas\sysutils\osutilsh.inc"/>
<TopLine Value="31"/>
<CursorPos X="10" Y="38"/>
- <UsageCount Value="12"/>
+ <UsageCount Value="11"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit115>
<Unit116>
@@ -1076,21 +1070,21 @@
<UnitName Value="part"/>
<TopLine Value="1"/>
<CursorPos X="11" Y="31"/>
- <UsageCount Value="12"/>
+ <UsageCount Value="11"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit116>
<Unit117>
<Filename Value="graphx.lrs"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="153"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit117>
<Unit118>
<Filename Value="landmarks.lfm"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
<DefaultSyntaxHighlighter Value="LFM"/>
</Unit118>
<Unit119>
@@ -1102,14 +1096,14 @@
<UnitName Value="landmarks"/>
<TopLine Value="166"/>
<CursorPos X="50" Y="175"/>
- <UsageCount Value="64"/>
+ <UsageCount Value="98"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit119>
<Unit120>
<Filename Value="prefs.lfm"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="LFM"/>
</Unit120>
<Unit121>
@@ -1117,26 +1111,25 @@
<UnitName Value="BaseUnix"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit121>
<Unit122>
<Filename Value="common\isgui.inc"/>
- <EditorIndex Value="5"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="57" Y="1"/>
- <UsageCount Value="18"/>
- <Loaded Value="True"/>
+ <CursorPos X="10" Y="1"/>
+ <UsageCount Value="22"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit122>
<Unit123>
<Filename Value="batchstatselect.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="batchstatselect"/>
- <TopLine Value="58"/>
- <CursorPos X="64" Y="69"/>
- <UsageCount Value="53"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="43" Y="6"/>
+ <UsageCount Value="87"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit123>
<Unit124>
@@ -1144,7 +1137,7 @@
<UnitName Value="yokeipc"/>
<TopLine Value="3"/>
<CursorPos X="29" Y="105"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit124>
<Unit125>
@@ -1153,7 +1146,7 @@
<WindowIndex Value="0"/>
<TopLine Value="53"/>
<CursorPos X="14" Y="58"/>
- <UsageCount Value="14"/>
+ <UsageCount Value="13"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit125>
<Unit126>
@@ -1161,7 +1154,7 @@
<UnitName Value="winmemmap"/>
<TopLine Value="2"/>
<CursorPos X="56" Y="9"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit126>
<Unit127>
@@ -1169,25 +1162,23 @@
<UnitName Value="Interfaces"/>
<TopLine Value="1"/>
<CursorPos X="17" Y="13"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit127>
<Unit128>
<Filename Value="C:\lazarus\fpc\2.4.1\source\rtl\win\wininc\defines.inc"/>
<TopLine Value="1"/>
<CursorPos X="64" Y="301"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit128>
<Unit129>
<Filename Value="common\dialogsx.pas"/>
<UnitName Value="dialogsx"/>
- <EditorIndex Value="10"/>
<WindowIndex Value="0"/>
<TopLine Value="118"/>
<CursorPos X="38" Y="119"/>
- <UsageCount Value="14"/>
- <Loaded Value="True"/>
+ <UsageCount Value="18"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit129>
<Unit130>
@@ -1195,7 +1186,7 @@
<UnitName Value="nifti_hdr"/>
<TopLine Value="47"/>
<CursorPos X="26" Y="49"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit130>
<Unit131>
@@ -1203,7 +1194,7 @@
<UnitName Value="process"/>
<TopLine Value="25"/>
<CursorPos X="70" Y="25"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit131>
<Unit132>
@@ -1212,7 +1203,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="9" Y="6"/>
- <UsageCount Value="19"/>
+ <UsageCount Value="18"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit132>
<Unit133>
@@ -1220,7 +1211,7 @@
<WindowIndex Value="0"/>
<TopLine Value="206"/>
<CursorPos X="1" Y="228"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit133>
<Unit134>
@@ -1230,16 +1221,16 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="13" Y="98"/>
- <UsageCount Value="30"/>
+ <UsageCount Value="64"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit134>
<Unit135>
<Filename Value="CarbonOpenDoc.pas"/>
<UnitName Value="CarbonOpenDoc"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="39" Y="6"/>
- <UsageCount Value="12"/>
+ <TopLine Value="33"/>
+ <CursorPos X="42" Y="38"/>
+ <UsageCount Value="11"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit135>
<Unit136>
@@ -1249,17 +1240,17 @@
<WindowIndex Value="0"/>
<TopLine Value="16"/>
<CursorPos X="17" Y="28"/>
- <UsageCount Value="30"/>
+ <UsageCount Value="64"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit136>
<Unit137>
<Filename Value="common\gzio2.pas"/>
<UnitName Value="gzio2"/>
- <EditorIndex Value="9"/>
+ <EditorIndex Value="6"/>
<WindowIndex Value="0"/>
- <TopLine Value="75"/>
- <CursorPos X="5" Y="82"/>
- <UsageCount Value="12"/>
+ <TopLine Value="111"/>
+ <CursorPos X="81" Y="119"/>
+ <UsageCount Value="24"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit137>
@@ -1269,131 +1260,177 @@
<WindowIndex Value="0"/>
<TopLine Value="275"/>
<CursorPos X="11" Y="15"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit138>
+ <Unit139>
+ <Filename Value="nii_label.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="nii_label"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="1" Y="34"/>
+ <UsageCount Value="45"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit139>
+ <Unit140>
+ <Filename Value="crop.pas"/>
+ <UnitName Value="crop"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1"/>
+ <CursorPos X="113" Y="9"/>
+ <UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit140>
+ <Unit141>
+ <Filename Value="..\raycast\gzio2.pas"/>
+ <UnitName Value="gzio2"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1175"/>
+ <CursorPos X="1" Y="1180"/>
+ <UsageCount Value="10"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit141>
+ <Unit142>
+ <Filename Value="common\nifti_types.pas"/>
+ <UnitName Value="nifti_types"/>
+ <EditorIndex Value="4"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="109"/>
+ <CursorPos X="3" Y="118"/>
+ <UsageCount Value="18"/>
+ <Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit142>
+ <Unit143>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <UnitName Value="nifti_foreign"/>
+ <EditorIndex Value="1"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="815"/>
+ <CursorPos X="29" Y="826"/>
+ <UsageCount Value="18"/>
+ <Loaded Value="True"/>
+ <DefaultSyntaxHighlighter Value="Delphi"/>
+ </Unit143>
</Units>
- <JumpHistory Count="30" HistoryIndex="29">
+ <JumpHistory Count="29" HistoryIndex="28">
<Position1>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="5290" Column="16" TopLine="5263"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="799" Column="27" TopLine="672"/>
</Position1>
<Position2>
- <Filename Value="common\gzio2.pas"/>
- <Caret Line="34" Column="79" TopLine="13"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="620" Column="63" TopLine="613"/>
</Position2>
<Position3>
- <Filename Value="common\gzio2.pas"/>
- <Caret Line="35" Column="17" TopLine="13"/>
+ <Filename Value="common\nifti_types.pas"/>
+ <Caret Line="5" Column="85" TopLine="1"/>
</Position3>
<Position4>
- <Filename Value="common\gzio2.pas"/>
- <Caret Line="36" Column="17" TopLine="13"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="806" Column="59" TopLine="793"/>
</Position4>
<Position5>
- <Filename Value="common\gzio2.pas"/>
- <Caret Line="125" Column="39" TopLine="119"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="805" Column="32" TopLine="796"/>
</Position5>
<Position6>
- <Filename Value="common\gzio2.pas"/>
- <Caret Line="126" Column="23" TopLine="118"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="805" Column="32" TopLine="796"/>
</Position6>
<Position7>
- <Filename Value="common\gzio2.pas"/>
- <Caret Line="125" Column="10" TopLine="116"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="617" Column="5" TopLine="602"/>
</Position7>
<Position8>
- <Filename Value="common\gzio2.pas"/>
- <Caret Line="97" Column="29" TopLine="95"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="609" Column="3" TopLine="602"/>
</Position8>
<Position9>
- <Filename Value="common\gzio2.pas"/>
- <Caret Line="33" Column="87" TopLine="26"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="4" Column="117" TopLine="1"/>
</Position9>
<Position10>
- <Filename Value="common\gzio2.pas"/>
- <Caret Line="1786" Column="3" TopLine="1779"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="623" Column="95" TopLine="610"/>
</Position10>
<Position11>
- <Filename Value="common\dialogsx.pas"/>
- <Caret Line="15" Column="18" TopLine="6"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="709" Column="32" TopLine="701"/>
</Position11>
<Position12>
- <Filename Value="common\dialogsx.pas"/>
- <Caret Line="6" Column="20" TopLine="1"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="721" Column="18" TopLine="701"/>
</Position12>
<Position13>
- <Filename Value="common\dialogsx.pas"/>
- <Caret Line="18" Column="31" TopLine="11"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="719" Column="76" TopLine="708"/>
</Position13>
<Position14>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="5158" Column="4" TopLine="4881"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="33" Column="126" TopLine="30"/>
</Position14>
<Position15>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="14" Column="18" TopLine="7"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="624" Column="7" TopLine="604"/>
</Position15>
<Position16>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="5158" Column="67" TopLine="5152"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="132" Column="109" TopLine="127"/>
</Position16>
<Position17>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="5456" Column="29" TopLine="5450"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="3" Column="109" TopLine="1"/>
</Position17>
<Position18>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="4261" Column="67" TopLine="4253"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="634" Column="31" TopLine="622"/>
</Position18>
<Position19>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="4259" Column="24" TopLine="4252"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="638" Column="20" TopLine="622"/>
</Position19>
<Position20>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="4258" Column="53" TopLine="4251"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="824" Column="35" TopLine="816"/>
</Position20>
<Position21>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="3877" Column="24" TopLine="3870"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="826" Column="40" TopLine="810"/>
</Position21>
<Position22>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="3876" Column="24" TopLine="3870"/>
+ <Filename Value="common\nifti_foreign.pas"/>
+ <Caret Line="656" Column="10" TopLine="641"/>
</Position22>
<Position23>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="62" Column="73" TopLine="55"/>
+ <Filename Value="nifti_hdr_view.pas"/>
+ <Caret Line="8" Column="87" TopLine="1"/>
</Position23>
<Position24>
<Filename Value="nifti_img.pas"/>
- <Caret Line="2248" Column="3" TopLine="2241"/>
+ <Caret Line="88" Column="118" TopLine="87"/>
</Position24>
<Position25>
<Filename Value="nifti_img.pas"/>
- <Caret Line="2087" Column="28" TopLine="2079"/>
+ <Caret Line="5060" Column="37" TopLine="5043"/>
</Position25>
<Position26>
<Filename Value="nifti_img.pas"/>
- <Caret Line="2000" Column="5" TopLine="2000"/>
+ <Caret Line="5102" Column="18" TopLine="5087"/>
</Position26>
<Position27>
<Filename Value="nifti_img.pas"/>
- <Caret Line="2022" Column="30" TopLine="2017"/>
+ <Caret Line="5472" Column="54" TopLine="5458"/>
</Position27>
<Position28>
- <Filename Value="nifti_img.pas"/>
- <Caret Line="1926" Column="22" TopLine="1919"/>
+ <Filename Value="common\dicomhdr.pas"/>
+ <Caret Line="7" Column="76" TopLine="1"/>
</Position28>
<Position29>
- <Filename Value="ortho_reorient.pas"/>
- <Caret Line="393" Column="24" TopLine="376"/>
+ <Filename Value="common\dicomhdr.pas"/>
+ <Caret Line="36" Column="47" TopLine="26"/>
</Position29>
- <Position30>
- <Filename Value="ortho_reorient.pas"/>
- <Caret Line="256" Column="6" TopLine="247"/>
- </Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
diff --git a/mricron.lpr b/mricron.lpr
index 59963ec..245150d 100755
--- a/mricron.lpr
+++ b/mricron.lpr
@@ -10,7 +10,7 @@ uses
about, Text, ReadInt, histoform, autoroi, ROIfilt, render,
MultiSlice, CropEdges, bet, mni,
voismooth, prefs, perisettings, graphx, cutout, ReadFloat, landmarks,
-batchstatselect;
+batchstatselect, nii_label;
{$IFNDEF UNIX}
{$IFDEF FPC}
{$R manifest.res}
diff --git a/nifti_hdr_view.lfm b/nifti_hdr_view.lfm
index fcd42c7..260589d 100755
--- a/nifti_hdr_view.lfm
+++ b/nifti_hdr_view.lfm
@@ -1,7 +1,7 @@
object HdrForm: THdrForm
- Left = 476
+ Left = 369
Height = 418
- Top = 380
+ Top = 154
Width = 542
ActiveControl = PageControl1
BorderIcons = [biSystemMenu]
@@ -18,7 +18,7 @@ object HdrForm: THdrForm
OnCreate = FormCreate
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '0.9.30.2'
+ LCLVersion = '1.0.12.0'
object PageControl1: TPageControl
Left = 4
Height = 395
@@ -397,11 +397,11 @@ object HdrForm: THdrForm
end
object TabSheet4: TTabSheet
Caption = 'Reorient'
- ClientHeight = 338
- ClientWidth = 526
+ ClientHeight = 356
+ ClientWidth = 528
object Label24: TLabel
Left = 10
- Height = 17
+ Height = 18
Top = 184
Width = 9
Caption = 'X'
@@ -409,57 +409,57 @@ object HdrForm: THdrForm
end
object Label36: TLabel
Left = 10
- Height = 17
+ Height = 18
Top = 218
- Width = 10
+ Width = 9
Caption = 'Y'
ParentColor = False
end
object Label37: TLabel
Left = 10
- Height = 17
+ Height = 18
Top = 251
- Width = 9
+ Width = 8
Caption = 'Z'
ParentColor = False
end
object Label39: TLabel
Left = 10
- Height = 17
+ Height = 18
Top = 123
- Width = 55
+ Width = 61
Caption = 'Q Offsets'
ParentColor = False
end
object Label40: TLabel
Left = 10
- Height = 17
+ Height = 18
Top = 86
- Width = 73
+ Width = 76
Caption = 'Quaternions'
ParentColor = False
end
object Label46: TLabel
Left = 10
- Height = 17
+ Height = 18
Top = 46
- Width = 94
+ Width = 109
Caption = 'qFactor [1 or -1]'
ParentColor = False
end
object Label38: TLabel
Left = 4
- Height = 17
+ Height = 18
Top = 9
- Width = 141
+ Width = 150
Caption = 'Quaternion parameters '
ParentColor = False
end
object Label47: TLabel
Left = 4
- Height = 17
+ Height = 18
Top = 157
- Width = 109
+ Width = 118
Caption = 'Affine parameters '
ParentColor = False
end
@@ -831,37 +831,37 @@ object HdrForm: THdrForm
end
object TabSheet1: TTabSheet
Caption = 'Statistics'
- ClientHeight = 338
- ClientWidth = 526
+ ClientHeight = 356
+ ClientWidth = 528
object Label35: TLabel
Left = 8
- Height = 17
+ Height = 18
Top = 14
- Width = 50
+ Width = 57
Caption = 'Intention'
ParentColor = False
end
object Label25: TLabel
Left = 24
- Height = 17
+ Height = 18
Top = 46
- Width = 74
+ Width = 78
Caption = 'Parameter 1'
ParentColor = False
end
object Label27: TLabel
Left = 24
- Height = 17
+ Height = 18
Top = 83
- Width = 74
+ Width = 78
Caption = 'Parameter 2'
ParentColor = False
end
object Label28: TLabel
Left = 24
- Height = 17
+ Height = 18
Top = 118
- Width = 74
+ Width = 78
Caption = 'Parameter 3'
ParentColor = False
end
@@ -898,7 +898,7 @@ object HdrForm: THdrForm
'ln(p-value)'
'log10(p-val'
'Estimatevalue)'
- 'Labelste'
+ 'Labels'
'NeuroN'
'Generic M'
'Symmetric Matrix'
@@ -950,69 +950,69 @@ object HdrForm: THdrForm
end
object TabSheet2: TTabSheet
Caption = 'fMRI'
- ClientHeight = 333
- ClientWidth = 530
+ ClientHeight = 356
+ ClientWidth = 528
object Label11: TLabel
Left = 12
- Height = 13
+ Height = 18
Top = 145
- Width = 65
+ Width = 69
Caption = 'Slice Order'
ParentColor = False
end
object Label16: TLabel
Left = 12
- Height = 13
+ Height = 18
Top = 8
- Width = 63
+ Width = 75
Caption = 'Time Offset'
ParentColor = False
end
object Label17: TLabel
Left = 14
- Height = 13
+ Height = 18
Top = 39
- Width = 78
+ Width = 86
Caption = 'Slice duration'
ParentColor = False
end
object Label32: TLabel
Left = 12
- Height = 13
+ Height = 18
Top = 74
- Width = 58
+ Width = 66
Caption = 'Slice Start'
ParentColor = False
end
object Label20: TLabel
Left = 12
- Height = 13
+ Height = 18
Top = 105
- Width = 55
+ Width = 57
Caption = 'Slice End'
ParentColor = False
end
object Label31: TLabel
Left = 12
- Height = 13
+ Height = 18
Top = 178
- Width = 124
+ Width = 134
Caption = 'Frequency Dimension'
ParentColor = False
end
object Label43: TLabel
Left = 12
- Height = 13
+ Height = 18
Top = 214
- Width = 98
+ Width = 106
Caption = 'Phase Dimension'
ParentColor = False
end
object Label45: TLabel
Left = 12
- Height = 13
+ Height = 18
Top = 250
- Width = 91
+ Width = 98
Caption = 'Slice Dimension'
ParentColor = False
end
@@ -1020,14 +1020,16 @@ object HdrForm: THdrForm
Left = 87
Height = 20
Top = 137
- Width = 159
+ Width = 274
ItemHeight = 0
Items.Strings = (
'Unknown'
- 'Sequential Increasing'
- 'Sequential Decreasing'
- 'Alternating Increasing'
- 'Alternating Decreasing'
+ 'Sequential Increasing (1 2 3 4)'
+ 'Sequential Decreasing (4 3 2 1)'
+ 'Interleaved Increasing (1 3 2 4)'
+ 'Interleaved Decreasing (4 2 3 1)'
+ 'Interleaved Increasing2 (2 4 1 3)'
+ 'Interleaved Decreasing2 (3 1 4 2)'
)
OnSelect = ImageSzChange
Style = csDropDownList
@@ -1037,7 +1039,7 @@ object HdrForm: THdrForm
Left = 146
Height = 20
Top = 174
- Width = 100
+ Width = 215
ItemHeight = 0
Items.Strings = (
'Unknown'
@@ -1053,7 +1055,7 @@ object HdrForm: THdrForm
Left = 146
Height = 20
Top = 210
- Width = 100
+ Width = 215
ItemHeight = 0
Items.Strings = (
'Unknown'
@@ -1069,7 +1071,7 @@ object HdrForm: THdrForm
Left = 146
Height = 20
Top = 246
- Width = 100
+ Width = 215
ItemHeight = 0
Items.Strings = (
'Unknown'
@@ -1124,51 +1126,51 @@ object HdrForm: THdrForm
end
object TabUnused: TTabSheet
Caption = 'Optional'
- ClientHeight = 333
- ClientWidth = 530
+ ClientHeight = 356
+ ClientWidth = 528
object Label34: TLabel
Left = 3
- Height = 13
+ Height = 18
Top = 43
- Width = 59
+ Width = 66
Caption = 'Data Type'
ParentColor = False
end
object Label5: TLabel
Left = 3
- Height = 13
+ Height = 18
Top = 8
- Width = 48
+ Width = 57
Caption = 'Intention'
ParentColor = False
end
object Label6: TLabel
Left = 268
- Height = 13
+ Height = 18
Top = 116
- Width = 41
+ Width = 49
Caption = 'Extents'
ParentColor = False
end
object Label9: TLabel
Left = 268
- Height = 13
+ Height = 18
Top = 76
- Width = 70
+ Width = 76
Caption = 'Sesion Error'
ParentColor = False
end
object Label10: TLabel
Left = 268
- Height = 13
+ Height = 18
Top = 148
- Width = 75
+ Width = 89
Caption = 'Regular [114]'
ParentColor = False
end
object Label14: TLabel
Left = 268
- Height = 13
+ Height = 18
Top = 8
Width = 35
Caption = 'G Min'
@@ -1176,7 +1178,7 @@ object HdrForm: THdrForm
end
object Label15: TLabel
Left = 268
- Height = 13
+ Height = 18
Top = 43
Width = 38
Caption = 'G Max'
@@ -1184,31 +1186,31 @@ object HdrForm: THdrForm
end
object Label18: TLabel
Left = 3
- Height = 13
+ Height = 18
Top = 148
- Width = 48
+ Width = 50
Caption = 'Aux File'
ParentColor = False
end
object Label19: TLabel
Left = 3
- Height = 13
+ Height = 18
Top = 111
- Width = 54
+ Width = 58
Caption = 'DB Name'
ParentColor = False
end
object Label26: TLabel
Left = 3
- Height = 13
+ Height = 18
Top = 76
- Width = 33
+ Width = 38
Caption = 'Notes'
ParentColor = False
end
object intent_nameEdit: TEdit
Left = 76
- Height = 25
+ Height = 22
Top = 6
Width = 152
MaxLength = 16
@@ -1217,7 +1219,7 @@ object HdrForm: THdrForm
end
object data_typeEdit: TEdit
Left = 76
- Height = 25
+ Height = 22
Top = 41
Width = 152
MaxLength = 10
@@ -1226,7 +1228,7 @@ object HdrForm: THdrForm
end
object CommentEdit: TEdit
Left = 76
- Height = 25
+ Height = 22
Top = 74
Width = 152
MaxLength = 80
@@ -1235,7 +1237,7 @@ object HdrForm: THdrForm
end
object db_: TEdit
Left = 76
- Height = 25
+ Height = 22
Top = 109
Width = 152
MaxLength = 18
@@ -1244,7 +1246,7 @@ object HdrForm: THdrForm
end
object aux: TEdit
Left = 76
- Height = 25
+ Height = 22
Top = 148
Width = 152
MaxLength = 24
@@ -1309,8 +1311,8 @@ object HdrForm: THdrForm
SimplePanel = False
end
object MainMenu1: TMainMenu
- left = 411
- top = 6
+ left = 424
+ top = 72
object File1: TMenuItem
Caption = '&File'
object Open1: TMenuItem
@@ -1345,7 +1347,7 @@ object HdrForm: THdrForm
object ImageIntensity1: TMenuItem
Tag = 2
Caption = 'Image Intensity'
- ShortCut = 16451
+ ShortCut = 16457
OnClick = TabMenuClick
end
object Statistics1: TMenuItem
@@ -1378,15 +1380,15 @@ object HdrForm: THdrForm
object OpenHdrDlg: TOpenDialog
FilterIndex = 0
Options = [ofFileMustExist]
- left = 450
- top = 6
+ left = 456
+ top = 72
end
object SaveHdrDlg: TSaveDialog
OnClose = SaveHdrDlgClose
Width = 52
Filter = 'NIfTI (*.hdr;*.nii)|*.hdr; *.nii|NIfTI separate header (*.hdr)|*.hdr|NIfTI embedded header|*.nii'
FilterIndex = 0
- left = 484
- top = 6
+ left = 496
+ top = 72
end
end
diff --git a/nifti_hdr_view.lrs b/nifti_hdr_view.lrs
index b8d0ae3..b70f9b7 100755
--- a/nifti_hdr_view.lrs
+++ b/nifti_hdr_view.lrs
@@ -1,14 +1,14 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('THdrForm','FORMDATA',[
- 'TPF0'#8'THdrForm'#7'HdrForm'#4'Left'#3#220#1#6'Height'#3#162#1#3'Top'#3'|'#1
+ 'TPF0'#8'THdrForm'#7'HdrForm'#4'Left'#3'q'#1#6'Height'#3#162#1#3'Top'#3#154#0
+#5'Width'#3#30#2#13'ActiveControl'#7#12'PageControl1'#11'BorderIcons'#11#12
+'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#8'0.9.30.2'#0#12'TPageCon'
+ +#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#8'1.0.12.0'#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'
@@ -103,20 +103,20 @@ LazarusResources.Add('THdrForm','FORMDATA',[
+'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
+ +#9'TabSheet4'#7'Caption'#6#8'Reorient'#12'ClientHeight'#3'd'#1#11'ClientWidt'
+ +'h'#3#16#2#0#6'TLabel'#7'Label24'#4'Left'#2#10#6'Height'#2#18#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'
+ +'Left'#2#10#6'Height'#2#18#3'Top'#3#218#0#5'Width'#2#9#7'Caption'#6#1'Y'#11
+ +'ParentColor'#8#0#0#6'TLabel'#7'Label37'#4'Left'#2#10#6'Height'#2#18#3'Top'#3
+ +#251#0#5'Width'#2#8#7'Caption'#6#1'Z'#11'ParentColor'#8#0#0#6'TLabel'#7'Labe'
+ +'l39'#4'Left'#2#10#6'Height'#2#18#3'Top'#2'{'#5'Width'#2'='#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
+ +#2#18#3'Top'#2'V'#5'Width'#2'L'#7'Caption'#6#11'Quaternions'#11'ParentColor'
+ +#8#0#0#6'TLabel'#7'Label46'#4'Left'#2#10#6'Height'#2#18#3'Top'#2'.'#5'Width'
+ +#2'm'#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#18#3'Top'#2#9#5'Width'#3#150#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'
+ +'t'#2#4#6'Height'#2#18#3'Top'#3#157#0#5'Width'#2'v'#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'
@@ -226,13 +226,13 @@ LazarusResources.Add('THdrForm','FORMDATA',[
+'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
+ +'Statistics'#12'ClientHeight'#3'd'#1#11'ClientWidth'#3#16#2#0#6'TLabel'#7'La'
+ +'bel35'#4'Left'#2#8#6'Height'#2#18#3'Top'#2#14#5'Width'#2'9'#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'
+ +#2#18#3'Top'#2'.'#5'Width'#2'N'#7'Caption'#6#11'Parameter 1'#11'ParentColor'
+ +#8#0#0#6'TLabel'#7'Label27'#4'Left'#2#24#6'Height'#2#18#3'Top'#2'S'#5'Width'
+ +#2'N'#7'Caption'#6#11'Parameter 2'#11'ParentColor'#8#0#0#6'TLabel'#7'Label28'
+ +#4'Left'#2#24#6'Height'#2#18#3'Top'#2'v'#5'Width'#2'N'#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'
@@ -243,7 +243,7 @@ LazarusResources.Add('THdrForm','FORMDATA',[
+'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
+ +'log10(p-val'#6#14'Estimatevalue)'#6#6'Labels'#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
@@ -258,103 +258,105 @@ LazarusResources.Add('THdrForm','FORMDATA',[
+#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#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'?'
+ +#0#0#9'TTabSheet'#9'TabSheet2'#7'Caption'#6#4'fMRI'#12'ClientHeight'#3'd'#1
+ +#11'ClientWidth'#3#16#2#0#6'TLabel'#7'Label11'#4'Left'#2#12#6'Height'#2#18#3
+ +'Top'#3#145#0#5'Width'#2'E'#7'Caption'#6#11'Slice Order'#11'ParentColor'#8#0
+ +#0#6'TLabel'#7'Label16'#4'Left'#2#12#6'Height'#2#18#3'Top'#2#8#5'Width'#2'K'
+#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'
+ +'eft'#2#14#6'Height'#2#18#3'Top'#2''''#5'Width'#2'V'#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
+ +#18#3'Top'#2'J'#5'Width'#2'B'#7'Caption'#6#11'Slice Start'#11'ParentColor'#8
+ +#0#0#6'TLabel'#7'Label20'#4'Left'#2#12#6'Height'#2#18#3'Top'#2'i'#5'Width'#2
+ +'9'#7'Caption'#6#9'Slice End'#11'ParentColor'#8#0#0#6'TLabel'#7'Label31'#4'L'
+ +'eft'#2#12#6'Height'#2#18#3'Top'#3#178#0#5'Width'#3#134#0#7'Caption'#6#19'Fr'
+ +'equency Dimension'#11'ParentColor'#8#0#0#6'TLabel'#7'Label43'#4'Left'#2#12#6
+ +'Height'#2#18#3'Top'#3#214#0#5'Width'#2'j'#7'Caption'#6#15'Phase Dimension'
+ +#11'ParentColor'#8#0#0#6'TLabel'#7'Label45'#4'Left'#2#12#6'Height'#2#18#3'To'
+ +'p'#3#250#0#5'Width'#2'b'#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'Width'#3#18#1#10'ItemHeight'#2#0#13'Items.Strings'#1#6#7'Unknown'#6#31
+ +'Sequential Increasing (1 2 3 4)'#6#31'Sequential Decreasing (4 3 2 1)'#6' I'
+ +'nterleaved Increasing (1 3 2 4)'#6' Interleaved Decreasing (4 2 3 1)'#6'!In'
+ +'terleaved Increasing2 (2 4 1 3)'#6'!Interleaved Decreasing2 (3 1 4 2)'#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'#3#215#0#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'csDropDown'
+ +'List'#8'TabOrder'#2#5#0#0#9'TComboBox'#12'PhaseDimDrop'#4'Left'#3#146#0#6'H'
+ +'eight'#2#20#3'Top'#3#210#0#5'Width'#3#215#0#10'ItemHeight'#2#0#13'Items.Str'
+ +'ings'#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'TComboBox'#12'SliceDimD'
+ +'rop'#4'Left'#3#146#0#6'Height'#2#20#3'Top'#3#246#0#5'Width'#3#215#0#10'Item'
+ +'Height'#2#0#13'Items.Strings'#1#6#7'Unknown'#6#1'I'#6#1'J'#6#1'K'#0#8'OnSel'
+ +'ect'#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'Wi'
+ +'dth'#2'p'#8'TabOrder'#2#2#5'Value'#2#1#0#0#14'TFloatSpinEdit'#18'Slice_dura'
+ +'tionEdit'#4'Left'#2'x'#6'Height'#2#16#3'Top'#2'&'#5'Width'#2'p'#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
+ +#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#16#3'Top'#2#7#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#16#3'Top'#2'h'#5'Widt'
+ +'h'#2'p'#8'TabOrder'#2#3#5'Value'#2#1#0#0#0#9'TTabSheet'#9'TabUnused'#7'Capt'
+ +'ion'#6#8'Optional'#12'ClientHeight'#3'd'#1#11'ClientWidth'#3#16#2#0#6'TLabe'
+ +'l'#7'Label34'#4'Left'#2#3#6'Height'#2#18#3'Top'#2'+'#5'Width'#2'B'#7'Captio'
+ +'n'#6#9'Data Type'#11'ParentColor'#8#0#0#6'TLabel'#6'Label5'#4'Left'#2#3#6'H'
+ +'eight'#2#18#3'Top'#2#8#5'Width'#2'9'#7'Caption'#6#9'Intention'#11'ParentCol'
+ +'or'#8#0#0#6'TLabel'#6'Label6'#4'Left'#3#12#1#6'Height'#2#18#3'Top'#2't'#5'W'
+ +'idth'#2'1'#7'Caption'#6#7'Extents'#11'ParentColor'#8#0#0#6'TLabel'#6'Label9'
+ +#4'Left'#3#12#1#6'Height'#2#18#3'Top'#2'L'#5'Width'#2'L'#7'Caption'#6#12'Ses'
+ +'ion Error'#11'ParentColor'#8#0#0#6'TLabel'#7'Label10'#4'Left'#3#12#1#6'Heig'
+ +'ht'#2#18#3'Top'#3#148#0#5'Width'#2'Y'#7'Caption'#6#13'Regular [114]'#11'Par'
+ +'entColor'#8#0#0#6'TLabel'#7'Label14'#4'Left'#3#12#1#6'Height'#2#18#3'Top'#2
+ +#8#5'Width'#2'#'#7'Caption'#6#5'G Min'#11'ParentColor'#8#0#0#6'TLabel'#7'Lab'
+ +'el15'#4'Left'#3#12#1#6'Height'#2#18#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#18
+ +#3'Top'#3#148#0#5'Width'#2'2'#7'Caption'#6#8'Aux File'#11'ParentColor'#8#0#0
+ +#6'TLabel'#7'Label19'#4'Left'#2#3#6'Height'#2#18#3'Top'#2'o'#5'Width'#2':'#7
+ +'Caption'#6#7'DB Name'#11'ParentColor'#8#0#0#6'TLabel'#7'Label26'#4'Left'#2#3
+ +#6'Height'#2#18#3'Top'#2'L'#5'Width'#2'&'#7'Caption'#6#5'Notes'#11'ParentCol'
+ +'or'#8#0#0#5'TEdit'#15'intent_nameEdit'#4'Left'#2'L'#6'Height'#2#22#3'Top'#2
+ +#6#5'Width'#3#152#0#9'MaxLength'#2#16#8'TabOrder'#2#0#4'Text'#6#11'intent_na'
+ +'me'#0#0#5'TEdit'#13'data_typeEdit'#4'Left'#2'L'#6'Height'#2#22#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#22#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'TEd'
+ +'it'#3'db_'#4'Left'#2'L'#6'Height'#2#22#3'Top'#2'm'#5'Width'#3#152#0#9'MaxLe'
+ +'ngth'#2#18#8'TabOrder'#2#3#4'Text'#6#3'db_'#0#0#5'TEdit'#3'aux'#4'Left'#2'L'
+ +#6'Height'#2#22#3'Top'#3#148#0#5'Width'#3#152#0#9'MaxLength'#2#24#8'TabOrder'
+ +#2#4#4'Text'#6#3'aux'#0#0#9'TSpinEdit'#4'gmax'#4'Left'#3'n'#1#6'Height'#2#16
+ +#3'Top'#2','#5'Width'#2'B'#8'TabOrder'#2#6#5'Value'#2#1#0#0#9'TSpinEdit'#4'g'
+ +'min'#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'Lef'
+ +'t'#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'Height'#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'TSt'
+ +'atusBar'#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'Width'#2'2'#0#0#11'SimplePanel'#8
+ +#0#0#9'TMainMenu'#9'MainMenu1'#4'left'#3#168#1#3'top'#2'H'#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'I@'#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#200#1#3'top'#2'H'#0#0#11'TSaveDi'
+ +'alog'#10'SaveHdrDlg'#7'OnClose'#7#15'SaveHdrDlgClose'#5'Width'#2'4'#6'Filte'
+ +'r'#6'`NIfTI (*.hdr;*.nii)|*.hdr; *.nii|NIfTI separate header (*.hdr)|*.hdr|'
+ +'NIfTI embedded header|*.nii'#11'FilterIndex'#2#0#4'left'#3#240#1#3'top'#2'H'
+ +#0#0#0
]);
\ No newline at end of file
diff --git a/nifti_hdr_view.pas b/nifti_hdr_view.pas
index ede1182..c8670bb 100755
--- a/nifti_hdr_view.pas
+++ b/nifti_hdr_view.pas
@@ -10,7 +10,7 @@ LResources, Spin,
{$ENDIF}
{$IFNDEF Unix} ShellAPI, {$ENDIF}
SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, nifti_hdr, Menus, ComCtrls, define_types;
+ StdCtrls, nifti_hdr, Menus, ComCtrls, define_types, nifti_types;
type
{ THdrForm }
@@ -329,16 +329,7 @@ begin
else
Endian.SetItemIndex(1);
//caption := inttohex(Magic);
- if Magic = kNIFTI2_MAGIC_EMBEDDED_HDR then
- HeaderMagicDrop.SetItemIndex(4)
- else if Magic = kNIFTI2_MAGIC_SEPARATE_HDR then
- HeaderMagicDrop.SetItemIndex(3)
- else if Magic = kswapNIFTI2_MAGIC_EMBEDDED_HDR then
- HeaderMagicDrop.SetItemIndex(4)
- else if Magic = kswapNIFTI2_MAGIC_SEPARATE_HDR then
- HeaderMagicDrop.SetItemIndex(3)
- else
- if Magic = kNIFTI_MAGIC_EMBEDDED_HDR then
+ if Magic = kNIFTI_MAGIC_EMBEDDED_HDR then
HeaderMagicDrop.SetItemIndex(2)
else if Magic = kNIFTI_MAGIC_SEPARATE_HDR then
HeaderMagicDrop.SetItemIndex(1)
@@ -356,15 +347,7 @@ begin
Endian.ItemIndex:=(0)
else
Endian.ItemIndex:=(1);
- if Magic = kNIFTI2_MAGIC_EMBEDDED_HDR then
- HeaderMagicDrop.ItemIndex:=(4)
- else if Magic = kNIFTI2_MAGIC_SEPARATE_HDR then
- HeaderMagicDrop.ItemIndex:=(3)
- else if Magic = kswapNIFTI2_MAGIC_EMBEDDED_HDR then
- HeaderMagicDrop.ItemIndex:=(4)
- else if Magic = kswapNIFTI2_MAGIC_SEPARATE_HDR then
- HeaderMagicDrop.ItemIndex:=(3)
- else if Magic = kNIFTI_MAGIC_EMBEDDED_HDR then
+ if Magic = kNIFTI_MAGIC_EMBEDDED_HDR then
HeaderMagicDrop.ItemIndex:=(2)
else if Magic = kNIFTI_MAGIC_SEPARATE_HDR then
HeaderMagicDrop.ItemIndex:=(1)
@@ -706,7 +689,7 @@ begin
Exit1.ShortCut := ShortCut(Word('W'), [ssMeta]);
Dimensions1.ShortCut := ShortCut(Word('A'), [ssMeta]);
Rotations1.ShortCut := ShortCut(Word('B'), [ssMeta]);
- ImageIntensity1.ShortCut := ShortCut(Word('C'), [ssMeta]);
+ ImageIntensity1.ShortCut := ShortCut(Word('I'), [ssMeta]);
Statistics1.ShortCut := ShortCut(Word('D'), [ssMeta]);
FunctionalMRI1.ShortCut := ShortCut(Word('E'), [ssMeta]);
Optional1.ShortCut := ShortCut(Word('F'), [ssMeta]);
diff --git a/nifti_img.pas b/nifti_img.pas
index 03c7efc..b52819b 100755
--- a/nifti_img.pas
+++ b/nifti_img.pas
@@ -9,9 +9,9 @@ RXSpin,capmenu,PNGImage,SSE,ShellAPI,Spin,
{$ELSE}
RGBGraphics,rgbroutines,
{$ENDIF}
-
+nifti_types,
SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- Menus, ExtCtrls, NIFTI_hdr, //StdCtrls, ComCtrls,
+ Menus, ExtCtrls, NIFTI_hdr,nii_label, //StdCtrls, ComCtrls,
Math,
ClipBrd,define_types,
GraphicsMathLibrary,Distr,Stat,ReadInt,gzio2;
@@ -23,6 +23,7 @@ const
kAxViewOnly = -1;
kSagViewOnly = -2;
kCoroViewOnly = -3;
+ kMaxLabel = 255;
Type
TBGImg = record //Next: analyze Format Header structure
@@ -32,7 +33,7 @@ Type
SliceView,SPMDefaultsStatsFmriT,SPMDefaultsStatsFmriT0,
MaxDim,LicenseID,XBarGap,XBarThick,VOIUndoSlice,VOIUndoOrient,VOIUndoVolItems,
RenderDepthBufferItems,VOIInvZoom,ZoomPct,BGTransPct,OverlayTransPct,
- ImageSeparation,RenderDim,SigDig,LesionSmooth,LesionDilate,FontSize: integer;
+ ImageSeparation,RenderDim,SigDig,LesionSmooth,LesionDilate,FontSize, SaveImgFilter, SaveVoiFilter: integer;
//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,
@@ -41,7 +42,8 @@ Type
StretchQuality : TStretchQuality;
VOIClr,XBarClr: TColor;
BackupLUT: TLUT;
- LabelStr20 : Array[0..255] of kstr20;
+ //LabelStr20 : Array[0..kMaxLabel] of kstr50;
+ LabelRA: TStrRA;
{FSLDIR,}FSLBASE,FSLOUTPUTTYPE{,FSLBETEXE}: kStr255;
InvMat: TMatrix;
ReorientHdr: TNIFTIHdr;
@@ -1920,7 +1922,6 @@ var
lUnCompressedFilename,lExt: string;
lImgOffset,lC,lFSize: integer;
lMat: TMatrix;
- lHdr2: TNIfTIHdr2;
begin
lExt := UpCaseExt(lFileName);
move(lNiftiHdr,lHdr,sizeof(lHdr));
@@ -2010,21 +2011,13 @@ begin
Filemode := 2;
exit;
end; //separate header
- if lNII2 then begin
- lHdr.magic := kNIFTI2_MAGIC_EMBEDDED_HDR;
- lImgOffset := kImgOffset2;
- end else begin
+
lHdr.magic := kNIFTI_MAGIC_EMBEDDED_HDR;
lImgOffset := kImgOffset;
- end;
lHdr.vox_offset := lImgOffset;//352 bytes
lFSize := lImgOffset+(lImgBufferItems*lImgBufferBPP);
getmem(lBuff,lFSize);
- if lNII2 then begin
- NII1_2_NII2 ( lHdr, lHdr2);
- move(lHdr2,lBuff^,sizeof(lHdr2));
- end else
move(lHdr,lBuff^,sizeof(lHdr));
//Next: NIfTI 1.1 requires bytes 349..352 set to zero when no XML information
@@ -2243,28 +2236,67 @@ begin
freemem(lBuff);
end;*)
+{$IFDEF FPC}
+// http://bugs.freepascal.org/view.php?id=7797
+function GetExtensionFromFilterAtIndex(Filter: String; Index: Integer): String;
+var
+ p, pipe: Integer;
+begin
+ Result := '';
+ if Index < 1 then Exit;
+ p := 0;
+ pipe := 0;
+ while (p < Length(Filter)) do begin
+ Inc(p);
+ if Filter[p] = '|' then Inc(pipe);
+ if (pipe = 2 * (Index - 1)) then break;
+ end;
+ if (p = length(Filter)) then exit;
+ System.Delete(Filter,1,p);
+ p := Pos('|',Filter);
+ if (p = 0) then exit;
+ System.Delete(Filter,1,p);
+ Filter := Copy(Filter,1,MaxInt);
+ p := Pos(';',Filter);
+ pipe := Pos('|',Filter);
+ if (pipe < p) or (p = 0) then p := pipe;
+ if (p > 0) then System.Delete(Filter,p,Length(Filter) - p +1);
+ Filter := StringReplace(Filter, '*', '',[rfReplaceAll, rfIgnoreCase]);
+ if (Pos('?',Filter) > 0) {or (Pos('*',Filter) > 0)} then exit;
+ Result := Filter;
+end;
+{$ENDIF}
+
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...
var
lFileName,lExt: string;
begin
if DefaultFormatVOI then begin
- ImgForm.SaveDialog1.Filter := 'Volume of Interest(.voi)|*.voi|NIfTI (.nii)|*.nii|NIfTI compressed (.nii.gz)|*.nii.gz|NIfTI (.hdr/.img)|*.hdr|MRIcro (.roi)|*.roi';
- ImgForm.SaveDialog1.Filename := changefileext(ImgForm.SaveDialog1.Filename,'.voi');//10/10/06
- ImgForm.SaveDialog1.DefaultExt := '.voi';
+ ImgForm.SaveDialog1.Filter := 'Volume of Interest(.voi)|*.voi|NIfTI (.nii)|*.nii|NIfTI compressed (.nii.gz)|*.nii.gz|NIfTI (.hdr/.img)|*.hdr|MRIcro (.roi)|*.roi';
+ ImgForm.SaveDialog1.FilterIndex:= gBGImg.SaveVoiFilter; //+1since default added
+ ImgForm.SaveDialog1.Filename := changefileext(ImgForm.SaveDialog1.Filename,'.voi');//10/10/06
+ ImgForm.SaveDialog1.DefaultExt := '.voi';
end else begin
- ImgForm.SaveDialog1.Filter := 'NIfTI compressed (.nii.gz)|*.nii.gz|NIfTI (.nii)|*.nii|NIfTI (.hdr/.img)|*.hdr|Volume of Interest(.voi)|*.voi|MRIcro (.roi)|*.roi';
- ImgForm.SaveDialog1.Filename := changefileext(ImgForm.SaveDialog1.Filename,'.nii.gz');//10/10/06
- ImgForm.SaveDialog1.DefaultExt := '.nii.gz';
+ ImgForm.SaveDialog1.Filter := 'NIfTI compressed (.nii.gz)|*.nii.gz|NIfTI (.nii)|*.nii|NIfTI (.hdr/.img)|*.hdr|Volume of Interest(.voi)|*.voi|MRIcro (.roi)|*.roi';
+ ImgForm.SaveDialog1.Filename := changefileext(ImgForm.SaveDialog1.Filename,'.nii.gz');//10/10/06
+ ImgForm.SaveDialog1.FilterIndex:= gBGImg.SaveImgFilter+1; //+1since default added
+ ImgForm.SaveDialog1.DefaultExt := '.nii.gz';
end;
if lDefFilename <> '' then
ImgForm.SaveDialog1.Filename := ParseFilename(lDefFilename);
if not ImgForm.SaveDialog1.Execute then exit;
+ if DefaultFormatVOI then
+ gBGImg.SaveVoiFilter := ImgForm.SaveDialog1.FilterIndex
+ else
+ gBGImg.SaveImgFilter := ImgForm.SaveDialog1.FilterIndex;
lFileName := ImgForm.SaveDialog1.Filename;
+ {$IFDEF FPC}
+ if ImgForm.SaveDialog1.filterIndex > 0 then begin
+ lExt := GetExtensionFromFilterAtIndex(ImgForm.SaveDialog1.Filter,ImgForm.SaveDialog1.FilterIndex+1);
+ lFilename := ChangeFileExtX(lFilename,lExt);
+ end;
+ {$ENDIF}
lExt := UpCaseExt(lFileName);
-
-
gBGImg.VOIchanged := false;
if (lExt='.ROI') then begin
Showmessage('Note that the MRIcro ROI format does not save image dimensions. You may want to save a copy as VOI format.');
@@ -2303,6 +2335,9 @@ begin
with lBGImg do begin
FlipAx := false;
FlipSag := false;
+ SaveImgFilter := 0;
+ SaveVoiFilter := 0;
+
OverlayTransPct := -1;
FontSize := 12;
BGTransPct := 0;
@@ -2442,24 +2477,24 @@ begin
//z
end;
-procedure LoadLabelLUT(var lBackgroundImg: TBGImg; var lHdr: TMRIcroHdr);
+procedure LoadLabelsOld(var lBackgroundImg: TBGImg; var lHdr: TMRIcroHdr);
var lLUTname: string;
lInc: integer;
lTextFile: TextFile;
lStr1: string;
lCh: char;
begin
- lLUTname := changefileext(lHdr.HdrFileName,'.lut');
- if Fileexists(lLUTname) then begin
- lHdr.UsesCustomPalette := true;
- LoadColorScheme(lLUTname,lHdr);
- end;
- //next load labels
- for lInc := 0 to 255 do //regular
- lBackgroundImg.LabelStr20[lInc] := inttostr(lInc);
- lLUTname := changefileext(lHdr.HdrFileName,'.txt');
- if Fileexists(lLUTname) then begin
- assignfile(lTextFile,lLUTname);
+ SetLength(lBackgroundImg.LabelRA,kMaxLabel+1); //+1 as indexed from 0
+ for lInc := 0 to High(lBackgroundImg.LabelRA) do
+ lBackgroundImg.LabelRA[lInc] := inttostr(lInc);
+ lLUTname := changefileext(lHdr.HdrFileName,'.txt');
+ if not Fileexists(lLUTname) then begin
+ lLUTname := ParseFileName(lHdr.HdrFileName)+'.txt'; //file.nii.gz -> file.txt
+ if not Fileexists(lLUTname) then
+ exit;
+ end;
+ assignfile(lTextFile,lLUTname);
+ lHdr.UsesLabels := true;
Filemode := 0;
reset(lTextFile);
while not EOF(lTextFile) do begin
@@ -2471,22 +2506,41 @@ begin
until (EOF(lTextFile)) or (lCh=kCR) or (lCh=UNIXeoln) or (((lCh=kTab)or (lCh=' ')) and (length(lStr1)>0));
if (length(lStr1) > 0) and (not EOF(lTextFile)) then begin
linc := strtoint(lStr1);
- if (lInc >= 0) and (lInc <= 255) then begin
+ if (lInc >= 0) and (lInc <= kMaxLabel) then begin
lStr1 := '';
repeat
read(lTextFile,lCh);
- if (EOF(lTextFile)) or (lCh=kCR) or (lCh=UNIXeoln) or (lCh=kTab)or (lCh=' ') then
+ if (EOF(lTextFile)) or (lCh=kCR) or (lCh=UNIXeoln) {or (lCh=kTab) or (lCh=' ')} then
else
lStr1 := lStr1 + lCh;
- until (EOF(lTextFile)) or (lCh=kCR) or (lCh=UNIXeoln) or (lCh=kTab)or (lCh=' ');
- lBackgroundImg.LabelStr20[lInc] := lStr1;
+ until (EOF(lTextFile)) or (lCh=kCR) or (lCh=UNIXeoln) {or (lCh=kTab)or (lCh=' ')};
+ //showmessage(inttostr(lInc)+'x'+lStr1);
+ lBackgroundImg.LabelRA[lInc] := lStr1;
end;
end;
end;
- CloseFile(lTextFile);
- Filemode := 2;
+ CloseFile(lTextFile);
+ Filemode := 2;
+end;
+
+procedure LoadLabelLUT(var lBackgroundImg: TBGImg; var lHdr: TMRIcroHdr {; isBackground: boolean});
+var lLUTname: string;
+(* lInc: integer;
+ lTextFile: TextFile;
+ lStr1: string;
+ lCh: char; *)
+begin
+ lLUTname := changefileext(lHdr.HdrFileName,'.lut');
+ if Fileexists(lLUTname) then begin
+ lHdr.UsesCustomPalette := true;
+ LoadColorScheme(lLUTname,lHdr);
+
end;
+ //if isBackground then begin
+ LoadLabelsOld(lBackgroundImg,lHdr);
+ lHdr.UsesLabels := true;
+ //end;
end;
procedure LoadMonochromeLUT (var lLUT: integer; var lBackgroundImg: TBGImg; var lHdr: TMRIcroHdr); //lLUT: 0=gray,1=red,2=green,3=blue
@@ -2691,7 +2745,7 @@ end; //Proc LoadColorScheme
procedure FreeImgMemory(var lHdr: TMRIcroHdr);
begin
with lHdr do begin
- if ScrnBufferItems > 0 then freemem(ScrnBuffer);
+ if ScrnBufferItems > 0 then freemem(ScrnBuffer);
if ImgBufferItems > 0 then freemem(ImgBufferUnaligned);
if RenderBufferItems > 0 then freemem(RenderBuffer);
RenderBufferItems := 0;
@@ -3560,9 +3614,7 @@ if lFiltMax8Bit < 255 then begin
lFiltMin8bit := 255-lFiltMax8bit;
lFiltMax8Bit := 255;
end;
-
lScale := (lFiltMax8bit-lFiltMin8bit)/255;
-
if (lFiltMin8bit > 0) or (lFiltMax8bit < 255) then
for lInc := 1 to lItems do
if lHdr.ScrnBuffer^[lInc] <> 0 then
@@ -3575,10 +3627,22 @@ var lRng: single;
lMax,lMin,lSwap,lMod: single;
lFiltMin8bit,lFiltMax8bit,lInc: integer;
begin
- if (lHdr.ImgBufferBPP <> 1) or (lHdr.ImgBufferItems < 2) then
+ if (lHdr.ImgBufferItems < 2) or (lHdr.ImgBufferBPP <> 1) then
exit;
- ReturnMinMax (lHdr, lMin,lMax,lFiltMin8bit,lFiltMax8bit);
- lRng := (lMax - lMin);
+ if (lHdr.UsesCustomPaletteRandomRainbow) then begin
+ createLutLabel (lHdr.LUT, abs(lHdr.WindowScaledMax-lHdr.WindowScaledMin)/100);
+ for lInc := 1 to lHdr.ScrnBufferItems do
+ lHdr.ScrnBuffer^[lInc] := lHdr.ImgBuffer^[lInc];
+ (* l16Buf := SmallIntP(lHdr.ImgBuffer );
+ for lInc := 1 to lHdr.ScrnBufferItems do
+ lHdr.ScrnBuffer^[lInc] := ((l16Buf^[lInc]-1) mod 100)+1;
+ *)
+ exit;
+ end;
+
+ ReturnMinMax (lHdr, lMin,lMax,lFiltMin8bit,lFiltMax8bit);
+
+ lRng := (lMax - lMin);
if lRng <> 0 then
lMod := abs({trunc}(((254)/lRng)))
else
@@ -3619,7 +3683,14 @@ var lRng: single;
lFiltMin8bit,lFiltMax8bit,lRngi,lMin16Val,lMax,lMin,lSwap,lModShl10,lInc,lInt: integer;
begin
if (lHdr.ImgBufferBPP <> 2) or (lHdr.ImgBufferItems < 2) then exit;
- ReturnMinMaxInt (lHdr, lMin,lMax,lFiltMin8bit,lFiltMax8bit);
+ if (lHdr.UsesCustomPaletteRandomRainbow) then begin
+ createLutLabel (lHdr.LUT, abs(lHdr.WindowScaledMax-lHdr.WindowScaledMin)/100);
+ l16Buf := SmallIntP(lHdr.ImgBuffer );
+ for lInc := 1 to lHdr.ScrnBufferItems do
+ lHdr.ScrnBuffer^[lInc] := ((l16Buf^[lInc]-1) mod 100)+1;
+ exit;
+ end;
+ ReturnMinMaxInt (lHdr, lMin,lMax,lFiltMin8bit,lFiltMax8bit);
lRng := lMax - lMin;
if lRng <> 0 then
lModShl10 := abs( trunc(((254)/lRng)* 1024))
@@ -4654,10 +4725,11 @@ begin
end;
if lHdr.ImgBufferItems = 0 then
exit; //2/2010
- if lHdr.UsesCustomPalette then begin
+ if (lHdr.UsesCustomPalette) and (not lHdr.UsesCustomPaletteRandomRainbow) then begin //2014
lHdr.WindowScaledMin := kMin8bit;
lHdr.WindowScaledMax := 255;
end;
+
if lImgSamples < 1 then
exit;
if (lHdr.ImgBufferBPP = 4) then
@@ -4670,6 +4742,7 @@ begin
showmessage(inttostr(lHdr.ImgBufferItems)+'Unknown Image Buffer Bytes Per Pixel: '+inttostr(lHdr.ImgBufferBPP)+' : '+lHdr.HdrFileName);
exit;
end;
+
//if not lHdr.SameDimsAsBG then OrthogonalResliceScrnImg (lBackgroundImg, lHdr);
//ReturnRawMinMax (lHdr, lMin,lMax,lFiltMin8bit,lFiltMax8bit);
if (lLayer <> kBGOverlayNum) and ((lHdr.WindowScaledMin <= 0) and (lHdr.WindowScaledMax <= 0)) then
@@ -5150,22 +5223,24 @@ function OpenImg(var lBackgroundImg: TBGImg; var lImg2Load: TMRIcroHdr; lLoadBac
label
456;
var
- lReslice,lSwap,lGzipped: boolean;
+ lReslice,lSwap: boolean;
lWordX: word;
lP05,lP01,lFWE05,lFWE01,lFDR05,lFDR01:single;
lMinI,lMaxI,lInc: integer;
lMultiImgSzOff,lMultiImgSz,lOffset,
lVol,lnVol,lFileSz,lDataType,lFSz,lImgSamples: Int64; //,lRow
lP: Bytep;
- lFName,lExt,lParseName: String;
+ lFName,lParseName: String;
F: file;
l16Buf : SmallIntP;
l32Buf,l32TempBuf : SingleP;
l64Buf : DoubleP;
begin
lReslice := lResliceIn;
- if lLoadBackground then
+ if lLoadBackground then begin
+ lBackgroundImg.LabelRA := nil;
ImgForm.CloseImagesClick(nil);
+ end;
result := false;
FreeImgMemory(lImg2Load);
if not lImg2Load.DiskDataNativeEndian then
@@ -5203,7 +5278,6 @@ begin
end; //no reslice...
lDataType := lImg2Load.NIFTIhdr.datatype;
lFName := lImg2Load.ImgFileName;
- lGZipped := false;
lMultiImgSz := ComputeImageDataBytes(lImg2Load);
lOffset := round(lImg2Load.NIFTIhdr.vox_offset);
lMultiImgSzOff := lMultiImgSz + abs(lOffset);
@@ -5216,9 +5290,7 @@ begin
lFSz := FSize(lFName);
if (lFSz = 0) then
Showmessage('Unable to find the image file '+lFName);
- lExt := UpCaseExt(lFName);
- if (lExt = '.GZ') or (lExt = '.VOI') or(lExt = '.NII.GZ') then
- lGzipped := true;
+
lVol := 1;
if lnVol > 1 then begin
if lOffset < 0 then
@@ -5232,7 +5304,7 @@ begin
end;
end else
lFileSz := lMultiImgSzOff;
- if ((lFileSz) > lFSz) and (not lgZipped) then begin
+ if ((lFileSz) > lFSz) and (lImg2Load.gzBytesX = K_gzBytes_headerAndImageUncompressed) then begin
ShowMessage('Error: This image file is smaller than described in header.'+
' Expected: '+inttostr(lFileSz)+' Selected:'+inttostr(lFSz)+ ' '+lFname);
exit;
@@ -5241,11 +5313,14 @@ begin
AssignFile(F, lFName);
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
+ if (lImg2Load.gzBytesX <> K_gzBytes_headerAndImageUncompressed) then begin //deal with compressed data
+ if (lImg2Load.gzBytesX = K_gzBytes_headerAndImageCompressed) then begin
+ if lOffset < 0 then
+ lOffset := abs(lOffset) + (lMultiImgSzOff *(lVol-1))
+ else
lOffset := lOffset + (lMultiImgSz *(lVol-1));
+ end else
+ lOffset := (lMultiImgSz *(lVol-1));//header UNCOMPRESSED!
end else if lOffset < 0 then
Seek (F,abs(lOffset) + (lMultiImgSzOff *(lVol-1)) )
else
@@ -5286,12 +5361,14 @@ begin
end;
lImg2Load.ImgBuffer := align(lImg2Load.ImgBufferUnaligned, 16);
//Next Load Image
- if lGzipped then begin
+ if (lImg2Load.gzBytesX <> K_gzBytes_headerAndImageUncompressed) then begin
lP := ByteP(lImg2Load.ImgBuffer);
- UnGZip(lFName,lP,lOffset,lMultiImgSz);
+ if lImg2Load.gzBytesX = K_gzBytes_headerAndImageCompressed then
+ UnGZip(lFName,lP,lOffset,lMultiImgSz)
+ else
+ UnGZip2 (lFName,lP,lOffset,lMultiImgSz, round(lImg2Load.NIFTIhdr.vox_offset)); //unzip
end else
- BlockRead(F,lImg2Load.ImgBuffer^,lMultiImgSz);
-
+ BlockRead(F,lImg2Load.ImgBuffer^,lMultiImgSz);
if IOResult <> 0 then
ShowMessage('Open image file error: '+inttostr(IOResult));
//Next: prepare image : byte swap, check for special..
@@ -5473,19 +5550,44 @@ begin
lImg2Load.LutFromZero := true;
lImg2Load.AutoBalMinUnscaled := lImg2Load.WindowScaledMin;
lImg2Load.AutoBalMaxUnscaled := lImg2Load.WindowScaledMax;
- end else if (lImg2Load.NIFTIhdr.intent_code = kNIFTI_INTENT_LABEL) and (lImg2Load.ImgBufferBPP = 1) then begin
- //maw
- LoadLabelLUT(lBackgroundImg,lImg2Load);
+ end else if (lImg2Load.NIFTIhdr.intent_code = kNIFTI_INTENT_LABEL) and (lImg2Load.ImgBufferBPP = 1) and (lImg2Load.NIFTIhdr.regular = char(98)) then begin
+ //createLutLabel (lImg2Load, 1.0);
+ LoadLabelLUT(lBackgroundImg,lImg2Load);
+ lImg2Load.NIFTIhdr.scl_slope := 1;
+ lImg2Load.NIFTIhdr.scl_inter := 0;
+ lImg2Load.WindowScaledMin := kMin8bit;
+ lImg2Load.WindowScaledMax := 255;
+ lImg2Load.UsesCustomPalette := true;
+ lImg2Load.AutoBalMinUnscaled := lImg2Load.WindowScaledMin;
+ lImg2Load.AutoBalMaxUnscaled := lImg2Load.WindowScaledMax;
+ end else if (lImg2Load.NIFTIhdr.intent_code = kNIFTI_INTENT_LABEL) and ((lImg2Load.ImgBufferBPP = 1) or (lImg2Load.ImgBufferBPP = 2)) then begin
+
+ createLutLabel (lImg2Load.LUT, 1.0);
lImg2Load.NIFTIhdr.scl_slope := 1;
lImg2Load.NIFTIhdr.scl_inter := 0;
- lImg2Load.WindowScaledMin := kMin8bit;//MAW
- lImg2Load.WindowScaledMax := 255;
+ lImg2Load.WindowScaledMin := 0;//kMin8bit;
+ lImg2Load.WindowScaledMax := 100;//255;
lImg2Load.UsesCustomPalette := true;
+ lImg2Load.UsesCustomPaletteRandomRainbow := true;
lImg2Load.AutoBalMinUnscaled := lImg2Load.WindowScaledMin;
lImg2Load.AutoBalMaxUnscaled := lImg2Load.WindowScaledMax;
+ if {lLoadBackground} true then begin
+ if (( lImg2Load.NIFTIhdr.vox_offset- lImg2Load.NIFTIhdr.HdrSz) > 128) then
+ LoadLabels(lImg2Load.HdrFileName,lBackgroundImg.LabelRA, lImg2Load.NIFTIhdr.HdrSz, round( lImg2Load.NIFTIhdr.vox_offset))
+ else
+ LoadLabelsTxt(lImg2Load.HdrFileName, lBackgroundImg.LabelRA);
+ if (High(lBackgroundImg.LabelRA) < 1) and (lImg2Load.ImgBufferBPP = 1) then
+ LoadLabelsOld(lBackgroundImg,lImg2Load);
+ if High(lBackgroundImg.LabelRA) > 0 then
+ lImg2Load.UsesLabels := true;
+ //showmessage(inttostr(High(lBackgroundImg.LabelRA) )+'xxx');
+ end
//ImgForm.Help1.caption := 'imaw'+realtostr(lImg2Load.WindowScaledMin,4);//maw
end else begin
- lImg2Load.UsesCustomPalette := false;
+ if (lImg2Load.NIFTIhdr.intent_code = kNIFTI_INTENT_LABEL) then begin//>only called when BPP <> 1
+ LoadLabelLUT(lBackgroundImg,lImg2Load);
+ end;
+ lImg2Load.UsesCustomPalette := false;
lImg2Load.WindowScaledMin := raw2ScaledIntensity(lImg2Load,lImg2Load.AutoBalMinUnscaled);
lImg2Load.WindowScaledMax := raw2ScaledIntensity(lImg2Load,lImg2Load.AutoBalMaxUnscaled);
diff --git a/nifti_img_view.lfm b/nifti_img_view.lfm
index 460d63a..bc22885 100755
--- a/nifti_img_view.lfm
+++ b/nifti_img_view.lfm
@@ -1,12 +1,12 @@
object ImgForm: TImgForm
- Left = 867
+ Left = 347
Height = 469
- Top = 208
+ Top = 156
Width = 1025
ActiveControl = ControlPanel
AllowDropFiles = True
Caption = 'MRIcroN'
- ClientHeight = 450
+ ClientHeight = 469
ClientWidth = 1025
DockSite = True
Font.Name = 'MS Sans Serif'
@@ -20,7 +20,7 @@ object ImgForm: TImgForm
OnResize = FormResize
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '1.0.2.0'
+ LCLVersion = '1.0.12.0'
object ControlPanel: TPanel
Left = 0
Height = 40
@@ -37,7 +37,7 @@ object ImgForm: TImgForm
OnDblClick = ControlPanelDblClick
object LabelX: TLabel
Left = 6
- Height = 17
+ Height = 18
Top = 12
Width = 9
Caption = 'X'
@@ -45,17 +45,17 @@ object ImgForm: TImgForm
end
object LabelY: TLabel
Left = 81
- Height = 17
+ Height = 18
Top = 12
- Width = 10
+ Width = 9
Caption = 'Y'
ParentColor = False
end
object LabelZ: TLabel
Left = 153
- Height = 17
+ Height = 18
Top = 12
- Width = 9
+ Width = 8
Caption = 'Z'
ParentColor = False
end
@@ -407,10 +407,10 @@ object ImgForm: TImgForm
end
object LayerDrop: TComboBox
Left = 4
- Height = 24
+ Height = 20
Top = 4
Width = 116
- ItemHeight = 16
+ ItemHeight = 0
ItemIndex = 0
Items.Strings = (
'Background Layer'
@@ -425,7 +425,7 @@ object ImgForm: TImgForm
end
object MinWindowEdit: TFloatSpinEdit
Left = 153
- Height = 24
+ Height = 16
Top = 4
Width = 88
DecimalPlaces = 4
@@ -438,7 +438,7 @@ object ImgForm: TImgForm
end
object MaxWindowEdit: TFloatSpinEdit
Left = 245
- Height = 24
+ Height = 16
Top = 4
Width = 88
DecimalPlaces = 4
@@ -451,11 +451,11 @@ object ImgForm: TImgForm
end
object LUTdrop: TComboBox
Left = 340
- Height = 24
+ Height = 20
Top = 5
Width = 100
DropDownCount = 66
- ItemHeight = 16
+ ItemHeight = 0
OnChange = LUTdropChange
OnSelect = LUTdropSelect
ParentShowHint = False
@@ -466,11 +466,11 @@ object ImgForm: TImgForm
end
object ZoomDrop: TComboBox
Left = 225
- Height = 24
+ Height = 20
Top = 8
Width = 79
DropDownCount = 12
- ItemHeight = 16
+ ItemHeight = 0
Items.Strings = (
'To Fit'
'To Int'
@@ -493,7 +493,7 @@ object ImgForm: TImgForm
end
object XViewEdit: TSpinEdit
Left = 24
- Height = 24
+ Height = 16
Top = 12
Width = 52
MinValue = 1
@@ -503,7 +503,7 @@ object ImgForm: TImgForm
end
object YViewEdit: TSpinEdit
Left = 97
- Height = 24
+ Height = 16
Top = 12
Width = 52
MinValue = 1
@@ -513,7 +513,7 @@ object ImgForm: TImgForm
end
object ZViewEdit: TSpinEdit
Left = 169
- Height = 24
+ Height = 16
Top = 12
Width = 52
MinValue = 1
@@ -923,7 +923,7 @@ object ImgForm: TImgForm
object MagPanel: TPanel
Left = 0
Height = 18
- Top = 432
+ Top = 451
Width = 1025
Align = alBottom
BevelOuter = bvNone
@@ -932,9 +932,9 @@ object ImgForm: TImgForm
TabOrder = 1
object StatusLabel: TLabel
Left = 2
- Height = 17
+ Height = 18
Top = 2
- Width = 129
+ Width = 134
Caption = ' No Images Loaded '
ParentColor = False
end
@@ -951,25 +951,25 @@ object ImgForm: TImgForm
end
object Panel1: TPanel
Left = 0
- Height = 392
+ Height = 411
Top = 40
Width = 1025
Align = alClient
BevelOuter = bvNone
- ClientHeight = 392
+ ClientHeight = 411
ClientWidth = 1025
TabOrder = 2
object TriplePanel: TScrollBox
Tag = 666
Left = 0
- Height = 392
+ Height = 411
Top = 0
Width = 1025
- HorzScrollBar.Page = 1021
- VertScrollBar.Page = 388
+ HorzScrollBar.Page = 1025
+ VertScrollBar.Page = 411
Align = alClient
- ClientHeight = 388
- ClientWidth = 1021
+ ClientHeight = 411
+ ClientWidth = 1025
Constraints.MinWidth = 5
Color = clBlack
ParentColor = False
diff --git a/nifti_img_view.lrs b/nifti_img_view.lrs
index 40ed781..f308432 100755
--- a/nifti_img_view.lrs
+++ b/nifti_img_view.lrs
@@ -1,24 +1,24 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TImgForm','FORMDATA',[
- 'TPF0'#8'TImgForm'#7'ImgForm'#4'Left'#3'c'#3#6'Height'#3#213#1#3'Top'#3#208#0
+ 'TPF0'#8'TImgForm'#7'ImgForm'#4'Left'#3'['#1#6'Height'#3#213#1#3'Top'#3#156#0
+#5'Width'#3#1#4#13'ActiveControl'#7#12'ControlPanel'#14'AllowDropFiles'#9#7
- +'Caption'#6#7'MRIcroN'#12'ClientHeight'#3#194#1#11'ClientWidth'#3#1#4#8'Dock'
+ +'Caption'#6#7'MRIcroN'#12'ClientHeight'#3#213#1#11'ClientWidth'#3#1#4#8'Dock'
+'Site'#9#9'Font.Name'#6#13'MS Sans Serif'#4'Menu'#7#9'MainMenu1'#7'OnClose'#7
+#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#7'1.0.2.0'#0#6'TPanel'#12
+ +#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#8'1.0.12.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
+#10'OnDblClick'#7#20'ControlPanelDblClick'#0#6'TLabel'#6'LabelX'#4'Left'#2#6
- +#6'Height'#2#17#3'Top'#2#12#5'Width'#2#9#7'Caption'#6#1'X'#11'ParentColor'#8
- +#0#0#6'TLabel'#6'LabelY'#4'Left'#2'Q'#6'Height'#2#17#3'Top'#2#12#5'Width'#2
- +#10#7'Caption'#6#1'Y'#11'ParentColor'#8#0#0#6'TLabel'#6'LabelZ'#4'Left'#3#153
- +#0#6'Height'#2#17#3'Top'#2#12#5'Width'#2#9#7'Caption'#6#1'Z'#11'ParentColor'
- +#8#0#0#12'TSpeedButton'#10'HideROIBtn'#4'Left'#3'('#3#6'Height'#2#30#4'Hint'
- +#6#30'Briefly hide VOIs and Overlays'#3'Top'#2#4#5'Width'#2#30#10'Glyph.Data'
+ +#6'Height'#2#18#3'Top'#2#12#5'Width'#2#9#7'Caption'#6#1'X'#11'ParentColor'#8
+ +#0#0#6'TLabel'#6'LabelY'#4'Left'#2'Q'#6'Height'#2#18#3'Top'#2#12#5'Width'#2#9
+ +#7'Caption'#6#1'Y'#11'ParentColor'#8#0#0#6'TLabel'#6'LabelZ'#4'Left'#3#153#0
+ +#6'Height'#2#18#3'Top'#2#12#5'Width'#2#8#7'Caption'#6#1'Z'#11'ParentColor'#8
+ +#0#0#12'TSpeedButton'#10'HideROIBtn'#4'Left'#3'('#3#6'Height'#2#30#4'Hint'#6
+ +#30'Briefly hide VOIs and Overlays'#3'Top'#2#4#5'Width'#2#30#10'Glyph.Data'
+#10':'#6#0#0'6'#6#0#0'BM6'#6#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#16#0#0#0#24#0#0#0
+#1#0' '#0#0#0#0#0#0#6#0#0'd'#0#0#0'd'#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255
+#255#255#0#255#255#255#0#198#28#29'%'#192#0#0#127#140'EE'#188#183#11#11#203
@@ -399,34 +399,34 @@ LazarusResources.Add('TImgForm','FORMDATA',[
+#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128
+#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#128#9'N'
+'umGlyphs'#2#0#11'OnMouseDown'#7#20'ColorBarBtnMouseDown'#0#0#9'TComboBox'#9
- +'LayerDrop'#4'Left'#2#4#6'Height'#2#24#3'Top'#2#4#5'Width'#2't'#10'ItemHeigh'
- +'t'#2#16#9'ItemIndex'#2#0#13'Items.Strings'#1#6#16'Background Layer'#0#8'OnC'
- +'hange'#7#15'LayerDropChange'#8'OnSelect'#7#15'LayerDropSelect'#14'ParentSho'
- +'wHint'#8#8'ShowHint'#9#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#0#4'Text'
+ +'LayerDrop'#4'Left'#2#4#6'Height'#2#20#3'Top'#2#4#5'Width'#2't'#10'ItemHeigh'
+ +'t'#2#0#9'ItemIndex'#2#0#13'Items.Strings'#1#6#16'Background Layer'#0#8'OnCh'
+ +'ange'#7#15'LayerDropChange'#8'OnSelect'#7#15'LayerDropSelect'#14'ParentShow'
+ +'Hint'#8#8'ShowHint'#9#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#0#4'Text'
+#6#16'Background Layer'#0#0#14'TFloatSpinEdit'#13'MinWindowEdit'#4'Left'#3
- +#153#0#6'Height'#2#24#3'Top'#2#4#5'Width'#2'X'#13'DecimalPlaces'#2#4#9'Incre'
+ +#153#0#6'Height'#2#16#3'Top'#2#4#5'Width'#2'X'#13'DecimalPlaces'#2#4#9'Incre'
+'ment'#5#0#0#0#0#0#0#0#128#255'?'#8'MaxValue'#5#0#0#0#0#0#127#150#152#22'@'#8
+'MinValue'#5#0#0#0#0#0#127#150#152#22#192#8'OnChange'#7#27'MinContrastWindow'
+'EditChange'#8'TabOrder'#2#1#5'Value'#5#0#0#0#0#0#0#0#128#255'?'#0#0#14'TFlo'
- +'atSpinEdit'#13'MaxWindowEdit'#4'Left'#3#245#0#6'Height'#2#24#3'Top'#2#4#5'W'
+ +'atSpinEdit'#13'MaxWindowEdit'#4'Left'#3#245#0#6'Height'#2#16#3'Top'#2#4#5'W'
+'idth'#2'X'#13'DecimalPlaces'#2#4#9'Increment'#5#0#0#0#0#0#0#0#128#255'?'#8
+'MaxValue'#5#0#0#0#0#0#127#150#152#22'@'#8'MinValue'#5#0#0#0#0#0#127#150#152
+#22#192#8'OnChange'#7#27'MaxContrastWindowEditChange'#8'TabOrder'#2#2#5'Valu'
+'e'#5#0#0#0#0#0#0#0#128#255'?'#0#0#9'TComboBox'#7'LUTdrop'#4'Left'#3'T'#1#6
- +'Height'#2#24#3'Top'#2#5#5'Width'#2'd'#13'DropDownCount'#2'B'#10'ItemHeight'
- +#2#16#8'OnChange'#7#13'LUTdropChange'#8'OnSelect'#7#13'LUTdropSelect'#14'Par'
- +'entShowHint'#8#8'ShowHint'#9#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#3#0
- +#0#0#9'TComboBox'#8'ZoomDrop'#4'Left'#3#225#0#6'Height'#2#24#3'Top'#2#8#5'Wi'
- +'dth'#2'O'#13'DropDownCount'#2#12#10'ItemHeight'#2#16#13'Items.Strings'#1#6#6
+ +'Height'#2#20#3'Top'#2#5#5'Width'#2'd'#13'DropDownCount'#2'B'#10'ItemHeight'
+ +#2#0#8'OnChange'#7#13'LUTdropChange'#8'OnSelect'#7#13'LUTdropSelect'#14'Pare'
+ +'ntShowHint'#8#8'ShowHint'#9#5'Style'#7#14'csDropDownList'#8'TabOrder'#2#3#0
+ +#0#0#9'TComboBox'#8'ZoomDrop'#4'Left'#3#225#0#6'Height'#2#20#3'Top'#2#8#5'Wi'
+ +'dth'#2'O'#13'DropDownCount'#2#12#10'ItemHeight'#2#0#13'Items.Strings'#1#6#6
+'To Fit'#6#6'To Int'#6#2'x1'#6#2'x2'#6#2'x3'#6#2'x4'#6#2'x5'#6#2'x6'#6#2'x7'
+#6#2'x8'#6#2'x9'#0#8'OnChange'#7#14'ZoomDropChange'#8'OnSelect'#7#14'ZoomDro'
+'pSelect'#14'ParentShowHint'#8#8'ShowHint'#9#5'Style'#7#14'csDropDownList'#8
- +'TabOrder'#2#4#0#0#9'TSpinEdit'#9'XViewEdit'#4'Left'#2#24#6'Height'#2#24#3'T'
+ +'TabOrder'#2#4#0#0#9'TSpinEdit'#9'XViewEdit'#4'Left'#2#24#6'Height'#2#16#3'T'
+'op'#2#12#5'Width'#2'4'#8'MinValue'#2#1#8'OnChange'#7#15'XViewEditChange'#8
+'TabOrder'#2#0#5'Value'#2'd'#0#0#9'TSpinEdit'#9'YViewEdit'#4'Left'#2'a'#6'He'
- +'ight'#2#24#3'Top'#2#12#5'Width'#2'4'#8'MinValue'#2#1#8'OnChange'#7#15'XView'
+ +'ight'#2#16#3'Top'#2#12#5'Width'#2'4'#8'MinValue'#2#1#8'OnChange'#7#15'XView'
+'EditChange'#8'TabOrder'#2#1#5'Value'#2' '#0#0#9'TSpinEdit'#9'ZViewEdit'#4'L'
- +'eft'#3#169#0#6'Height'#2#24#3'Top'#2#12#5'Width'#2'4'#8'MinValue'#2#1#8'OnC'
+ +'eft'#3#169#0#6'Height'#2#16#3'Top'#2#12#5'Width'#2'4'#8'MinValue'#2#1#8'OnC'
+'hange'#7#15'XViewEditChange'#8'TabOrder'#2#2#5'Value'#2#14#0#0#6'TPanel'#9
+'ToolPanel'#4'Left'#3'h'#3#6'Height'#2' '#3'Top'#2#4#5'Width'#3#165#0#10'Bev'
+'elOuter'#7#6'bvNone'#12'ClientHeight'#2' '#11'ClientWidth'#3#165#0#8'TabOrd'
@@ -858,156 +858,156 @@ LazarusResources.Add('TImgForm','FORMDATA',[
+#142#0'Q'#255'Y'#0'E'#255#16#255#255#255#0#255#255#255#0#255#255#255#0#255
+#255#255#0#255#255#255#0#255#255#255#0#255#255#255#0#10'GroupIndex'#2','#9'N'
+'umGlyphs'#2#0#7'OnClick'#7#14'Fill3DBtnClick'#0#0#0#0#6'TPanel'#8'MagPanel'
- +#4'Left'#2#0#6'Height'#2#18#3'Top'#3#176#1#5'Width'#3#1#4#5'Align'#7#8'alBot'
+ +#4'Left'#2#0#6'Height'#2#18#3'Top'#3#195#1#5'Width'#3#1#4#5'Align'#7#8'alBot'
+'tom'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2#18#11'ClientWidth'#3#1#4
- +#8'TabOrder'#2#1#0#6'TLabel'#11'StatusLabel'#4'Left'#2#2#6'Height'#2#17#3'To'
- +'p'#2#2#5'Width'#3#129#0#7'Caption'#6#20' No Images Loaded '#11'ParentColo'
+ +#8'TabOrder'#2#1#0#6'TLabel'#11'StatusLabel'#4'Left'#2#2#6'Height'#2#18#3'To'
+ +'p'#2#2#5'Width'#3#134#0#7'Caption'#6#20' No Images Loaded '#11'ParentColo'
+'r'#8#0#0#12'TProgressBar'#12'ProgressBar1'#4'Left'#3'k'#3#6'Height'#2#18#3
+'Top'#2#0#5'Width'#3#150#0#5'Align'#7#7'alRight'#7'Anchors'#11#7'akRight'#8
+'akBottom'#0#11'BorderWidth'#2#1#8'TabOrder'#2#0#0#0#0#6'TPanel'#6'Panel1'#4
- +'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
+ +'Left'#2#0#6'Height'#3#155#1#3'Top'#2'('#5'Width'#3#1#4#5'Align'#7#8'alClien'
+ +'t'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#3#155#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#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'
+ +#6'Height'#3#155#1#3'Top'#2#0#5'Width'#3#1#4#18'HorzScrollBar.Page'#3#1#4#18
+ +'VertScrollBar.Page'#3#155#1#5'Align'#7#8'alClient'#12'ClientHeight'#3#155#1
+ +#11'ClientWidth'#3#1#4#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'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'
- +'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
+ +'e'#9'OnMouseUp'#7#14'PGImageMouseUp'#7'Stretch'#9#0#0#6'TImage'#10'PGImageS'
+ +'ag'#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'PGImageCorDblClick'#11'O'
+ +'nMouseDown'#7#16'PGImageMouseDown'#11'OnMouseMove'#7#16'PGImageMouseMove'#9
+ +'OnMouseUp'#7#14'PGImageMouseUp'#7'Stretch'#9#0#0#6'TImage'#9'PGImageAx'#3'T'
+ +'ag'#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'OnMo'
+ +'useDown'#7#16'PGImageMouseDown'#11'OnMouseMove'#7#16'PGImageMouseMove'#9'On'
+ +'MouseUp'#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'File1'#7'Caption'#6#5'&File'#0
+ +#9'TMenuItem'#5'Open1'#7'Caption'#6#5'&Open'#8'ShortCut'#3'O@'#7'OnClick'#7
+ +#10'Open1Click'#0#0#9'TMenuItem'#7'Recent1'#7'Caption'#6#12'Open &recent'#0#0
+ +#9'TMenuItem'#10'Templates1'#7'Caption'#6#15'Open &templates'#0#0#9'TMenuIte'
+ +'m'#11'CloseImages'#7'Caption'#6#13'&Close images'#7'OnClick'#7#16'CloseImag'
+ +'esClick'#0#0#9'TMenuItem'#12'SaveasNIfTI1'#7'Caption'#6#16'Save as NIfTI...'
+ +#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'OnC'
+ +'lick'#7#19'Saveaspicture1Click'#0#0#9'TMenuItem'#5'Exit1'#7'Caption'#6#5'E&'
+ +'xit'#7'OnClick'#7#10'Exit1Click'#0#0#0#9'TMenuItem'#5'Edit1'#7'Caption'#6#5
+ +'&Edit'#0#9'TMenuItem'#5'Copy1'#7'Caption'#6#4'Copy'#8'ShortCut'#3'C@'#7'OnC'
+ +'lick'#7#10'Copy1Click'#0#0#9'TMenuItem'#6'Paste1'#7'Caption'#6#5'Paste'#8'S'
+ +'hortCut'#3'V@'#7'OnClick'#7#11'Paste1Click'#0#0#9'TMenuItem'#5'Undo1'#7'Cap'
+ ,'tion'#6#4'Undo'#8'ShortCut'#3'Z@'#7'OnClick'#7#10'Undo1Click'#0#0#0#9'TMenu'
+ +'Item'#11'OverlayMenu'#7'Caption'#6#8'&Overlay'#0#9'TMenuItem'#11'OverlayOpe'
+ +'n'#7'Caption'#6#3'Add'#8'ShortCut'#3'A@'#7'OnClick'#7#16'OverlayOpenClick'#0
+ +#0#9'TMenuItem'#15'CloseOverlayImg'#7'Caption'#6#14'Close overlays'#7'OnClic'
+ +'k'#7#20'CloseOverlayImgClick'#0#0#9'TMenuItem'#14'BGTransPctMenu'#7'Caption'
+ +#6#26'Transparency on background'#0#9'TMenuItem'#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'BGtrans20'#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'BGtrans100Click'#0#0#9'TMenuItem'#9
+ +'BGtrans50'#3'Tag'#2'2'#7'Caption'#6#3'50%'#10'GroupIndex'#3#251#0#9'RadioIt'
+ +'em'#9#7'OnClick'#7#15'BGtrans100Click'#0#0#9'TMenuItem'#9'BGtrans60'#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'BGtrans100Click'
+ +#0#0#9'TMenuItem'#10'BGtrans100'#3'Tag'#2'd'#7'Caption'#6#16'100% transparen'
+ +'t'#10'GroupIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15'BGtrans100Click'#0
+ +#0#9'TMenuItem'#10'BGAdditive'#3'Tag'#2#255#7'Caption'#6#8'Additive'#10'Grou'
+ +'pIndex'#3#251#0#9'RadioItem'#9#7'OnClick'#7#15'BGtrans100Click'#0#0#0#9'TMe'
+ +'nuItem'#19'OverlayTransPctMenu'#7'Caption'#6#30'Transparency on other overl'
+ +'ays'#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'C'
+ +'aption'#6#3'40%'#10'GroupIndex'#3#253#0#9'RadioItem'#9#7'OnClick'#7#17'Over'
+ +'layTransClick'#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'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'#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
+ +'TMenuItem'#4'N601'#3'Tag'#2'<'#7'Caption'#6#3'60%'#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'OnCli'
+ +'ck'#7#17'OverlayTransClick'#0#0#9'TMenuItem'#16'N100transparent1'#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'OverlayAdditive'#3'Tag'
+ +#2#255#7'Caption'#6#8'Additive'#7'Checked'#9#10'GroupIndex'#3#253#0#9'RadioI'
+ +'tem'#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'Noneopen1'#7'Capti'
+ +'on'#6#9'None open'#0#0#0#9'TMenuItem'#11'Layerrange1'#7'Caption'#6#15'Layer'
+ +' intensity'#7'Visible'#8#0#9'TMenuItem'#9'Noneopen2'#7'Caption'#6#9'None op'
+ +'en'#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'OnClick'#7#14'Toggl'
+ +'eDrawMenu'#0#0#9'TMenuItem'#7'OpenVOI'#7'Caption'#6#11'Open VOI...'#7'OnCli'
+ +'ck'#7#12'OpenVOIClick'#0#0#9'TMenuItem'#7'SaveVOI'#7'Caption'#6#11'Save VOI'
+ +'...'#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'VOIColor'
+ +#7'Caption'#6#12'VOI color...'#7'OnClick'#7#13'VOIColorClick'#0#0#9'TMenuIte'
+ +'m'#29'Applyintensityfiltertovolume1'#7'Caption'#6#19'Intensity filter...'#8
+ +'ShortCut'#3'F@'#7'OnClick'#7'"Applyintensityfiltertovolume1Click'#0#0#9'TMe'
+ +'nuItem'#10'SmoothVOI1'#7'Caption'#6#13'Smooth VOI...'#7'OnClick'#7#15'Smoot'
+ +'hVOI1Click'#0#0#9'TMenuItem'#17'MaskimagewithVOI1'#7'Caption'#6#19'Mask ima'
+ +'ge with VOI'#0#9'TMenuItem'#13'VOImaskDelete'#7'Caption'#6#23'Delete region'
+ +'s with VOI'#7'OnClick'#7#12'VOImaskClick'#0#0#9'TMenuItem'#15'VOImaskPreser'
+ +'ve'#3'Tag'#2#1#7'Caption'#6#25'Preserve regions with VOI'#7'OnClick'#7#12'V'
+ +'OImaskClick'#0#0#0#9'TMenuItem'#19'Overlaycomparisons1'#7'Caption'#6#19'Ove'
+ +'rlay comparisons'#0#9'TMenuItem#IntersectionmutualtoVOIandoverlays1'#7'Capt'
+ +'ion'#6#31'Intersection [VOI and overlays]'#7'OnClick'#7#18'ROIcomparisonCli'
+ +'ck'#0#0#9'TMenuItem'#19'UnionVOIoroverlays1'#3'Tag'#2#1#7'Caption'#6#23'Uni'
+ +'on [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'#14'DrawHiddenMenu'#7'Caption'
+ +#6#4'Draw'#7'Visible'#8#0#9'TMenuItem'#9'MenuItem2'#7'Caption'#6#18'Show dra'
+ +'wing tools'#7'OnClick'#7#14'ToggleDrawMenu'#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'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
diff --git a/nifti_img_view.pas b/nifti_img_view.pas
index 93c07dc..7634ab9 100755
--- a/nifti_img_view.pas
+++ b/nifti_img_view.pas
@@ -19,8 +19,8 @@ yokesharemem,
LResources, fx8, cpucount, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ComCtrls, ExtCtrls, StdCtrls, GraphicsMathLibrary, ClipBrd,
define_types, Spin, Buttons, nifti_hdr, nifti_hdr_view, nifti_img, voismooth,
-IniFiles, ReadInt, registry, stat, Distr, bet, mni, prefs, CropEdges,
-userdir, graphx, GraphType, IntfGraphics, landmarks,fastsmooth;
+IniFiles, ReadInt, registry, stat, Distr, bet, mni, prefs, CropEdges,nifti_types,
+userdir, graphx, GraphType, IntfGraphics, landmarks,fastsmooth, nii_label;
type
@@ -191,6 +191,7 @@ MNIMenu: TMenuItem;
procedure ToggleDrawMenu(Sender: TObject);
procedure SaveVOIcore(lPromptFilename: boolean);
procedure FormOpenFileMethod(const FileName : string);
+
procedure Landmarks1Click(Sender: TObject);
procedure SetIniMenus;
procedure Batchclusterprobmaps1Batchclusterprobmaps1ClickClick(Sender: TObject);
@@ -207,6 +208,7 @@ procedure C(Sender: TObject);
procedure CropMenuClick(Sender: TObject);
procedure ExportasRGBAnalyzeimage1Click(Sender: TObject);
procedure FormDropFiles(Sender: TObject; const FileNames: array of String);
+//procedure DropFilesOSX(Sender: TObject; const FileNames: array of String);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormKeyPress(Sender: TObject; var Key: char);
procedure Header1Click(Sender: TObject);
@@ -334,11 +336,15 @@ procedure UpdateColorSchemes;
procedure ControlPanelDblClick(Sender: TObject);
procedure ResizeControlPanel (lRows: integer);
procedure SaveOrCopyImages(lCopy: boolean);
+ function ImgIntensityString(var lHdr: TMRIcroHdr; lVox: integer): string; overload;
+ function ImgIntensityString(var lHdr: TMRIcroHdr; lX,lY,lZ: integer): string; overload;
private
{ Private declarations }
{$IFDEF FPC} function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;MousePos: TPoint): Boolean; override;{$ENDIF}
public
+
+
{ Public declarations }
public
//procedure WMSysCommand (var Msg: TWMSysCommand) ; message WM_SYSCOMMAND;
@@ -348,7 +354,7 @@ public
const
kYokeItems= 12;
- knMRU = 5;//max items in most recently used list
+ knMRU = 12;//max items in most recently used list
knMaxOverlay = 20;
kVOIOverlayNum = knMaxOverlay;
kBGOverlayNum = 0;
@@ -557,11 +563,8 @@ var
lIniFile: TIniFile;
begin
lIni:= IniName;
- // if not (gBGIMg.SaveDefaultIni) then
- // showmessage(lIni+ inttostr(DiskFreeEx(lIni)));
if (DiskFreeEx(lIni) < 1) or (not gBGIMg.SaveDefaultIni) then
exit;
-
//lIniFile := TIniFile.Create(changefileext(paramstr(0),'.ini'));
lIniFile := TIniFile.Create(lIni);//DefaultsDir('')+ParseFileName(extractfilename(paramstr(0)))+'.ini');
//recent files
@@ -590,6 +593,9 @@ begin
//Integers
//lIniFile.WriteString('INT', 'ResizeBeforeRescale',IntToStr(gBGImg.ResizeBeforeRescale));
lIniFile.WriteString('INT', 'FontSize',IntToStr(gBGImg.FontSize));
+ lIniFile.WriteString('INT', 'SaveImgFilter',IntToStr(gBGImg.SaveImgFilter));
+ lIniFile.WriteString('INT', 'SaveVoiFilter',IntToStr(gBGImg.SaveVoiFilter));
+
lIniFile.WriteString('INT', 'MaxDim',IntToStr(gBGImg.MaxDim));
lIniFile.WriteString('INT', 'LicenseID',IntToStr(gBGImg.LicenseID));
lIniFile.WriteString('INT', 'Zoom',IntToStr(ZoomDrop.ItemIndex));
@@ -676,10 +682,10 @@ begin
lFilename := ininame;//DefaultsDir('')+ParseFileName(extractfilename(paramstr(0)))+'.ini';
if not FileexistsEx(lFilename) then begin
- DrawMenu.Visible := ToolPanel.visible;
+ //DrawMenu.Visible := ToolPanel.visible;
+ WriteIni2Form(gBGImg);
exit;
end;
-
lIniFile := TIniFile.Create(lFilename);
gMRUstr[0] := lIniFile.ReadString('MRU', 'file0', '');//file0 - last file viewed
lFileNum := 0;
@@ -734,7 +740,8 @@ begin
gBGImg.SigDig := IniInt(lIniFile,'SigDigits',gBGImg.SigDig);
gBGImg.ImageSeparation := IniInt(lIniFile,'ImageSeparation',gBGImg.ImageSeparation);
gBGImg.FontSize := IniInt(lIniFile,'FontSize',gBGImg.FontSize);
-
+ gBGImg.SaveImgFilter := IniInt(lIniFile,'SaveImgFilter',gBGImg.SaveImgFilter);
+ gBGImg.SaveVoiFilter := IniInt(lIniFile,'SaveVoiFilter',gBGImg.SaveVoiFilter);
gBGImg.SPMDefaultsStatsFmriT := IniInt(lIniFile,'SPMDefaultsStatsFmriT',gBGImg.SPMDefaultsStatsFmriT);
gBGImg.SPMDefaultsStatsFmriT0 := IniInt(lIniFile,'SPMDefaultsStatsFmriT0',gBGImg.SPMDefaultsStatsFmriT0);
gBGImg.LesionSmooth := IniInt(lIniFile,'LesionSmooth',gBGImg.LesionSmooth);
@@ -773,7 +780,6 @@ begin
FindClose(lSearchRec);
lStrings.Sort;
LUTdrop.Items.AddStrings(lStrings);
-
lStrings.Free;
//LUTDrop.DropDownCount := 66;//LUTDrop.Items.Count;
end;//UpdateColorSchemes
@@ -856,11 +862,11 @@ begin
gBGImg.Mirror := lFlip;
end;
-procedure TImgForm.FormDropFiles(Sender: TObject;
- const FileNames: array of String);
+procedure TImgForm.FormDropFiles(Sender: TObject; const FileNames: array of String);
var
lFilename: string;
begin
+
if length(FileNames) < 1 then
exit;
lFilename := Filenames[0];
@@ -1272,8 +1278,9 @@ begin
if FindFirst(gTemplateDir+pathdelim+'*.*', faAnyFile, lSearchRec) = 0 then begin
repeat
lFName := lSearchRec.Name;
+
if IsNIfTIHdrExt (lFName) then begin
- Templates1.Items[lN].Caption :=ExtractFileName(lFName);//(ParseFileName(ExtractFileName(lFName)));
+ Templates1.Items[lN].Caption :=ExtractFileName(lFName);//(ParseFileName(ExtractFileName(lFName)));
Templates1.Items[lN].Tag := 0;
Templates1.Items[lN].visible := true;
Templates1.Items[lN].onclick := OpenTemplateMRU;
@@ -1285,7 +1292,9 @@ begin
inc(lN);
end;
until (FindNext(lSearchRec) <> 0) or (lN >= knMRU);
- end;
+ end;// else
+ ImgForm.Caption :=('Unable to find any files in the folder '+gTemplateDir+pathdelim);
+
while lN < knMRU do begin
Templates1.Items[lN].visible := false;
inc(lN);
@@ -1356,16 +1365,14 @@ var
lFilename: string;
begin
if sender = nil then begin
- //autolaunch with last image, or last template image in list
-
- lFilename := gMRUstr[0];
- if (lFilename = '') or (not FileExistsEX(lFilename)) then begin
- if Templates1.Count > 0 then
- Templates1.Items[Templates1.Count-1].click;
- exit;
- end;
-
- OpenAndDisplayImg(lFilename,true); //open but do not add templates to MRU
+ //autolaunch with last image, or last template image in list
+ lFilename := gMRUstr[0];
+ if (lFilename = '') or (not FileExistsEX(lFilename)) then begin
+ if Templates1.Count > 0 then
+ Templates1.Items[Templates1.Count-1].click;
+ exit;
+ end;
+ OpenAndDisplayImg(lFilename,true); //open but do not add templates to MRU
end else if (Sender as TMenuItem).tag = 0 then begin
lFilename := gTemplateDir+pathdelim+(Sender as TMenuItem).caption ;//+ '.hdr';
OpenAndDisplayImg(lFilename,false); //open but do not add templates to MRU
@@ -1619,6 +1626,8 @@ begin
end;
+
+
procedure TImgForm.FormCreate(Sender: TObject);
var
lInc: longint;
@@ -1626,6 +1635,7 @@ begin
Application.ShowButtonGlyphs := sbgNever;
KeyPreview := true;
+
{$IFDEF Darwin}
InitOpenDocHandler;//allows files to be associated...
{$IFNDEF LCLgtk} //only for Carbon compile
@@ -1643,12 +1653,10 @@ begin
N4DTraces1.ShortCut := ShortCut(Word('D'), [ssMeta]);
Header1.ShortCut := ShortCut(Word('I'), [ssMeta]);
YokeMenu.ShortCut := ShortCut(Word('Y'), [ssMeta]);
+ // OnDropFiles := OnDropFiles;
{$ENDIF}
{$ENDIF}
-
-
-
{$IFDEF Darwin}
{$IFNDEF LCLgtk} //only for Carbon compile
Exit1.visible := false;//with OSX users quit from application menu
@@ -1729,17 +1737,17 @@ begin
ZoomDrop.OnSelect(nil);
CreateShareMem;
if YokeMenu.checked then YokeTimer.enabled := true;
+
//gBGIMg.SaveDefaultIni := true;
end;
-function ImgIntensity(var lHdr: TMRIcroHdr; lX,lY,lZ: integer): single;
+function ImgIntensity(var lHdr: TMRIcroHdr; lPos: integer): single; overload;
var
- lPos: integer;
l16Buf : SmallIntP;
l32Buf : SingleP;
begin
+
result := 0;
- lPos := lX + ((lY-1)*gBGImg.ScrnDim[1])+((lZ-1)*gBGImg.ScrnDim[1]*gBGImg.ScrnDim[2]);
if (lPos > lHdr.ImgBufferItems) or (lPos < 1) then exit;
if (lHdr.ImgBufferBPP = 4) then begin
l32Buf := SingleP(lHdr.ImgBuffer );
@@ -1756,31 +1764,37 @@ begin
result := Raw2ScaledIntensity (lHdr,result);
end;
-function ImgIntensityString(var lHdr: TMRIcroHdr; lX,lY,lZ: integer): string;
+function ImgIntensity(var lHdr: TMRIcroHdr; lX,lY,lZ: integer): single; overload;
var
lPos: integer;
begin
lPos := lX + ((lY-1)*gBGImg.ScrnDim[1])+((lZ-1)*gBGImg.ScrnDim[1]*gBGImg.ScrnDim[2]);
- result := '';
- if lHdr.ImgBufferItems < 1 then exit;
- if not lHdr.UsesCustomPalette then begin
- result := realtostr(ImgIntensity(lHdr,lX,lY,lZ),gBGImg.SigDig);
-(* if lHdr.ScrnBuffer[lPos] = 0 then begin
- if lHdr.Slope8Bit < 0 then
- result := '>'+result
- else
- result := '<'+result
- end else if lHdr.ScrnBuffer[lPos] = 255 then begin
- if lHdr.Slope8Bit < 0 then
- result := '<'+result
- else
- result := '>'+result
- end else
- result := '~'+result;*)
+ ImgIntensity(lHdr,lPos);
+end;
+
+function TImgForm.ImgIntensityString(var lHdr: TMRIcroHdr; lVox: integer): string; overload;
+var
+ lV: integer;
+begin
+ if (lVox > lHdr.ImgBufferItems) or (lVox < 1) then exit;
+ if lHdr.UsesLabels then begin
+ lV := round(ImgIntensity(lHdr,lVox));
+ if lV <= High(gBGImg.LabelRA) then
+ result := gBGImg.LabelRA[lV];
+ exit;
+ end;
+ if (not lHdr.UsesCustomPalette) or (lHdr.NIFTIhdr.datatype = kDT_RGB) then begin
+ result := realtostr(ImgIntensity(lHdr,lVox),gBGImg.SigDig);
exit;
end;
- if (lPos > lHdr.ImgBufferItems) or (lPos < 1) then exit;
- result := gBGImg.LabelStr20[lHdr.ImgBuffer^[lPos]];
+end;
+
+function TImgForm.ImgIntensityString(var lHdr: TMRIcroHdr; lX,lY,lZ: integer): string; overload;
+var
+ lVox: integer;
+begin
+ lVox := lX + ((lY-1)*gBGImg.ScrnDim[1])+((lZ-1)*gBGImg.ScrnDim[1]*gBGImg.ScrnDim[2]);
+ result := ImgIntensityString(lHdr,lVox);
end;
procedure TImgForm.UpdateStatusLabel;
@@ -1809,7 +1823,7 @@ begin
if lLen > 2 then
lIntenStr[lLen-1] := ' ';
//StatusLabel.Caption := realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0)+'= '+lIntenStr;
- Caption := realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0)+'= '+lIntenStr;
+ Caption :=realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0)+'= '+lIntenStr;
SetShareMem (lXmm,lYmm,lZmm);
end;
@@ -1973,11 +1987,11 @@ begin
if lVal > lMaxInten then lMaxInten := lVal;
end; //for PGX each column
end; //for PGY2 - each row
- ImgForm.StatusLabel.caption := 'Intensity range '+(RealToStr(lMinInten,4))+'..'+({x} RealToStr(lMaxInten,4));
+ ImgForm.StatusLabel.caption := 'Intensity range'+(RealToStr(lMinInten,4))+'..'+({x} RealToStr(lMaxInten,4));
if lMinInten = lMaxInten then exit; //no range
ImgForm.MinWindowEdit.value := lMinInten;
ImgForm.MaxWindowEdit.value := lMaxInten;
- {$IFDEF FPC} ImgForm.MinContrastWindowEditChange(nil) {$ENDIF}
+ {$IFDEF FPC} ImgForm.MinContrastWindowEditChange(nil); {$ENDIF}
end;
procedure sortLTRB(var lXoutLow,lYOutLow,lXoutHi,lYOutHi: integer); //left<right, top<bottom
@@ -2036,7 +2050,6 @@ begin
// lImage.Canvas.Pen.Color :=gBGImg.VOIClr;
SelectPanel(lPanel);
gBGImg.VOIInvZoom := ComputeInvZoomShl10(lPanel,lImage);
-
if DrawToolSelected then begin //paint tool
WriteUndoVOI(lPanel,false);
if (ssShift in Shift) then begin //erase
@@ -2642,98 +2655,133 @@ begin
end; //for each row
end; *)
procedure DescribeVOIonLabels (lOverlayNum: integer; lShowFilename: boolean);
+const
+ kT = kTextSep;
+ PositiveInfinityBits : Int64 = $7FF0000000000000;
+ NegativeInfinityBits : Int64 = $FFF0000000000000;
+VAR
+ dPositiveInfinity : DOUBLE ABSOLUTE PositiveInfinityBits;
+ dNegativeInfinity : DOUBLE ABSOLUTE NegativeInfinityBits;
var
- lLocalMax,lLocalSum : HistoDoubleRA;
- l16Buf : SmallIntP;
- l32Buf : SingleP;
- l8Buf: byteP;
- lInten: double;
- lXmm,lYmm,lZmm: single;
- lHisto,lRegionVol,lLocalMaxPos: HistoRA;
- lInc,lRegion: Integer;
- lLabelStr: string;
- lVOI: boolean;
- lLabelStr50 : Array[0..kHistoBins] of kstr50;
+ l16Buf : SmallIntP;
+ l32Buf : SingleP;
+ l8Buf: byteP;
+ type
+ TVxStat = RECORD //peristimulus plot
+ n, nNot0, minPos,maxPos: integer;
+ sum,sumNot0,min,max: double;
+ end;
+function clearVxStat: TVxStat;
+begin
+ result.sum:=0;
+ result.sumNot0:= 0;
+ result.n:=0;
+ result.nNot0 := 0;
+ result.minPos:= 0;
+ result.maxPos:=0;
+ result.min := dPositiveInfinity;
+ result.max := dNegativeInfinity;
+end;
+function roiIntensity(var lHdr: TMRIcroHdr; lPos: integer): integer;
+var
+ l16Buf : SmallIntP;
begin
- lInten := 0;//just to hide compiler hint...
- (*if (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP = 2) and ('ratlas.nii.gz' = (extractfilename( gMRIcroOverlay[kBGOverlayNum].HdrFileName))) then begin
- DescribeVOIonLabelsRAT(lOverlayNum,lShowFilename);
- exit;
- end; *)
- if (gMRIcroOverlay[lOverlayNum].ScrnBufferItems <> gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems) or (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP <> 1) or (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 2) then
- exit;
- TextForm.MemoT.Lines.add(' Custom Region Analysis');
- TextForm.MemoT.Lines.add(' For Speculative Brodmann Map: 0=not cortical and 48=no Brodmann label');
- lVOI := IsVOIROIExt(gMRIcroOverlay[lOverlayNum].HdrFileName);
- if (not lVOI) and (lOverlayNum = kVOIOverlayNum) then
- lVOI := true;
- //next describe format
- if lShowfilename then
- lLabelStr := kTextSep+'Filename'+kTextSep
- else
- lLabelStr := kTextSep;
- if lVOI then //intensity min/max position are not important
- TextForm.MemoT.Lines.add(lLabelStr+'Index'+kTextSep+'Area'+kTextSep+'N>0'+kTextSep+'%N>0')
- else
- TextForm.MemoT.Lines.add(lLabelStr+'Index'+kTextSep+'Area'+kTextSep+'N>0'+kTextSep+'%N>0'+kTextSep+'Sum>0'+kTextSep+'Mean>0'+kTextSep+'Max'+kTextSep+'MaxX'+kTextSep+'MaxY'+kTextSep+'MaxZ');
- //next initialize
+ if (lHdr.ImgBufferBPP = 2) then begin
+ l16Buf := SmallIntP(lHdr.ImgBuffer );
+ result := l16Buf^[lPos];
+ end else
+ result := lHdr.ImgBuffer^[lPos];
+end;
+function overlayIntensity(var lHdr: TMRIcroHdr; lPos: integer): single;
+
+begin
+ if (lHdr.ImgBufferBPP = 4) then begin
+ result := l32Buf^[lPos];
+ end else if (lHdr.ImgBufferBPP = 2) then begin
+ result := l16Buf^[lPos];
+ end else
+ result := l8Buf^[lPos];
+end;
+procedure scaleIntensity(var valn: double);
+begin
+ valn := (valn * gMRIcroOverlay[lOverlayNum].NIFTIhdr.scl_slope)+gMRIcroOverlay[lOverlayNum].NIFTIhdr.scl_inter
+end;
+var
+ lROI,lVx: integer;
+ lStat: array of TVxStat;
+ lVal,loMax,hiMax: double;
+ lStartTime: DWord;
+ lBinaryOverlay: boolean;
+ lLabelStr,lStr: string;
+begin
+ if (not gMRIcroOverlay[kBGOverlayNum].UsesLabels) or (High(gBGImg.LabelRA) < 1) then exit;
+ if (gMRIcroOverlay[lOverlayNum].ScrnBufferItems <> gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems) then exit;
+ if (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP > 2) or (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 2) then exit;
+ //pointers to image data
+ l32Buf := SingleP(gMRIcroOverlay[lOverlayNum].ImgBuffer );
+ l16Buf := SmallIntP(gMRIcroOverlay[lOverlayNum].ImgBuffer );
+ if gMRIcroOverlay[lOverlayNum].ScrnBufferItems = gMRIcroOverlay[lOverlayNum].ImgBufferItems then
+ l8Buf := gMRIcroOverlay[lOverlayNum].ImgBuffer
+ else
+ l8Buf := gMRIcroOverlay[lOverlayNum].ScrnBuffer;
+
+ lStartTime := GetTickCount;
+ setlength(lStat, High(gBGImg.LabelRA)+1);
+ for lROI := 0 to High(gBGImg.LabelRA) do
+ lStat[lROI] := clearVxStat;
+ for lVx := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do begin
+ lROI :=roiIntensity(gMRIcroOverlay[kBGOverlayNum], lVx);
+ inc(lStat[lROI].n);
+ lVal := overlayIntensity(gMRIcroOverlay[lOverlayNum],lVx);
+ lStat[lROI].sum := lStat[lROI].sum+ lVal;
+ if lVal <> 0 then begin
+ lStat[lROI].sumNot0 := lStat[lROI].sumNot0+ lVal;
+ inc(lStat[lROI].nNot0);
+ end;
+ if lVal > lStat[lROI].max then
+ lStat[lROI].max := lVal;
+ if lVal < lStat[lROI].min then
+ lStat[lROI].min := lVal;
+ end; //for each voxel
+ //calibrate values with rescale slope/intercept, see if overlay has variablility
+ loMax := dPositiveInfinity;
+ hiMax := dNegativeInfinity;
+ if gMRIcroOverlay[lOverlayNum].NIFTIhdr.scl_slope = 0 then gMRIcroOverlay[lOverlayNum].NIFTIhdr.scl_slope := 1;
+ for lROI := 0 to High(gBGImg.LabelRA) do begin
+ if (lStat[lROI].nNot0 > 0) and (lStat[lROI].max > hiMax) then hiMax := lStat[lROI].max;
+ if (lStat[lROI].nNot0 > 0) and (lStat[lROI].min < loMax) then loMax := lStat[lROI].max;
+ scaleIntensity (lStat[lROI].max);
+ scaleIntensity (lStat[lROI].min);
+ scaleIntensity (lStat[lROI].sum);
+ scaleIntensity (lStat[lROI].sumNot0);
+ end;
+ lBinaryOverlay := (hiMax <= loMax);
if lShowFilename then begin
if gMRIcroOverlay[lOverlayNum].HdrFileName = '' then
- lLabelStr := 'VOI'+kTextSep
+ lLabelStr := 'VOI'+kT
else
- lLabelStr := gMRIcroOverlay[lOverlayNum].HdrFileName+kTextSep;
+ lLabelStr := gMRIcroOverlay[lOverlayNum].HdrFileName+kT;
end else
lLabelStr := '';
- for lInc := 0 to kHistoBins do begin
- lHisto[lInc] := 0;
- lLocalMax[lInc] := 0;
- lLocalSum[lInc] := 0;
- lRegionVol[lInc] := 0;
- if (gMRIcroOverlay[kBGOverlayNum].UsesCustomPalette) then
- lLabelStr50[lInc] := inttostr(lInc)+kTextSep+gBGImg.LabelStr20[lInc]
- else
- lLabelStr50[lInc] := inttostr(lInc)+kTextSep+realtostr(Scrn2ScaledIntensity (gMRIcroOverlay[kBGOverlayNum],lInc),2);
- end;
- for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do
- if gMRIcroOverlay[lOverlayNum].ScrnBuffer^[lInc] > 0 then
- inc(lHisto[gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc]]);
- //local max start
- l32Buf := SingleP(gMRIcroOverlay[lOverlayNum].ImgBuffer );
- l16Buf := SmallIntP(gMRIcroOverlay[lOverlayNum].ImgBuffer );
- //NEXT if..else July07 - ROIs only use screen buffer, not imgbuffer...
- if gMRIcroOverlay[lOverlayNum].ScrnBufferItems = gMRIcroOverlay[lOverlayNum].ImgBufferItems then
- l8Buf := gMRIcroOverlay[lOverlayNum].ImgBuffer
- else
- l8Buf := gMRIcroOverlay[lOverlayNum].ScrnBuffer;
- for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do begin
- if (gMRIcroOverlay[lOverlayNum].ImgBufferBPP = 4) then
- lInten := l32Buf^[lInc]
- else if (gMRIcroOverlay[lOverlayNum].ImgBufferBPP = 2) then
- lInten := l16Buf^[lInc]
- else if gMRIcroOverlay[lOverlayNum].ImgBufferBPP = 1 then
- lInten := l8Buf^[lInc];//July07
- lRegion := gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc];
- if lInten > 0 then
- lLocalSum[lRegion] := lLocalSum[lRegion]+lInten;
- if lInten > lLocalMax[lRegion] then begin
- lLocalMax[lRegion] := lInten;//intensity
- lLocalMaxPos[lRegion] := lInc;//location
- end;
- inc(lRegionVol[lRegion]);
- end;
- for lInc := 0 to kHistoBins do begin
- if (not lVOI) and (lLocalMax[lInc] > 0) then begin
- lLocalMax[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalMax[lInc]);
- lLocalSum[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalSum[lInc]);
- ImgPosToMM(lLocalMaxPos[lInc], lXmm,lYmm,lZmm);
- TextForm.MemoT.Lines.Add(lLabelStr+ lLabelStr50[lInc] +kTextSep + inttostr(lHisto[lInc])+kTextSep+floattostr( lHisto[lInc]/lRegionVol[lInc])
- +kTextSep+floattostr( lLocalSum[lInc])+kTextSep+floattostr( lLocalSum[lInc]/lRegionVol[lInc]) //Sum>0, mean>0
- +kTextSep + floattostr(lLocalMax[lInc])+kTextSep+floattostr(lXmm)+kTextSep+floattostr(lYmm)+kTextSep+floattostr(lZmm) );
- end else if (lHisto[lInc] > 0) {necessarily also and (lRegionVol[lInc] > 0)} then
- TextForm.MemoT.Lines.Add(lLabelStr+ lLabelStr50[lInc] +kTextSep+ inttostr(lHisto[lInc])+kTextSep+floattostr( lHisto[lInc]/lRegionVol[lInc])) ;
- end; //for each row
-end;
+ TextForm.MemoT.Lines.add(lLabelStr+'Custom Region Analysis');
+ //add header
+ lStr := 'Index'+kT+'Name'+kT+'numVox'+kT+'numVoxNotZero'+kT+'fracNotZero';
+ if not lBinaryOverlay then
+ lStr := lStr+kT+'peak'+kT+'min'+kT+'mean'+kT+'meanNotZero';
+ TextForm.MemoT.Lines.Add(lLabelStr+lStr);
+ //report values
+ for lROI := 0 to High(gBGImg.LabelRA) do begin
+ if (lStat[lROI].nNot0 > 0) then begin
+ lStr := inttostr(lROI)+kT+gBGImg.LabelRA[lROI]
+ +kT+inttostr(lStat[lROI].n)+kT+inttostr(lStat[lROI].nNot0)+kT+ realtoStr(lStat[lROI].nNot0/lStat[lROI].n,3);
+ if not lBinaryOverlay then
+ lStr := lStr+kT+floattostr(lStat[lROI].max)+kT+floattostr(lStat[lROI].min)
+ +kT+floattostr(lStat[lROI].sum/lStat[lROI].n) +kT+floattostr(lStat[lROI].sumNot0/lStat[lROI].nNot0);
+ TextForm.MemoT.Lines.Add(lLabelStr+lStr );
+ end;
+ end;
+end;
procedure ShowDescriptive (lOverlayNum: integer; lShowFilename: boolean);
var
@@ -2990,11 +3038,19 @@ procedure TImgForm.LUTdropLoad(var lLayer: integer);
var
lStr: string;
begin
- if gMRIcroOverlay[lLayer].UsesCustomPalette then begin
+ (*if gMRIcroOverlay[lLayer].NIFTIhdr.intent_code = kNIFTI_INTENT_LABEL then begin
+ createLutLabel (gMRIcroOverlay[lLayer], 1.0);
+ //RefreshImagesTimer.Enabled := true;
+ exit;
+ end;
+ if gMRIcroOverlay[lLayer].UsesCustomPaletteRandomRainbow then
+ exit; *)
+ if gMRIcroOverlay[lLayer].UsesCustomPalette then begin
exit;
end;
//gMRIcroOverlay[lLayer].LUTindex := LUTdrop.ItemIndex;
- if gMRIcroOverlay[lLayer].LUTindex < knAutoLUT then begin
+
+ if gMRIcroOverlay[lLayer].LUTindex < knAutoLUT then begin
LoadMonochromeLUT(gMRIcroOverlay[lLayer].LUTindex,gBGImg,gMRIcroOverlay[lLayer]);
RefreshImagesTimer.Enabled := true;
exit;
@@ -3040,8 +3096,9 @@ var
lLayer: integer;
begin
lLayer := ActiveLayer;
- if gMRIcroOverlay[lLayer].WindowScaledMin = MinWindowEdit.Value then exit;
+ //if gMRIcroOverlay[lLayer].WindowScaledMin = MinWindowEdit.Value then exit;
gMRIcroOverlay[lLayer].WindowScaledMin := MinWindowEdit.Value;
+ gMRIcroOverlay[lLayer].WindowScaledMax := MaxWindowEdit.Value;
RescaleImagesTimer.Enabled := true;
end;
@@ -4116,7 +4173,7 @@ begin
end;
end;
-procedure DescribeVOIonLabelsX (lOverlayNum: integer);
+(*procedure DescribeVOIonLabelsX (lOverlayNum: integer);
var
lShowfilename: boolean = true;
lLocalMax,lLocalSum : HistoDoubleRA;
@@ -4163,8 +4220,8 @@ begin
lLocalMax[lInc] := 0;
lLocalSum[lInc] := 0;
lRegionVol[lInc] := 0;
- if (gMRIcroOverlay[kBGOverlayNum].UsesCustomPalette) then
- lLabelStr20[lInc] := gBGImg.LabelStr20[lInc]
+ if (gMRIcroOverlay[kBGOverlayNum].UsesLabels) then
+ lLabelStr20[lInc] := gBGImg.LabelRA[lInc]// gBGImg.LabelStr20[lInc]
else
lLabelStr20[lInc] := inttostr(lInc);
end;
@@ -4205,31 +4262,10 @@ begin
+kTextSep+floattostr( lLocalSum[lInc])+kTextSep+floattostr( lLocalSum[lInc]/lRegionVol[lInc]) //Sum>0, mean>0
+kTextSep + floattostr(lLocalMax[lInc])+kTextSep+floattostr(lXmm)+kTextSep+floattostr(lYmm)+kTextSep+floattostr(lZmm) );
end else if (lHisto[lInc] > 0) {necessarily also and (lRegionVol[lInc] > 0)} then
- TextForm.MemoT.Lines.Add({lLabelStr+ lLabelStr20[lInc]}gBGImg.LabelStr20[lInc] + kTextSep+ inttostr(lHisto[lInc])+kTextSep+floattostr( lHisto[lInc]/lRegionVol[lInc])) ;
+ TextForm.MemoT.Lines.Add(gBGImg.LabelRA[lInc] + kTextSep+ inttostr(lHisto[lInc])+kTextSep+floattostr( lHisto[lInc]/lRegionVol[lInc])) ;
end; //for each row
-end;
+end; 2014: no longer used (16 bit LabelRA)*)
-(*procedure DescribeVOIonLabels (lOverlayNum: integer);
-var
- lHisto: HistoRA;
- lInc: Integer;
-begin
- if (gMRIcroOverlay[lOverlayNum].ScrnBufferItems <> gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems) or (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP <> 1) or (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 2) then
- exit;
- TextForm.Memo1.Lines.Add('');
- TextForm.Memo1.Lines.add('Custom Region Analysis');
- TextForm.Memo1.Lines.add(' For Speculative Brodmann Map, 0=not cortical, 48=no Brodmann label');
- for lInc := 0 to 255 do
- lHisto[lInc] := 0;
- for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do
- if gMRIcroOverlay[lOverlayNum].ScrnBuffer^[lInc] > 0 then
- inc(lHisto[gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc]]);
- for lInc := 0 to 255 do begin
- if lHisto[lInc] > 0 then
- TextForm.Memo1.Lines.Add( gBGImg.LabelStr20[lInc] + ', ' + inttostr(lHisto[lInc]) );
-
- end;
-end;*)
function Mode (lOverlayNum: integer): double;
const
@@ -4303,6 +4339,7 @@ begin
Showmessage('You need to create or load an overlay (Overlay/Open or Draw/OpenVOI) to get overlay statistics.');
exit;
end;
+
TextForm.MemoT.Lines.Clear;
for lOverlayNum := 1 to knMaxOverlay do begin
if gMRIcroOverlay[lOverlayNum].ScrnBufferItems = gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems then begin
@@ -4360,7 +4397,7 @@ begin
lMode := Mode(lOverlayNum);
if lMode <> NaN then
TextForm.MemoT.Lines.Add('Mode:'+kTextSep+floattostr(lMode));
- if gMRIcroOverlay[kBGOverlayNum].UsesCustomPalette then
+ if gMRIcroOverlay[kBGOverlayNum].UsesLabels then
DescribeVOIonLabels(lOverlayNum,false);
TextForm.MemoT.Lines.Add('');
end; //overlaynum loaded
@@ -4602,6 +4639,12 @@ begin
{$IFDEF Darwin}
//Darwin starts passing a strange paramstr....
//with Darwin, opening a file can interfere with opening by association...
+
+ (*lStr := '/Users/rorden/desktop/mricrox/templates/aal.nii.gz';
+
+ ImgForm.OpenAndDisplayImg(lStr,True);
+ lStr := '/Users/rorden/desktop/mricrox/templates/crap.voi';
+ LoadOverlayIncludingRGB{LoadOverlay}(lStr); *)
exit;
//ResliceImg ('/Users/crlab/Documents/example_func.nii.gz','/Users/crlab/Documents/v1x.voi','/Users/crlab/Documents/example_func2standard.mat','/Users/crlab/Documents/z1x.nii.gz');
{$ENDIF}
diff --git a/nii_label.pas b/nii_label.pas
new file mode 100755
index 0000000..b01a1e5
--- /dev/null
+++ b/nii_label.pas
@@ -0,0 +1,257 @@
+unit nii_label;
+{$IFDEF FPC}
+{$mode delphi}
+{$ENDIF}
+interface
+uses
+{$IFNDEF FPC}
+ gziod,
+{$ELSE}
+ gzio2,
+{$ENDIF}
+ dialogs,Classes, SysUtils, define_types;
+
+procedure createLutLabel (var lut: TLUT; lSaturationFrac: single);
+procedure LoadLabels(lFileName: string; var lLabels: TStrRA; lOffset,lLength: integer);
+procedure LoadLabelsTxt(lFileName: string; var lLabels: TStrRA);
+
+implementation
+
+procedure LoadLabelsCore(lInStr: string; var lLabels: TStrRA);
+var
+ lIndex,lPass,lMaxIndex,lPos,lLength: integer;
+ lStr1: string;
+ lCh: char;
+begin
+ lLabels := nil;
+ lLength := length(lInStr);
+ lMaxIndex := -1;
+ for lPass := 1 to 2 do begin
+ lPos := 1;
+ if lPass = 2 then begin
+ if lMaxIndex < 1 then
+ exit;
+ SetLength(lLabels,lMaxIndex+1);
+ for lIndex := 0 to lMaxIndex do
+ lLabels[lIndex] := '';
+ end;
+ while lPos <= lLength do begin
+ lStr1 := '';
+ repeat
+ lCh := lInStr[lPos]; inc(lPos);
+ if (lCh >= '0') and (lCh <= '9') then
+ lStr1 := lStr1 + lCh;
+ until (lPos > lLength) or (lCh=kCR) or (lCh=UNIXeoln) or (((lCh=kTab)or (lCh=' ')) and (length(lStr1)>0));
+ if (length(lStr1) > 0) and (lPos <= lLength) then begin
+ lIndex := strtoint(lStr1);
+ if lPass = 1 then begin
+ if lIndex > lMaxIndex then
+ lMaxIndex := lIndex
+ end else if lIndex >= 0 then begin //pass 2
+ lStr1 := '';
+ repeat
+ lCh := lInStr[lPos]; inc(lPos);
+ if (lPos > lLength) or (lCh=kCR) or (lCh=UNIXeoln) {or (lCh=kTab) or (lCh=' ')} then
+ //
+ else
+ lStr1 := lStr1 + lCh;
+ until (lPos > lLength) or (lCh=kCR) or (lCh=UNIXeoln) {or (lCh=kTab)or (lCh=' ')};
+ lLabels[lIndex] := lStr1;
+ end; //if pass 2
+ end; //if lStr1>0
+ end; //while not EOF
+ end; //for each pass
+end;
+
+procedure LoadLabels(lFileName: string; var lLabels: TStrRA; lOffset,lLength: integer);
+var
+ f : file; // untyped file
+ s : string; // string for reading a file
+ sz: int64;
+ ptr: bytep;
+begin
+ if GzExt(lFilename) then begin
+ if (lLength < 1) then exit;
+ SetLength(s, lLength);
+ ptr := @s[1];
+ UnGZip (lFileName,ptr, lOffset,lLength);
+ end else begin
+ AssignFile(f, lFileName);
+ FileMode := fmOpenRead;
+ reset(f, 1);
+ if lOffset > 0 then
+ seek(f, lOffset);
+ if (lLength < 1) then
+ sz := FileSize(f)-lOffset
+ else
+ sz := lLength;
+ if (lOffset+sz) > FileSize(f) then
+ exit;
+ SetLength(s, sz);
+ BlockRead(f, s[1], length(s));
+ CloseFile(f);
+ FileMode := fmOpenReadWrite;
+ end;
+ LoadLabelsCore(s, lLabels);
+ //showmessage(lLabels[1]);
+end;
+
+procedure LoadLabelsTxt(lFileName: string; var lLabels: TStrRA);
+//filename = 'all.nii' will read 'aal.txt'
+var
+ lLUTname: string;
+begin
+ lLabels := nil; //empty current labels
+ lLUTname := changefileext(lFileName,'.txt');
+ if not Fileexists(lLUTname) then begin
+ lLUTname := ParseFileName(lFileName)+'.txt'; //file.nii.gz -> file.txt
+ if not Fileexists(lLUTname) then
+ exit;
+ end;
+ LoadLabels(lLUTname, lLabels,0,-1);
+end;
+
+procedure desaturateRGBA( var lRGBA: TRGBquad; frac: single);
+var
+ r,g,b: byte;
+ y: single;
+begin
+ r := lRGBA.rgbRed;
+ g := lRGBA.rgbGreen;
+ b := lRGBA.rgbBlue;
+ //convert RGB->YUV http://en.wikipedia.org/wiki/YUV
+ y := 0.299 * r + 0.587 * g + 0.114 * b;
+ r := round(y * (1-frac) + r * frac);
+ g := round(y * (1-frac) + g * frac);
+ b := round(y * (1-frac) + b * frac);
+ lRGBA.rgbRed := r;
+ lRGBA.rgbGreen := g;
+ lRGBA.rgbBlue := b;
+end;
+
+function makeRGB(r,g,b: byte): TRGBquad;
+begin
+ result.rgbRed := r;
+ result.rgbGreen := g;
+ result.rgbBlue := b;
+ result.rgbReserved := 64;
+end;
+
+procedure createLutLabel (var lut: TLUT; lSaturationFrac: single); //lLUT: 0=gray,1=red,2=green,3=blue
+var
+ i:integer;
+begin
+ lut[0] := makeRGB(0,0,0);
+ lut[0].rgbReserved:= 0;
+ lut[1] := makeRGB(71,46,154);
+ lut[2] := makeRGB(33,78,43);
+ lut[3] := makeRGB(192,199,10);
+ lut[4] := makeRGB(32,79,207);
+ lut[5] := makeRGB(195,89,204);
+ lut[6] := makeRGB(208,41,164);
+ lut[7] := makeRGB(173,208,231);
+ lut[8] := makeRGB(233,135,136);
+ lut[9] := makeRGB(202,20,58);
+ lut[10] := makeRGB(25,154,239);
+ lut[11] := makeRGB(210,35,30);
+ lut[12] := makeRGB(145,21,147);
+ lut[13] := makeRGB(89,43,230);
+ lut[14] := makeRGB(87,230,101);
+ lut[15] := makeRGB(245,113,111);
+ lut[16] := makeRGB(246,191,150);
+ lut[17] := makeRGB(38,147,35);
+ lut[18] := makeRGB(3,208,128);
+ lut[19] := makeRGB(25,37,57);
+ lut[20] := makeRGB(57,28,252);
+ lut[21] := makeRGB(167,27,79);
+ lut[22] := makeRGB(245,86,173);
+ lut[23] := makeRGB(86,203,120);
+ lut[24] := makeRGB(227,25,25);
+ lut[25] := makeRGB(208,209,126);
+ lut[26] := makeRGB(81,148,81);
+ lut[27] := makeRGB(64,187,85);
+ lut[28] := makeRGB(90,139,8);
+ lut[29] := makeRGB(199,111,7);
+ lut[30] := makeRGB(140,48,122);
+ lut[31] := makeRGB(48,102,237);
+ lut[32] := makeRGB(212,76,190);
+ lut[33] := makeRGB(180,110,152);
+ lut[34] := makeRGB(70,106,246);
+ lut[35] := makeRGB(120,130,182);
+ lut[36] := makeRGB(9,37,130);
+ lut[37] := makeRGB(192,160,219);
+ lut[38] := makeRGB(245,34,67);
+ lut[39] := makeRGB(177,222,76);
+ lut[40] := makeRGB(65,90,167);
+ lut[41] := makeRGB(157,165,178);
+ lut[42] := makeRGB(9,245,235);
+ lut[43] := makeRGB(193,222,250);
+ lut[44] := makeRGB(100,102,28);
+ lut[45] := makeRGB(181,47,61);
+ lut[46] := makeRGB(125,19,186);
+ lut[47] := makeRGB(145,130,250);
+ lut[48] := makeRGB(62,4,199);
+ lut[49] := makeRGB(8,232,67);
+ lut[50] := makeRGB(108,137,58);
+ lut[51] := makeRGB(36,211,50);
+ lut[52] := makeRGB(140,240,86);
+ lut[53] := makeRGB(237,11,182);
+ lut[54] := makeRGB(242,140,108);
+ lut[55] := makeRGB(248,21,77);
+ lut[56] := makeRGB(161,42,89);
+ lut[57] := makeRGB(189,22,112);
+ lut[58] := makeRGB(41,241,59);
+ lut[59] := makeRGB(114,61,125);
+ lut[60] := makeRGB(65,99,226);
+ lut[61] := makeRGB(121,115,50);
+ lut[62] := makeRGB(97,199,205);
+ lut[63] := makeRGB(50,166,227);
+ lut[64] := makeRGB(238,114,125);
+ lut[65] := makeRGB(149,190,128);
+ lut[66] := makeRGB(44,204,104);
+ lut[67] := makeRGB(214,60,27);
+ lut[68] := makeRGB(124,233,59);
+ lut[69] := makeRGB(167,66,66);
+ lut[70] := makeRGB(40,115,53);
+ lut[71] := makeRGB(167,230,133);
+ lut[72] := makeRGB(127,125,159);
+ lut[73] := makeRGB(178,103,203);
+ lut[74] := makeRGB(231,203,97);
+ lut[75] := makeRGB(30,125,125);
+ lut[76] := makeRGB(173,13,139);
+ lut[77] := makeRGB(244,176,159);
+ lut[78] := makeRGB(193,94,158);
+ lut[79] := makeRGB(203,131,7);
+ lut[80] := makeRGB(204,39,215);
+ lut[81] := makeRGB(238,198,47);
+ lut[82] := makeRGB(139,167,140);
+ lut[83] := makeRGB(135,124,226);
+ lut[84] := makeRGB(71,67,223);
+ lut[85] := makeRGB(234,175,231);
+ lut[86] := makeRGB(234,254,44);
+ lut[87] := makeRGB(217,1,110);
+ lut[88] := makeRGB(66,15,184);
+ lut[89] := makeRGB(14,198,61);
+ lut[90] := makeRGB(129,62,233);
+ lut[91] := makeRGB(19,237,47);
+ lut[92] := makeRGB(97,159,67);
+ lut[93] := makeRGB(165,31,148);
+ lut[94] := makeRGB(112,218,22);
+ lut[95] := makeRGB(244,58,120);
+ lut[96] := makeRGB(35,244,173);
+ lut[97] := makeRGB(73,47,156);
+ lut[98] := makeRGB(192,61,117);
+ lut[99] := makeRGB(12,67,181);
+ lut[100] := makeRGB(149,94,94);
+ for i := 1 to 100 do
+ lut[i+100] := lut[i]; //fill 101..200
+ for i := 1 to 55 do
+ lut[i+200] := lut[i]; //fill 201..255
+ if (lSaturationFrac < 0) or (lSaturationFrac >= 1.0) then
+ exit;
+ for i := 1 to 255 do
+ desaturateRGBA(lut[i], lSaturationFrac);
+end;
+
+end.
+
diff --git a/npm/MeanFLU.nii.gz b/npm/MeanFLU.nii.gz
new file mode 100755
index 0000000..f654e0a
Binary files /dev/null and b/npm/MeanFLU.nii.gz differ
diff --git a/npm/Notes.txt b/npm/Notes.txt
new file mode 100755
index 0000000..59d7218
--- /dev/null
+++ b/npm/Notes.txt
@@ -0,0 +1,52 @@
+Chris Rorden's 32-bit NPM: 28 August 2013 32bit; Threads used = 4 plankSize: 512mb
+Single Linear Regression [Weighted Least Squares]
+Mask = /Users/rorden/Downloads/dazhou_npm_glitch/BinaryLesionMask.nii
+Total voxels = 510340
+Number of observations = 35
+Image,FLU
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrTW_T2.nii,0
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrRH_T2.nii,5
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrRW_T2.nii,9
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrDE_T2.nii,4
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrJR_T2.nii,5
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrFJ_T2.nii,0
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrAC_T2.nii,7
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrMJ_T2.nii,4
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrAS_T2.nii,8
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrSH_T2.nii,1
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrDV_T2.nii,1
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrLO_T2.nii,10
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrMB_T2.nii,9
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrAS2_T2.nii,7
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrJR2_T2.nii,9
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrSF_T2.nii,1
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrTC_T2.nii,7
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrTR2_T2.nii,2
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrGK2_T2.nii,8
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrMH_T2.nii,1
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrTM_T2.nii,3
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrRS_T2.nii,9
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrAH_T2.nii,4
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrMB2_T2.nii,6
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrJM2_T2.nii,2
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrRC2_T2.nii,7
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrLM_T2.nii,4
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrMK_T2.nii,1
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrPC_T2.nii,7
+/Users/rorden/Downloads/dazhou_npm_glitch/zwr125_T2.nii,4
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrJE_T2.nii,9
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrJY_T2.nii,4
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrJA_T2.nii,9
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrMW_T2.nii,5
+/Users/rorden/Downloads/dazhou_npm_glitch/zwrML_T2.nii,9
+Analysis began = 2013-22-08 13:22:21
+Mask has voxels from 4080..468678
+Memory planks = 0.121153637537577
+Max voxels per Plank = 3834792
+Computing plank = 1
+Voxels tested = 75335
+75335 test Std Bonferroni FWE Z 0.050=4.836, 0.025=4.972, 0.01=5.146
+wlsFLU Range -5.551...3.209
+wlsFLU +FDR Z 0.050=9.20000000, 0.01=9.20000000
+wlsFLU -FDR Z 0.050=-2.31827721, 0.01=-3.42041674
+Analysis finished = 2013-22-08 13:22:31
\ No newline at end of file
diff --git a/npm/hdr.pas b/npm/hdr.pas
index 5641c5c..c952df6 100755
--- a/npm/hdr.pas
+++ b/npm/hdr.pas
@@ -2,7 +2,7 @@ unit hdr;
interface
{$H+}
{$Include ..\common\isgui.inc}
-uses nifti_hdr,define_types,classes, unpm;
+uses nifti_hdr,define_types,classes, unpm, nifti_types;
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);
@@ -60,10 +60,6 @@ begin
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
- showmessage('Error: This software can only read uncompressed images that are either 8-bit integer or 32-bit real precision.');
- exit;
- end; //beta *)
if UpCaseExt(lHdrName) = '.HDR' then
lHdrName := changefileext(lHdrName,'.img');
if (not GzExt(lHdrName) ) and (FSize(lHdrName) < lMaskVoxels) then begin
@@ -71,8 +67,9 @@ begin
exit;
end;
result := true;
- //gBitPixRA[lImageNumber] := lHdr.NIFTIhdr.bitpix;
- gDataTypeRA[lImageNumber] := lHdr.NIFTIhdr.datatype;
+
+ if (lImageNumber < 0) or (lImageNumber > kMaxImages) then exit;
+ gDataTypeRA[lImageNumber] := lHdr.NIFTIhdr.datatype;
gOffsetRA[lImageNumber] := lHdr.NIFTIhdr.vox_offset;
gScaleRA[lImageNumber] := lHdr.NIFTIhdr.scl_slope;
gInterceptRA[lImageNumber] := lHdr.NIFTIhdr.scl_inter;
@@ -396,7 +393,7 @@ var
lnVol,lC,lFSize: integer;
lImgBuffer: ByteP; lImgBufferItems{, lImgBufferBPP}: integer;
begin
- lnVol := lnVolIn;
+ lnVol := lnVolIn;
move(lNiftiHdr,lHdr,sizeof(lHdr));
lImgBufferItems := lHdr.dim[1]*lHdr.dim[2]*lHdr.dim[3];
//lImgBufferBPP:= 4;
@@ -507,7 +504,7 @@ begin
lBuff^[lC] := 0;
lC := kImgOffset+1;
move(lImgBuffer^[1],lBuff^[lC],lImgBufferItems*lImgBufferBPP*lnVol);
- if (lExt='.NII') then begin
+ if (lExt='.NII') then begin
Filemode := 1;
AssignFile(lF, lFileName);
Rewrite(lF,lFSize);
@@ -520,7 +517,7 @@ begin
lCompressedFilename := changefileextX(lFilename,'.nii.gz')
else
lCompressedFilename := lFilename;
- //FX(lFSize);
+
GZipBuffer(lCompressedFilename,lBuff,lFSize,false);
freemem(lBuff);
@@ -557,6 +554,8 @@ begin
if (lSingleFile) and (not lSPM2output) then begin
lHdr.magic := kNIFTI_MAGIC_EMBEDDED_HDR;
lOutNameMod := changefileextX(lOutNameMod,'.nii.gz');
+ //HACK lOutNameMod := changefileextX(lOutNameMod,'.nii');
+
end else if (not lSPM2output) then
lHdr.magic := kNIFTI_MAGIC_SEPARATE_HDR
else //the nifti_hdr reader converts the Analyze to NIfTI, so we need to save as NIfTI with NPM
diff --git a/npm/nifti_img.pas b/npm/nifti_img.pas
index dacbd11..2cf59f0 100755
--- a/npm/nifti_img.pas
+++ b/npm/nifti_img.pas
@@ -1,7 +1,7 @@
unit nifti_img;
interface
{$Include ..\common\isgui.inc}
-uses hdr,define_types,Classes,nifti_hdr,sysutils,dialogsx, unpm
+uses hdr,define_types,Classes,nifti_hdr,sysutils,dialogsx, unpm, nifti_types
{$IFDEF FPC},gzio2
{$ELSE}
,gziod
diff --git a/npm/npm.app/Contents/Info.plist b/npm/npm.app/Contents/Info.plist
old mode 100755
new mode 100644
diff --git a/npm/npm.app/Contents/MacOS/npm b/npm/npm.app/Contents/MacOS/npm
deleted file mode 100755
index 20acbf9..0000000
--- a/npm/npm.app/Contents/MacOS/npm
+++ /dev/null
@@ -1 +0,0 @@
-../../../npm
\ No newline at end of file
diff --git a/npm/npm.app/Contents/MacOS/npm b/npm/npm.app/Contents/MacOS/npm
new file mode 120000
index 0000000..20acbf9
--- /dev/null
+++ b/npm/npm.app/Contents/MacOS/npm
@@ -0,0 +1 @@
+../../../npm
\ No newline at end of file
diff --git a/npm/npm.app/Contents/PkgInfo b/npm/npm.app/Contents/PkgInfo
old mode 100755
new mode 100644
diff --git a/npm/npm.cfg b/npm/npm.cfg
index c599db3..b8a3ee8 100755
--- a/npm/npm.cfg
+++ b/npm/npm.cfg
@@ -33,7 +33,7 @@
-K$00400000
-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"
--R"C:\pas\mricron\common;C:\pas\mricron\fpmath"
+-U"..\common;..\delphionly;C:\pas\mricron\fpmath"
+-O"..\common;..\delphionly;C:\pas\mricron\fpmath"
+-I"..\common;..\delphionly;C:\pas\mricron\fpmath"
+-R"..\common;..\delphionly;C:\pas\mricron\fpmath"
diff --git a/npm/npm.dof b/npm/npm.dof
index 7fdd741..6f2cb20 100755
--- a/npm/npm.dof
+++ b/npm/npm.dof
@@ -94,7 +94,7 @@ OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
-SearchPath=C:\pas\mricron\common;C:\pas\mricron\fpmath
+SearchPath=..\common;..\delphionly;C:\pas\mricron\fpmath
Packages=Vcl40;Vclx40;VclSmp40;Qrpt40;Vcldb40;RxCtl4
Conditionals=
DebugSourceDirs=
@@ -138,6 +138,7 @@ Comments=
Count=1
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
[HistoryLists\hlSearchPath]
-Count=2
-Item0=C:\pas\mricron\common;C:\pas\mricron\fpmath
-Item1=C:\pas\mricron\common
+Count=3
+Item0=..\common;..\delphionly;C:\pas\mricron\fpmath
+Item1=C:\pas\mricron\common;C:\pas\mricron\fpmath
+Item2=C:\pas\mricron\common
diff --git a/npm/npm.dsk b/npm/npm.dsk
deleted file mode 100755
index 6852856..0000000
--- a/npm/npm.dsk
+++ /dev/null
@@ -1,184 +0,0 @@
-[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.lpi b/npm/npm.lpi
index fc30648..e244a9b 100755
--- a/npm/npm.lpi
+++ b/npm/npm.lpi
@@ -33,7 +33,7 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
- <Units Count="67">
+ <Units Count="69">
<Unit0>
<Filename Value="npm.lpr"/>
<IsPartOfProject Value="True"/>
@@ -42,7 +42,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="34" Y="11"/>
- <UsageCount Value="103"/>
+ <UsageCount Value="111"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit0>
@@ -54,11 +54,11 @@
<ResourceBaseClass Value="Form"/>
<UnitName Value="npmform"/>
<IsVisibleTab Value="True"/>
- <EditorIndex Value="4"/>
+ <EditorIndex Value="1"/>
<WindowIndex Value="0"/>
- <TopLine Value="102"/>
- <CursorPos X="23" Y="130"/>
- <UsageCount Value="103"/>
+ <TopLine Value="1046"/>
+ <CursorPos X="8" Y="1058"/>
+ <UsageCount Value="111"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
@@ -68,7 +68,7 @@
<UnitName Value="nifti_hdr"/>
<TopLine Value="358"/>
<CursorPos X="49" Y="368"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit2>
<Unit3>
<Filename Value="define_types.pas"/>
@@ -76,7 +76,7 @@
<UnitName Value="define_types"/>
<TopLine Value="945"/>
<CursorPos X="38" Y="959"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit3>
<Unit4>
<Filename Value="GraphicsMathLibrary.pas"/>
@@ -84,7 +84,7 @@
<UnitName Value="GraphicsMathLibrary"/>
<TopLine Value="681"/>
<CursorPos X="1" Y="738"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit4>
<Unit5>
<Filename Value="distr.pas"/>
@@ -92,7 +92,7 @@
<UnitName Value="distr"/>
<TopLine Value="99"/>
<CursorPos X="1" Y="107"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit5>
<Unit6>
<Filename Value="statcr.pas"/>
@@ -101,15 +101,16 @@
<WindowIndex Value="0"/>
<TopLine Value="4"/>
<CursorPos X="11" Y="25"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit6>
<Unit7>
<Filename Value="stats.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="stats"/>
- <TopLine Value="369"/>
- <CursorPos X="41" Y="370"/>
- <UsageCount Value="99"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="615"/>
+ <CursorPos X="1" Y="635"/>
+ <UsageCount Value="107"/>
</Unit7>
<Unit8>
<Filename Value="brunner.pas"/>
@@ -117,18 +118,16 @@
<UnitName Value="brunner"/>
<TopLine Value="500"/>
<CursorPos X="29" Y="517"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit8>
<Unit9>
<Filename Value="StatThdsUtil.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="StatThdsUtil"/>
- <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="11" Y="11"/>
- <UsageCount Value="99"/>
- <Loaded Value="True"/>
+ <TopLine Value="49"/>
+ <CursorPos X="38" Y="4"/>
+ <UsageCount Value="107"/>
</Unit9>
<Unit10>
<Filename Value="StatThds.pas"/>
@@ -137,7 +136,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="24" Y="6"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit10>
<Unit11>
<Filename Value="valformat.pas"/>
@@ -146,7 +145,7 @@
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="9" Y="12"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit11>
<Unit12>
<Filename Value="design.pas"/>
@@ -155,13 +154,10 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="design"/>
- <EditorIndex Value="6"/>
<WindowIndex Value="0"/>
<TopLine Value="37"/>
<CursorPos X="36" Y="58"/>
- <UsageCount Value="98"/>
- <Loaded Value="True"/>
- <LoadedDesigner Value="True"/>
+ <UsageCount Value="106"/>
</Unit12>
<Unit13>
<Filename Value="spread.pas"/>
@@ -170,13 +166,10 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="spread"/>
- <EditorIndex Value="5"/>
<WindowIndex Value="0"/>
- <TopLine Value="557"/>
+ <TopLine Value="556"/>
<CursorPos X="1" Y="584"/>
- <UsageCount Value="98"/>
- <Loaded Value="True"/>
- <LoadedDesigner Value="True"/>
+ <UsageCount Value="106"/>
</Unit13>
<Unit14>
<Filename Value="gzio2.pas"/>
@@ -184,7 +177,7 @@
<UnitName Value="gzio2"/>
<TopLine Value="774"/>
<CursorPos X="22" Y="793"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit14>
<Unit15>
<Filename Value="part.pas"/>
@@ -192,7 +185,7 @@
<UnitName Value="part"/>
<TopLine Value="91"/>
<CursorPos X="38" Y="108"/>
- <UsageCount Value="99"/>
+ <UsageCount Value="107"/>
</Unit15>
<Unit16>
<Filename Value="markorder.pas"/>
@@ -223,18 +216,16 @@
<UnitName Value="nifti_img"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="15" Y="1"/>
- <UsageCount Value="9"/>
+ <CursorPos X="77" Y="4"/>
+ <UsageCount Value="10"/>
</Unit19>
<Unit20>
<Filename Value="lesion_pattern.pas"/>
<UnitName Value="lesion_pattern"/>
- <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"/>
@@ -246,24 +237,22 @@
<WindowIndex Value="0"/>
<TopLine Value="23"/>
<CursorPos X="9" Y="50"/>
- <UsageCount Value="97"/>
+ <UsageCount Value="105"/>
</Unit21>
<Unit22>
<Filename Value="ReadInt.lrs"/>
<IsPartOfProject Value="True"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="3"/>
- <UsageCount Value="95"/>
+ <UsageCount Value="103"/>
</Unit22>
<Unit23>
<Filename Value="LesionStatThds.pas"/>
<UnitName Value="LesionStatThds"/>
- <EditorIndex Value="14"/>
<WindowIndex Value="0"/>
- <TopLine Value="173"/>
- <CursorPos X="1" Y="193"/>
- <UsageCount Value="33"/>
- <Loaded Value="True"/>
+ <TopLine Value="319"/>
+ <CursorPos X="28" Y="335"/>
+ <UsageCount Value="35"/>
</Unit23>
<Unit24>
<Filename Value="power.pas"/>
@@ -289,12 +278,10 @@
<Unit27>
<Filename Value="firth.pas"/>
<UnitName Value="firth"/>
- <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"/>
@@ -307,12 +294,10 @@
<Unit29>
<Filename Value="firthThds.pas"/>
<UnitName Value="firthThds"/>
- <EditorIndex Value="8"/>
<WindowIndex Value="0"/>
- <TopLine Value="605"/>
+ <TopLine Value="604"/>
<CursorPos X="52" Y="36"/>
<UsageCount Value="29"/>
- <Loaded Value="True"/>
</Unit29>
<Unit30>
<Filename Value="design.lfm"/>
@@ -370,11 +355,11 @@
<Unit38>
<Filename Value="regression.pas"/>
<UnitName Value="regression"/>
- <EditorIndex Value="3"/>
+ <EditorIndex Value="5"/>
<WindowIndex Value="0"/>
- <TopLine Value="90"/>
- <CursorPos X="44" Y="106"/>
- <UsageCount Value="39"/>
+ <TopLine Value="1"/>
+ <CursorPos X="69" Y="13"/>
+ <UsageCount Value="42"/>
<Loaded Value="True"/>
</Unit38>
<Unit39>
@@ -401,29 +386,28 @@
<Unit42>
<Filename Value="..\common\define_types.pas"/>
<UnitName Value="define_types"/>
- <EditorIndex Value="9"/>
+ <EditorIndex Value="4"/>
<WindowIndex Value="0"/>
- <TopLine Value="124"/>
- <CursorPos X="23" Y="148"/>
+ <TopLine Value="8"/>
+ <CursorPos X="57" Y="25"/>
<UsageCount Value="36"/>
<Loaded Value="True"/>
</Unit42>
<Unit43>
<Filename Value="hdr.pas"/>
<UnitName Value="hdr"/>
- <EditorIndex Value="13"/>
<WindowIndex Value="0"/>
- <TopLine Value="404"/>
- <CursorPos X="22" Y="418"/>
- <UsageCount Value="31"/>
- <Loaded Value="True"/>
+ <TopLine Value="1"/>
+ <CursorPos X="42" Y="5"/>
+ <UsageCount Value="34"/>
</Unit43>
<Unit44>
<Filename Value="..\common\gzio2.pas"/>
<UnitName Value="gzio2"/>
- <TopLine Value="223"/>
- <CursorPos X="16" Y="236"/>
- <UsageCount Value="6"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1770"/>
+ <CursorPos X="11" Y="1778"/>
+ <UsageCount Value="12"/>
</Unit44>
<Unit45>
<Filename Value="..\common\nifti_hdr.pas"/>
@@ -501,9 +485,9 @@
<Filename Value="tfce_clustering.pas"/>
<UnitName Value="tfce_clustering"/>
<WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="128" Y="8"/>
- <UsageCount Value="8"/>
+ <TopLine Value="8"/>
+ <CursorPos X="75" Y="11"/>
+ <UsageCount Value="10"/>
</Unit55>
<Unit56>
<Filename Value="C:\Developer\lazarus\lcl\include\menuitem.inc"/>
@@ -514,22 +498,18 @@
</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"/>
+ <UsageCount Value="36"/>
</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"/>
@@ -542,30 +522,30 @@
<Unit60>
<Filename Value="unpm.pas"/>
<UnitName Value="unpm"/>
- <EditorIndex Value="1"/>
+ <EditorIndex Value="3"/>
<WindowIndex Value="0"/>
- <TopLine Value="20"/>
- <CursorPos X="84" Y="43"/>
- <UsageCount Value="37"/>
+ <TopLine Value="1"/>
+ <CursorPos X="49" Y="8"/>
+ <UsageCount Value="40"/>
<Loaded Value="True"/>
</Unit60>
<Unit61>
<Filename Value="turbolesion.pas"/>
<UnitName Value="turbolesion"/>
- <EditorIndex Value="11"/>
+ <EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
- <CursorPos X="94" Y="6"/>
- <UsageCount Value="33"/>
+ <CursorPos X="63" Y="8"/>
+ <UsageCount Value="35"/>
<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"/>
+ <TopLine Value="129"/>
+ <CursorPos X="22" Y="134"/>
+ <UsageCount Value="33"/>
</Unit62>
<Unit63>
<Filename Value="C:\usr\local\share\fpcsrc\rtl\objpas\sysutils\sysstrh.inc"/>
@@ -597,127 +577,142 @@
<CursorPos X="10" Y="500"/>
<UsageCount Value="31"/>
</Unit66>
+ <Unit67>
+ <Filename Value="..\..\..\..\..\..\usr\local\share\fpcsrc\packages\paszlib\src\zdeflate.pas"/>
+ <UnitName Value="zdeflate"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="1035"/>
+ <CursorPos X="10" Y="1049"/>
+ <UsageCount Value="12"/>
+ </Unit67>
+ <Unit68>
+ <Filename Value="..\..\..\..\..\..\Developer\lazarus\lcl\include\menuitem.inc"/>
+ <WindowIndex Value="0"/>
+ <TopLine Value="5"/>
+ <CursorPos X="1" Y="83"/>
+ <UsageCount Value="10"/>
+ </Unit68>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="371" Column="29" TopLine="344"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="1484" Column="8" TopLine="1470"/>
</Position1>
<Position2>
<Filename Value="turbolesion.pas"/>
- <Caret Line="424" Column="113" TopLine="389"/>
+ <Caret Line="398" Column="113" TopLine="379"/>
</Position2>
<Position3>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="506" Column="53" TopLine="471"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="4" Column="52" TopLine="1"/>
</Position3>
<Position4>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="9" Column="89" TopLine="1"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="83" Column="10" TopLine="63"/>
</Position4>
<Position5>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="424" Column="44" TopLine="397"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="335" Column="16" TopLine="324"/>
</Position5>
<Position6>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="11" Column="44" TopLine="1"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="422" Column="30" TopLine="402"/>
</Position6>
<Position7>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="18" Column="14" TopLine="1"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="462" Column="40" TopLine="460"/>
</Position7>
<Position8>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="5" Column="47" TopLine="1"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="799" Column="35" TopLine="786"/>
</Position8>
<Position9>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="18" Column="14" TopLine="1"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="800" Column="58" TopLine="786"/>
</Position9>
<Position10>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="290" Column="62" TopLine="272"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="801" Column="29" TopLine="786"/>
</Position10>
<Position11>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="30" Column="122" TopLine="20"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="805" Column="26" TopLine="786"/>
</Position11>
<Position12>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="19" Column="153" TopLine="16"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="811" Column="50" TopLine="816"/>
</Position12>
<Position13>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="5" Column="150" TopLine="2"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="906" Column="26" TopLine="886"/>
</Position13>
<Position14>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="194" Column="19" TopLine="158"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="2" Column="127" TopLine="1"/>
</Position14>
<Position15>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="10" Column="112" TopLine="1"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="130" Column="21" TopLine="110"/>
</Position15>
<Position16>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="200" Column="83" TopLine="193"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="2" Column="129" TopLine="1"/>
</Position16>
<Position17>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="14" Column="58" TopLine="1"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="25" Column="18" TopLine="5"/>
</Position17>
<Position18>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="113" Column="6" TopLine="84"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="3" Column="130" TopLine="1"/>
</Position18>
<Position19>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="127" Column="30" TopLine="98"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="82" Column="17" TopLine="62"/>
</Position19>
<Position20>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="13" Column="126" TopLine="1"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="94" Column="15" TopLine="74"/>
</Position20>
<Position21>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="22" Column="97" TopLine="5"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="119" Column="25" TopLine="99"/>
</Position21>
<Position22>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="216" Column="35" TopLine="205"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="3" Column="129" TopLine="1"/>
</Position22>
<Position23>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="220" Column="22" TopLine="204"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="104" Column="30" TopLine="84"/>
</Position23>
<Position24>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="218" Column="13" TopLine="203"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="414" Column="49" TopLine="394"/>
</Position24>
<Position25>
- <Filename Value="turbolesion.pas"/>
- <Caret Line="213" Column="32" TopLine="204"/>
+ <Filename Value="npmform.pas"/>
+ <Caret Line="992" Column="7" TopLine="991"/>
</Position25>
<Position26>
<Filename Value="npmform.pas"/>
- <Caret Line="129" Column="66" TopLine="7"/>
+ <Caret Line="991" Column="7" TopLine="990"/>
</Position26>
<Position27>
<Filename Value="npmform.pas"/>
- <Caret Line="4" Column="90" TopLine="1"/>
+ <Caret Line="5" Column="105" TopLine="1"/>
</Position27>
<Position28>
<Filename Value="npmform.pas"/>
- <Caret Line="38" Column="5" TopLine="29"/>
+ <Caret Line="103" Column="7" TopLine="83"/>
</Position28>
<Position29>
<Filename Value="npmform.pas"/>
- <Caret Line="7" Column="41" TopLine="1"/>
+ <Caret Line="118" Column="32" TopLine="98"/>
</Position29>
<Position30>
<Filename Value="npmform.pas"/>
- <Caret Line="38" Column="13" TopLine="9"/>
+ <Caret Line="434" Column="8" TopLine="410"/>
</Position30>
</JumpHistory>
</ProjectOptions>
diff --git a/npm/npmform.dfm b/npm/npmform.dfm
index ac7d3e3..b439c42 100755
Binary files a/npm/npmform.dfm and b/npm/npmform.dfm differ
diff --git a/npm/npmform.lfm b/npm/npmform.lfm
index 701cedc..c7d45da 100755
--- a/npm/npmform.lfm
+++ b/npm/npmform.lfm
@@ -5,17 +5,17 @@ object MainForm: TMainForm
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 = '1.0.2.0'
+ LCLVersion = '1.0.12.0'
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
@@ -101,14 +101,17 @@ object MainForm: TMainForm
end
object MultipleRegress: TMenuItem
Caption = 'Multiple WLS Regression'
+ Visible = False
OnClick = MultipleRegressClick
end
object SingleRegress: TMenuItem
Caption = 'Single WLS Regression'
+ Visible = False
OnClick = SingleRegressClick
end
object DualImageCorrelation1: TMenuItem
Caption = 'Dual image correlation'
+ Visible = False
OnClick = DualImageCorrelation1Click
end
end
@@ -282,10 +285,4 @@ object MainForm: TMainForm
left = 8
top = 72
end
- object StartTimer: TTimer
- Enabled = False
- OnTimer = StartTimerTimer
- left = 141
- top = 67
- end
-end
+end
\ No newline at end of file
diff --git a/npm/npmform.lrs b/npm/npmform.lrs
index c33e69c..f839837 100755
--- a/npm/npmform.lrs
+++ b/npm/npmform.lrs
@@ -3,81 +3,81 @@
LazarusResources.Add('TMainForm','FORMDATA',[
'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'
+ +'ic Mapping'#12'ClientHeight'#3#162#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'
- +'u'#9'MainMenu1'#4'left'#2#8#3'top'#2#8#0#9'TMenuItem'#5'File1'#7'Caption'#6
- +#4'File'#0#9'TMenuItem'#9'SaveText1'#7'Caption'#6#12'Save text...'#7'OnClick'
- +#7#14'Savetext1Click'#0#0#9'TMenuItem'#5'Exit1'#7'Caption'#6#4'Exit'#7'OnCli'
- +'ck'#7#10'Exit1Click'#0#0#0#9'TMenuItem'#5'Edit1'#7'Caption'#6#4'Edit'#0#9'T'
- +'MenuItem'#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'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'
- +'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
- +'ROIanalysis1'#7'Caption'#6#12'ROI analysis'#7'OnClick'#7#17'ROIanalysis1Cli'
- +'ck'#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 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'#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
+ +'FormShow'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#8'1.0.12.0'#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 grou'
+ +'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'Visible'#8#7'OnClick'#7#20'MultipleRegressCli'
+ +'ck'#0#0#9'TMenuItem'#13'SingleRegress'#7'Caption'#6#21'Single WLS Regressio'
+ +'n'#7'Visible'#8#7'OnClick'#7#18'SingleRegressClick'#0#0#9'TMenuItem'#21'Dua'
+ +'lImageCorrelation1'#7'Caption'#6#22'Dual image correlation'#7'Visible'#8#7
+ +'OnClick'#7#26'DualImageCorrelation1Click'#0#0#0#9'TMenuItem'#8'Options1'#7
+ +'Caption'#6#7'Options'#0#9'TMenuItem'#13'Permutations1'#7'Caption'#6#12'Perm'
+ +'utations'#0#9'TMenuItem'#2'N0'#9'AutoCheck'#9#7'Caption'#6#4'None'#7'Checke'
+ +'d'#9#10'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'#0#0
+ +#9'TMenuItem'#5'N1000'#3'Tag'#3#232#3#9'AutoCheck'#9#7'Caption'#6#4'1000'#10
+ +'GroupIndex'#2'{'#9'RadioItem'#9#7'OnClick'#7#14'radiomenuclick'#0#0#9'TMenu'
+ +'Item'#5'N2000'#3'Tag'#3#208#7#9'AutoCheck'#9#7'Caption'#6#4'2000'#10'GroupI'
+ +'ndex'#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'3000'#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'R'
+ +'adioItem'#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'On'
+ +'Click'#7#13'testmenuclick'#0#0#9'TMenuItem'#6'BMmenu'#7'Caption'#6#14'Brunn'
+ +'er 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'Cap'
+ +'tion'#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'AutoCheck'#9#7'Caption'#6#1'2'#10
+'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#9'TMen'
- +'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'
+ +'uItem'#2'T3'#9'AutoCheck'#9#7'Caption'#6#1'3'#10'GroupIndex'#3#131#0#9'Radi'
+ +'oItem'#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'thr'
+ +'eadChange'#0#0#9'TMenuItem'#2'T7'#9'AutoCheck'#9#7'Caption'#6#1'7'#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#6'TTimer'#10'StartTimer'#7'Enabled'#8#7'OnTimer'
- +#7#15'StartTimerTimer'#4'left'#3#141#0#3'top'#2'C'#0#0#0
-]);
+ +#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'AutoCheck'#9#7'Capt'
+ +'ion'#6#2'15'#10'GroupIndex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadCh'
+ +'ange'#0#0#9'TMenuItem'#3'T16'#9'AutoCheck'#9#7'Caption'#6#2'16'#10'GroupInd'
+ +'ex'#3#131#0#9'RadioItem'#9#7'OnClick'#7#12'threadChange'#0#0#0#9'TMenuItem'
+ +#16'PlankSzMenuItem1'#7'Caption'#6#10'Plank Size'#7'OnClick'#7#21'PlankSzMen'
+ ,'uItem1Click'#0#0#0#9'TMenuItem'#10'Utilities1'#7'Caption'#6#9'Utilities'#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#0#9'TMenuItem'#5'Help1'#7'Caption'#6#4'Help'#7'Visible'#8#0#9'TMenuI'
+ +'tem'#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
+]);
\ No newline at end of file
diff --git a/npm/npmform.pas b/npm/npmform.pas
index 76203f8..a7ba9b2 100755
--- a/npm/npmform.pas
+++ b/npm/npmform.pas
@@ -8,7 +8,7 @@ uses
define_types,SysUtils,
part,StatThds,statcr,StatThdsUtil,Brunner,DISTR,nifti_img,
Messages, userDir,
- Classes, Graphics, Controls, Forms, DialogsX,Dialogs,
+ Classes, Graphics, Controls, Forms, DialogsX,Dialogs, nifti_types ,
Menus, ComCtrls, ExtCtrls, StdCtrls,
overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr,
@@ -91,7 +91,6 @@ type
MaskedintensitynormalizationB1: TMenuItem;
Binarizeimages1: TMenuItem;
PlankSzMenuItem1: TMenuItem;
- StartTimer: TTimer;
//Setnonseroto1001: TMenuItem;
//AnaCOMmenu: TMenuItem;
//MonteCarloSimulation1: TMenuItem;
@@ -101,7 +100,7 @@ type
procedure NPMmsgUI( lStr: string);
procedure NPMmsgClearUI;
procedure NPMmsgSaveUI(lFilename: string);
- procedure ProcessParamStr;
+ //procedure ProcessParamStr;
function GetValX (var lnSubj, lnFactors: integer; var lSymptomRA: singleP; var lImageNames: TStrings; var lCrit: integer; {lBinomial : boolean;} var lPredictorList: TStringList):boolean;
function FirthNPMAnalyze (var lImages: TStrings; var lPredictorList: TStringList; var lMaskHdr: TMRIcroHdr; lnCond,lnCrit: integer; var lSymptomRA: SingleP; var lOutName: string): boolean;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
@@ -116,7 +115,7 @@ type
//function Balance (var lImageName,lMaskName: String; lMethod: integer{lInflection: boolean}): boolean;
procedure LesionBtnClick(Sender: TObject);
procedure Copy1Click(Sender: TObject);
- procedure StartTimerTimer(Sender: TObject);
+ //procedure StartTimerTimer(Sender: TObject);
procedure testmenuclick(Sender: TObject);
procedure radiomenuclick(Sender: TObject);
procedure Makemeanimage1Click(Sender: TObject);
@@ -402,18 +401,18 @@ begin
end;
-procedure TMainForm.StartTimerTimer(Sender: TObject);
+(*procedure TMainForm.StartTimerTimer(Sender: TObject);
begin
if StartTimer.Tag < 2 then begin
- StartTimer.tag := StartTimer.tag + 1;
- exit;
+ StartTimer.tag := StartTimer.tag + 1;
+ exit;
end;
StartTimer.Enabled := false;
- if (ParamCount > 0) then ProcessParamStr;
+ //if (ParamCount > 0) then ProcessParamStr;
-end;
+end; *)
procedure TMainForm.testmenuclick(Sender: TObject);
begin
@@ -919,7 +918,7 @@ begin
DoLesion (lPrefs);
end;
-procedure TMainForm.ProcessParamStr;
+(*procedure TMainForm.ProcessParamStr;
label
666;
var
@@ -990,10 +989,6 @@ begin
3: NPMMultipleRegressClick( lVALFilename, lMaskFilename,lOutFilename);
end;
- (*repeat
- Sleep(1000);
- Writeln('waiting');
- until gThreadsRunning = 0; *)
Writeln('Goodbye');
Application.ProcessMessages;
@@ -1002,9 +997,52 @@ begin
// stop program loop
666:
Close;
-end;
-
+end; *)
+(*function TestT: string;
+var
+ T: double;
+ l1,l0,lN: integer;
+
+ lIn: DoubleP0;
+ lInp: pointer;
+ //TStat2 (lnSubj, lnGroupX: integer; var lIn: DoubleP0; var lOutT: double);
+begin
+ T := 666;
+ l1 := 16;
+ l0 := 8;
+ lN := l0+l1;
+ createArray64(lInp,lIn,lN);
+ lIn^[0] := 44 ;
+ lIn^[1] := 23 ;
+ lIn^[2] := 41 ;
+ lIn^[3] := 32 ;
+ lIn^[4] := 60 ;
+ lIn^[5] := 58 ;
+ lIn^[6] := 57 ;
+ lIn^[7] := 57 ;
+ lIn^[8] := 55 ;
+ lIn^[9] := 56 ;
+ lIn^[10] := 60;
+ lIn^[11] := 59;
+ lIn^[12] := 57;
+ lIn^[13] := 58;
+ lIn^[14] := 56;
+ lIn^[15] := 57;
+ lIn^[16] := 2 ;
+ lIn^[17] := 22;
+ lIn^[18] := 24;
+ lIn^[19] := 22;
+ lIn^[20] := 18;
+ lIn^[21] := 12;
+ lIn^[22] := 15 ;
+ lIn^[23] := 22;
+
+ TStat2 (lN, l1, lIn, T);
+ result := floattostr(T);
+ freemem(lInp);
+
+end; *)
procedure TMainForm.FormShow(Sender: TObject);
begin
@@ -1015,9 +1053,9 @@ begin
ShortTimeFormat := 'YYYY-MMM-DD hh:nn:ss'; //freepascal TimeToStr
{$IFDEF FPC}{$IFNDEF UNIX} ReadParamStr; {$ENDIF} {$ENDIF}
{$IFDEF benchmark}
- MonteCarloSimulation1.visible := true;
+ //MonteCarloSimulation1.visible := true;
{$ENDIF}
- StartTimer.enabled := true;
+ //StartTimer.enabled := true;
end;
procedure TMainForm.PairedTMenuClick(Sender: TObject);
@@ -1151,6 +1189,9 @@ end;
procedure TMainForm.MultipleRegressClick(Sender: TObject);
var lVALFilename, lMaskname,lOutname: string;
begin
+ Showmessage('This function has been superceded by nii_stat');
+ exit;
+
if not MainForm.OpenDialogExecute('Select MRIcron VAL file',false,false,'MRIcron VAL (*.val)|*.val') then begin
ShowMsg('NPM aborted: VAL file selection failed.');
exit;
@@ -1169,10 +1210,13 @@ end;
procedure TMainForm.SingleRegressClick(Sender: TObject);
var lVALFilename, lMaskname,lOutname: string;
begin
+ showmessage('This function has been superceded with nii_stat');
+ exit;
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;
+ lOutname := lVALFilename;
NPMSingleRegress (lVALFilename, lMaskname,lOutname);
end;
@@ -1435,6 +1479,8 @@ var
lMultiSymptomRA,lTempRA: singleP;
//lBinomial: boolean;
begin
+ Showmessage('This function has been superceded by nii_stat');
+ exit;
// lBinomial := false;
lImageNames:= TStringList.Create; //not sure why TStrings.Create does not work???
//next, get 1st group
@@ -2159,4 +2205,4 @@ finalization
{$ENDIF} //Windows
end.
-
+
\ No newline at end of file
diff --git a/npm/regression.pas b/npm/regression.pas
index 9e17564..b802ca9 100755
--- a/npm/regression.pas
+++ b/npm/regression.pas
@@ -10,7 +10,7 @@ uses
{$IFDEF FPC} utypes,regmult,{$ELSE}
utypes,regmult,
{$ENDIF}define_types,Classes,nifti_hdr,sysutils,nifti_img,
- StatThdsUtil,Distr,Dialogsx, tfce_clustering, unpm;
+ StatThdsUtil,Distr,Dialogsx, tfce_clustering, unpm, nifti_types;
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;
@@ -324,7 +324,8 @@ begin
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
+
+ lnStatFact := lnFactors + 1; //factors + overall model
if lnStatFact > (kMaxFact-1) then begin //-1 because factors + model
NPMmsg('ERROR: Can not analyze more than = ' +inttostr(kMaxFact-1)+' factors');
goto 667;
@@ -335,7 +336,6 @@ begin
NPMmsg('Unable to load mask ' +lMaskHdr.ImgFileName);
goto 667;
end;
-
//next find start and end of mask
lPos := 0;
repeat
@@ -487,9 +487,11 @@ begin
//save mean
lOutNameMod := ChangeFilePostfixExt(lOutName,'Mean'+lRunName,'.hdr');
+
if not FileExistsEX(lOutNameMod) then
NIFTIhdr_SaveHdrImg(lOutNameMod,lStatHdr,true,not IsNifTiMagic(lMaskHdr.NIFTIhdr),true,lOutImgMn,1);
//save regression
+
for lFact := 1 to (lnStatFact) do begin
if (lFact > lnFactors) and (lnFactors = 1) then begin
//nothing
@@ -604,7 +606,6 @@ begin
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;
diff --git a/npm/stats.pas b/npm/stats.pas
index ccee73d..28f96cc 100755
--- a/npm/stats.pas
+++ b/npm/stats.pas
@@ -590,7 +590,6 @@ begin
lnGroupY := lnSubj - lnGroupX;
lOutT := 0;
if (lnGroupX < 1) or (lnGroupY < 1) or (lnSubj < 3) then //need at least 1 subj in each group
-
exit;
lSumx := 0;
lSumSqrX := 0;
diff --git a/npm/tfce_clustering.pas b/npm/tfce_clustering.pas
index 7ca95e0..aa3c4fa 100755
--- a/npm/tfce_clustering.pas
+++ b/npm/tfce_clustering.pas
@@ -8,7 +8,7 @@ uses
{$ELSE}
{$IFDEF GUI} LCLType, LCLintf,{$ENDIF}
{$ENDIF}
-define_types,dialogsx,SysUtils,nifti_hdr,nifti_img, math,unpm;
+define_types,dialogsx,SysUtils,nifti_hdr,nifti_img, math,unpm, nifti_types;
//procedure FindClusters (lMultiBuf: SingleP; lXdim, lYDim, lZDim, lThreshClusterSz: integer; lMinNeg, lMinPos: single);
diff --git a/npm/turbolesion.pas b/npm/turbolesion.pas
index 6b18218..42a7c3a 100755
--- a/npm/turbolesion.pas
+++ b/npm/turbolesion.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, Dialogs, nifti_types,
StdCtrls, ComCtrls,ExtCtrls,Menus, overlap,ReadInt,lesion_pattern,stats,LesionStatThds,nifti_hdr, unpm,
{$IFDEF FPC} LResources,gzio2,
diff --git a/npm/unpm.pas b/npm/unpm.pas
index 1628b6a..46de915 100755
--- a/npm/unpm.pas
+++ b/npm/unpm.pas
@@ -5,7 +5,7 @@ interface
uses
upower,math,utypes,
-regmult,IniFiles,Classes, SysUtils, define_types,distr, statcr, StatThdsUtil, userdir, dialogsx, nifti_hdr, StatThds, lesion_pattern;
+regmult,IniFiles,Classes, SysUtils , nifti_types, define_types,distr, statcr, StatThdsUtil, userdir, dialogsx, nifti_hdr, StatThds, lesion_pattern;
Type
TNPMPrefs = record
NULP,ROI,ttest,BMtest: boolean;
@@ -105,16 +105,11 @@ begin
{$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';
+ result := 'Chris Rorden''s NPM '+kMRIcronVers+' :: '+inttostr(sizeof(integer)*8)+'-bit :: Threads used = '+inttostr(gnCPUThreads )+' :: plankSize = '+inttostr(gNPMPrefs.PlankMB)+'mb';
end;
procedure Refresher;
@@ -562,7 +557,7 @@ begin
exit;
end;
lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
- if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
+ if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,-1)){make sure there is uncompressed .img file} then begin
ShowMsg('Mask file size too small.');
goto 666;
end;
@@ -571,7 +566,6 @@ begin
goto 666;
end;
lTemp4D := CreateDecompressed4D(lImageNames);
-
lImageNames1:= TStringList.Create;
for lCol := 1 to lnFactors do begin
lPredictorList1.Clear;
@@ -599,6 +593,7 @@ begin
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);
@@ -639,7 +634,7 @@ begin
goto 666;
end;
lMaskVoxels := ComputeImageDataBytes8bpp(lMaskHdr);
- if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,0)){make sure there is uncompressed .img file} then begin
+ if (lMaskVoxels < 2) or (not CheckVoxels(lMaskname,lMaskVoxels,-1)){make sure there is uncompressed .img file} then begin
ShowMsg('Mask file size too small.');
goto 666;
end;
diff --git a/npm/wlsFLU.nii.gz b/npm/wlsFLU.nii.gz
new file mode 100755
index 0000000..6cfa648
Binary files /dev/null and b/npm/wlsFLU.nii.gz differ
diff --git a/ortho_reorient.pas b/ortho_reorient.pas
index 27a741a..02e99eb 100755
--- a/ortho_reorient.pas
+++ b/ortho_reorient.pas
@@ -3,7 +3,7 @@ unit ortho_reorient;
interface
uses
- SysUtils,define_types,GraphicsMathLibrary,prefs,nifti_hdr,dialogs;
+ SysUtils,define_types,GraphicsMathLibrary,prefs,nifti_hdr,dialogs, nifti_types;
function OrthoReorientCore(var lHdr: TMRIcroHdr; l4D: boolean): boolean;
diff --git a/render_composite.pas b/render_composite.pas
index 285592e..491cd5a 100755
--- a/render_composite.pas
+++ b/render_composite.pas
@@ -18,7 +18,7 @@ rendernothreads,
{$ENDIF}
SysUtils, GraphicsMathLibrary,Classes, Graphics, Controls, Forms, Dialogs,ExtCtrls,Buttons,
nifti_img, nifti_hdr,define_types,nifti_img_view,StdCtrls, Menus,ClipBrd,ReadInt,cutout,IniFiles,
- ComCtrls;
+ ComCtrls, nifti_types;
type
TRender = record
Zoom: single;
@@ -1072,4 +1072,4 @@ var
ImgForm.StatusLabel.caption :=('update(ms): '+inttostr(GetTickCount-lStartTime));
end; //proceudre VolumeRotate;
-end.
+end.
\ No newline at end of file
diff --git a/reslice_img.pas b/reslice_img.pas
index d58c216..85b26ec 100755
--- a/reslice_img.pas
+++ b/reslice_img.pas
@@ -3,7 +3,7 @@ unit reslice_img;
interface
uses
{$ifndef fpc}{windows,} {$endif}
-GraphicsMathLibrary,nifti_hdr;
+GraphicsMathLibrary,nifti_hdr, nifti_types;
function Reslice_Img_To_Unaligned (var lTargHdr: TNIfTIhdr; var lSrcHdr: TMRIcroHdr; lTrilinearSmoothIn: boolean): boolean;
function Hdr2InvMat (lHdr: TNiftiHdr; var lOK: boolean): TMatrix;
procedure Voxel2mm(var X,Y,Z: single; var lHdr: TNIfTIHdr);
@@ -540,4 +540,4 @@ begin
result := lSrcMatInv;
end;
-end.
+end.
\ No newline at end of file
diff --git a/statclustertable.pas b/statclustertable.pas
index c7f9f74..8ab69ff 100755
--- a/statclustertable.pas
+++ b/statclustertable.pas
@@ -104,23 +104,20 @@ end;
procedure Report (lClusterMax: single; lClusterSz, lClusterMaxPos: integer);
var
- lAALstr,lBAstr : string;
+ lTemplateLabel: string;
begin
if lClusterSz < lMinClusterSz then
exit;
- lBAstr := '';
- if gMRIcroOverlay[2].ImgBufferItems = lVolSz then //BA map loaded
- lBAstr := inttostr(gMRIcroOverlay[2].ImgBuffer^[lClusterMaxPos]);
- if gMRIcroOverlay[3].ImgBufferItems = lVolSz then //AAL map loaded
- lAALstr := gBGImg.LabelStr20[gMRIcroOverlay[3].ImgBuffer^[lClusterMaxPos]];
-
- TextForm.MemoT.lines.add(XYZstr(lClusterMaxPos)+kTextSep+XYZstr(CenterOfMassPosition)+kTextSep+inttostr(lClusterSz)+kTextSep+lCh+floattostr(lClusterMax)+kTextSep+(lBAStr)+kTextSep+(lAALstr));
+ //lTemplateLabel := ImgForm.BGLabelString(lClusterMaxPos);
+ //burger ImgIntensityString
+ lTemplateLabel := ImgForm.ImgIntensityString(gMRIcroOverlay[2], lClusterMaxPos);
+ TextForm.MemoT.lines.add(XYZstr(lClusterMaxPos)+kTextSep+XYZstr(CenterOfMassPosition)+kTextSep+inttostr(lClusterSz)+kTextSep+lCh+floattostr(lClusterMax)+kTextSep+lTemplateLabel);
end;
procedure ReportLabel;
begin
TextForm.MemoT.lines.add('# Data='+kTextSep+lHdr.HdrFileName +kTextSep+'Threshold='+kTextSep+floattostr(lThreshIn) +kTextSep+'MinCluster='+kTextSep+inttostr(lMinClusterSz));
- TextForm.MemoT.lines.add('#X'+kTextSep+'Y'+kTextSep+'Z'+kTextSep+'Xcom'+kTextSep+'Ycom'+kTextSep+'Zcom'+kTextSep+'ClusterSize[Vox]'+kTextSep+'Max'+kTextSep+'BA'+kTextSep+'AAL');
+ TextForm.MemoT.lines.add('#X'+kTextSep+'Y'+kTextSep+'Z'+kTextSep+'Xcom'+kTextSep+'Ycom'+kTextSep+'Zcom'+kTextSep+'ClusterSize[Vox]'+kTextSep+'Max'+kTextSep+'Template');
end;
Procedure IncQra(var lVal, lQSz: integer);
@@ -280,7 +277,7 @@ end;
procedure BatchCluster;
var
lInc,lNumberofFiles,lMinClusterSz: integer;
- lFilename,lBAname,lAALname:string;
+ lFilename,lTemplateName:string;
lPref: boolean;
lThresh: single;
begin
@@ -289,16 +286,16 @@ begin
ImgForm.UpdateLayerMenu;
lMinClusterSz := ReadIntForm.GetInt('Minimum cluster size [in voxels]: ', 1,4,9999);
lThresh := ReadFloatForm.GetFloat('Please enter statistical threshold. ', -9999,2.3,9999);
- if not OpenDialogExecute(kImgFilter,'Select statistical maps',true) then exit;
+ lTemplateName := '';
+ if OpenDialogExecute(kImgFilter,'Select anatomical template (optional)',false) then begin
+ lTemplateName := HdrForm.OpenHdrDlg.Filename;
+ end;
+ if not OpenDialogExecute(kImgFilter,'Select statistical maps',true) then exit;
lNumberofFiles:= HdrForm.OpenHdrDlg.Files.Count;
if lNumberofFiles < 1 then
exit;
- lAALname := gTemplateDir+pathdelim+'aal.nii.gz';
- if not fileexists(lAALname) then
- lAALName := '';
- lBAname := gTemplateDir+pathdelim+'brodmann.nii.gz';
- if not fileexists(lBAname) then
- lBAName := '';
+ if not fileexists(lTemplateName) then
+ lTemplateName := '';
TextForm.MemoT.Lines.Clear;
lPref := gBGImg.ResliceOnLoad;
gBGImg.ResliceOnLoad := false;
@@ -306,16 +303,12 @@ begin
lFilename := HdrForm.OpenHdrDlg.Files[lInc-1];
ImgForm.OpenAndDisplayImg(lFilename,false);
- if lBAName <> '' then
- ImgForm.OverlayOpenCore ( lBAname, 2);
- if lAALName <> '' then
- ImgForm.OverlayOpenCore ( lAALname, 3);
+ if lTemplateName <> '' then
+ ImgForm.OverlayOpenCore ( lTemplateName, 2);
FindClustersText(gMRIcroOverlay[kBGOverlayNum], lThresh,lMinClusterSz);
end;//lLoop
gBGImg.ResliceOnLoad := lPref;
TextForm.Show;
end;
-
-
-end.
+end.
\ No newline at end of file
diff --git a/templates/aal.nii.txt b/templates/aal.nii.txt
deleted file mode 100755
index 6e1dc4a..0000000
--- a/templates/aal.nii.txt
+++ /dev/null
@@ -1,117 +0,0 @@
-1 Precentral_L 2001
-2 Precentral_R 2002
-3 Frontal_Sup_L 2101
-4 Frontal_Sup_R 2102
-5 Frontal_Sup_Orb_L 2111
-6 Frontal_Sup_Orb_R 2112
-7 Frontal_Mid_L 2201
-8 Frontal_Mid_R 2202
-9 Frontal_Mid_Orb_L 2211
-10 Frontal_Mid_Orb_R 2212
-11 Frontal_Inf_Oper_L 2301
-12 Frontal_Inf_Oper_R 2302
-13 Frontal_Inf_Tri_L 2311
-14 Frontal_Inf_Tri_R 2312
-15 Frontal_Inf_Orb_L 2321
-16 Frontal_Inf_Orb_R 2322
-17 Rolandic_Oper_L 2331
-18 Rolandic_Oper_R 2332
-19 Supp_Motor_Area_L 2401
-20 Supp_Motor_Area_R 2402
-21 Olfactory_L 2501
-22 Olfactory_R 2502
-23 Frontal_Sup_Medial_L 2601
-24 Frontal_Sup_Medial_R 2602
-25 Frontal_Mid_Orb_L 2611
-26 Frontal_Mid_Orb_R 2612
-27 Rectus_L 2701
-28 Rectus_R 2702
-29 Insula_L 3001
-30 Insula_R 3002
-31 Cingulum_Ant_L 4001
-32 Cingulum_Ant_R 4002
-33 Cingulum_Mid_L 4011
-34 Cingulum_Mid_R 4012
-35 Cingulum_Post_L 4021
-36 Cingulum_Post_R 4022
-37 Hippocampus_L 4101
-38 Hippocampus_R 4102
-39 ParaHippocampal_L 4111
-40 ParaHippocampal_R 4112
-41 Amygdala_L 4201
-42 Amygdala_R 4202
-43 Calcarine_L 5001
-44 Calcarine_R 5002
-45 Cuneus_L 5011
-46 Cuneus_R 5012
-47 Lingual_L 5021
-48 Lingual_R 5022
-49 Occipital_Sup_L 5101
-50 Occipital_Sup_R 5102
-51 Occipital_Mid_L 5201
-52 Occipital_Mid_R 5202
-53 Occipital_Inf_L 5301
-54 Occipital_Inf_R 5302
-55 Fusiform_L 5401
-56 Fusiform_R 5402
-57 Postcentral_L 6001
-58 Postcentral_R 6002
-59 Parietal_Sup_L 6101
-60 Parietal_Sup_R 6102
-61 Parietal_Inf_L 6201
-62 Parietal_Inf_R 6202
-63 SupraMarginal_L 6211
-64 SupraMarginal_R 6212
-65 Angular_L 6221
-66 Angular_R 6222
-67 Precuneus_L 6301
-68 Precuneus_R 6302
-69 Paracentral_Lobule_L 6401
-70 Paracentral_Lobule_R 6402
-71 Caudate_L 7001
-72 Caudate_R 7002
-73 Putamen_L 7011
-74 Putamen_R 7012
-75 Pallidum_L 7021
-76 Pallidum_R 7022
-77 Thalamus_L 7101
-78 Thalamus_R 7102
-79 Heschl_L 8101
-80 Heschl_R 8102
-81 Temporal_Sup_L 8111
-82 Temporal_Sup_R 8112
-83 Temporal_Pole_Sup_L 8121
-84 Temporal_Pole_Sup_R 8122
-85 Temporal_Mid_L 8201
-86 Temporal_Mid_R 8202
-87 Temporal_Pole_Mid_L 8211
-88 Temporal_Pole_Mid_R 8212
-89 Temporal_Inf_L 8301
-90 Temporal_Inf_R 8302
-91 Cerebelum_Crus1_L 9001
-92 Cerebelum_Crus1_R 9002
-93 Cerebelum_Crus2_L 9011
-94 Cerebelum_Crus2_R 9012
-95 Cerebelum_3_L 9021
-96 Cerebelum_3_R 9022
-97 Cerebelum_4_5_L 9031
-98 Cerebelum_4_5_R 9032
-99 Cerebelum_6_L 9041
-100 Cerebelum_6_R 9042
-101 Cerebelum_7b_L 9051
-102 Cerebelum_7b_R 9052
-103 Cerebelum_8_L 9061
-104 Cerebelum_8_R 9062
-105 Cerebelum_9_L 9071
-106 Cerebelum_9_R 9072
-107 Cerebelum_10_L 9081
-108 Cerebelum_10_R 9082
-109 Vermis_1_2 9100
-110 Vermis_3 9110
-111 Vermis_4_5 9120
-112 Vermis_6 9130
-113 Vermis_7 9140
-114 Vermis_8 9150
-115 Vermis_9 9160
-116 Vermis_10 9170
-
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/mricron.git
More information about the debian-med-commit
mailing list