~ubuntu-branches/ubuntu/raring/mricron/raring

« back to all changes in this revision

Viewing changes to nifti_img_view.pas

  • Committer: Bazaar Package Importer
  • Author(s): Michael Hanke
  • Date: 2010-07-29 22:07:43 UTC
  • Revision ID: james.westby@ubuntu.com-20100729220743-q621ts2zj806gu0n
Tags: upstream-0.20100725.1~dfsg.1
ImportĀ upstreamĀ versionĀ 0.20100725.1~dfsg.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
unit nifti_img_view;
 
2
 
 
3
interface
 
4
{$IFDEF Unix}
 
5
  {$DEFINE noCOMPILEYOKE}
 
6
{$ENDIF}
 
7
uses
 
8
{$H+}
 
9
{$IFDEF Darwin}
 
10
CarbonOpenDoc,
 
11
 
 
12
{$ENDIF}
 
13
{$IFDEF Unix}
 
14
lclintf,LCLType,//gettickcount ,LMessages
 
15
{$ELSE}
 
16
Windows,ShellAPI,
 
17
{$ENDIF}
 
18
{$IFNDEF FPC} E_memmap,RXSpin,capmenu,Math,ToolWin,Messages,
 
19
{$ELSE}
 
20
LResources,
 
21
{$ENDIF}
 
22
 fx8,cpucount,
 
23
SysUtils, Classes, Graphics, Controls, Forms, Dialogs,Menus,ComCtrls, ExtCtrls,
 
24
 StdCtrls, GraphicsMathLibrary,ClipBrd,define_types, Spin,Buttons,
 
25
nifti_hdr,nifti_hdr_view,nifti_img,     voismooth,
 
26
IniFiles,ReadInt,registry,stat,Distr,bet,mni,prefs,CropEdges,userdir,graphx,
 
27
GraphType,IntfGraphics, landmarks;
 
28
 
 
29
{$IFDEF UNIX}
 
30
type
 
31
  PINtBuffer = ^TIntBuffer;
 
32
  TIntBuffer = Array[0..6] of single;
 
33
{$ENDIF}
 
34
type
 
35
 
 
36
  { TImgForm }
 
37
 
 
38
  TImgForm = class(TForm)
 
39
    AutoContrastBtn: TSpeedButton;
 
40
    ColorBarBtn: TSpeedButton;
 
41
    LayerDrop: TComboBox;
 
42
    LUTdrop: TComboBox;
 
43
    LutFromZeroBtn: TSpeedButton;
 
44
        MainMenu1: TMainMenu;
 
45
        File1: TMenuItem;
 
46
MaxWindowEdit: TFloatSpinEdit;
 
47
MenuItem1: TMenuItem;
 
48
HistoMenu: TMenuItem;
 
49
Header1: TMenuItem;
 
50
ApplyClusterThreshold1: TMenuItem;
 
51
LRFlip1: TMenuItem;
 
52
ExportasRGBAnalyzeimage1: TMenuItem;
 
53
BatchROImean1: TMenuItem;
 
54
Batchprobmaps1: TMenuItem;
 
55
Batchclusterprobmaps1Batchclusterprobmaps1Click: TMenuItem;
 
56
Axial1: TMenuItem;
 
57
Coronal1: TMenuItem;
 
58
Axial2: TMenuItem;
 
59
Coronal2: TMenuItem;
 
60
Landmarks1: TMenuItem;
 
61
Sagittal2: TMenuItem;
 
62
Sagittal1: TMenuItem;
 
63
Multiple1: TMenuItem;
 
64
PGImageAx: TImage;
 
65
PGImageSag: TImage;
 
66
Resliceimage1: TMenuItem;
 
67
AdjustimagessoVOIintensityiszero1: TMenuItem;
 
68
Brainmask1: TMenuItem;
 
69
GenerateSPM5maskslesions1: TMenuItem;
 
70
RescaleMenu: TMenuItem;
 
71
BrainExtraction1: TMenuItem;
 
72
CropEdges1: TMenuItem;
 
73
NIIVOI: TMenuItem;
 
74
MinWindowEdit: TFloatSpinEdit;
 
75
N4DTraces1: TMenuItem;
 
76
LayerPanel: TPanel;
 
77
n5: TMenuItem;
 
78
Preferences1: TMenuItem;
 
79
Display2: TMenuItem;
 
80
MNIMenu: TMenuItem;
 
81
        Open1: TMenuItem;
 
82
        CloseImages: TMenuItem;
 
83
        Exit1: TMenuItem;
 
84
        Edit1: TMenuItem;
 
85
        Copy1: TMenuItem;
 
86
        Help1: TMenuItem;
 
87
        About1: TMenuItem;
 
88
        ControlPanel: TPanel;
 
89
        Crosshair1: TMenuItem;
 
90
        Pen1: TMenuItem;
 
91
        Penautoclose1: TMenuItem;
 
92
        CircleSquare1: TMenuItem;
 
93
        YokeTimer: TTimer;
 
94
        XViewEdit: TSpinEdit;
 
95
        YViewEdit: TSpinEdit;
 
96
        ZViewEdit: TSpinEdit;
 
97
        MagPanel: TPanel;
 
98
        ProgressBar1: TProgressBar;
 
99
        StatusLabel: TLabel;
 
100
        LabelX: TLabel;
 
101
        LabelY: TLabel;
 
102
        LabelZ: TLabel;
 
103
        Templates1: TMenuItem;
 
104
        Recent1: TMenuItem;
 
105
        Controls1: TMenuItem;
 
106
        ZoomDrop: TComboBox;
 
107
        Panel1: TPanel;
 
108
        Saveaspicture1: TMenuItem;
 
109
        SaveDialog1: TSaveDialog;
 
110
        ColorDialog1: TColorDialog;
 
111
        RefreshImagesTimer: TTimer;
 
112
        MagnifyMenuItem: TMenuItem;
 
113
        OverlayMenu: TMenuItem;
 
114
        OverlayOpen: TMenuItem;
 
115
        LayerMenu: TMenuItem;
 
116
        Noneopen1: TMenuItem;
 
117
        OverlaySmoothMenu: TMenuItem;
 
118
        CloseOverlayImg: TMenuItem;
 
119
        BGTransPctMenu: TMenuItem;
 
120
        OverlayTransPctMenu: TMenuItem;
 
121
        BGtrans0: TMenuItem;
 
122
        BGtrans20: TMenuItem;
 
123
        BGtrans40: TMenuItem;
 
124
        BGtrans50: TMenuItem;
 
125
        BGtrans60: TMenuItem;
 
126
        BGtrans80: TMenuItem;
 
127
        BGtrans100: TMenuItem;
 
128
        N0opaque1: TMenuItem;
 
129
        N201: TMenuItem;
 
130
        N401: TMenuItem;
 
131
        N501: TMenuItem;
 
132
        N601: TMenuItem;
 
133
        N801: TMenuItem;
 
134
        N100transparent1: TMenuItem;
 
135
        Layerrange1: TMenuItem;
 
136
        Noneopen2: TMenuItem;
 
137
 
 
138
        BGAdditive: TMenuItem;
 
139
        OverlayAdditive: TMenuItem;
 
140
 
 
141
        ShowRender: TMenuItem;
 
142
        DrawMenu: TMenuItem;
 
143
        OpenVOI: TMenuItem;
 
144
        SaveVOI: TMenuItem;
 
145
        CloseVOI: TMenuItem;
 
146
        VOIColor: TMenuItem;
 
147
        TriplePanel: TScrollBox;
 
148
        PGImageCor: TImage;
 
149
 
 
150
 
 
151
 
 
152
 
 
153
 
 
154
 
 
155
        Undo1: TMenuItem;
 
156
        Paste1: TMenuItem;
 
157
        Applyintensityfiltertovolume1: TMenuItem;
 
158
        Quicksmooth1: TMenuItem;
 
159
        MaskimagewithVOI1: TMenuItem;
 
160
        VOImaskDelete: TMenuItem;
 
161
        VOImaskPreserve: TMenuItem;
 
162
        SaveasNIfTI1: TMenuItem;
 
163
        Circle1: TMenuItem;
 
164
        Overlaycomparisons1: TMenuItem;
 
165
        IntersectionmutualtoVOIandoverlays1: TMenuItem;
 
166
        UnionVOIoroverlays1: TMenuItem;
 
167
        MaskVOIbutnotoverlays1: TMenuItem;
 
168
        RescaleImagesTimer: TTimer;
 
169
        SmoothVOI1: TMenuItem;
 
170
        Circle2: TMenuItem;
 
171
        Beta1: TMenuItem;
 
172
        Chisquare1: TMenuItem;
 
173
        Convert1: TMenuItem;
 
174
        ROIVOI1: TMenuItem;
 
175
 
 
176
        Statistics1: TMenuItem;
 
177
        ShowMultislice: TMenuItem;
 
178
        DescriptiveMenuItem: TMenuItem;
 
179
 
 
180
 
 
181
        N1: TMenuItem;
 
182
        HideROIBtn: TSpeedButton;
 
183
        XBarBtn: TSpeedButton;
 
184
        ToolPanel: TPanel;
 
185
        PenBtn: TSpeedButton;
 
186
        ClosedPenBtn: TSpeedButton;
 
187
        FillBtn: TSpeedButton;
 
188
        EllipseBtn: TSpeedButton;
 
189
        Fill3DBtn: TSpeedButton;
 
190
        N2: TMenuItem;
 
191
        Display1: TMenuItem;
 
192
        N3: TMenuItem;
 
193
        FlipLRmenu: TMenuItem;
 
194
        N4: TMenuItem;
 
195
        Menu2DSmooth: TMenuItem;
 
196
        VOI2NII: TMenuItem;
 
197
        Nudge1: TMenuItem;
 
198
        Up1: TMenuItem;
 
199
        Left1: TMenuItem;
 
200
        LeftX1: TMenuItem;
 
201
        RightX1: TMenuItem;
 
202
        Posterior1: TMenuItem;
 
203
        Posterior2: TMenuItem;
 
204
        YokeMenu: TMenuItem;
 
205
procedure FormOpenFileMethod(const FileName : string);
 
206
procedure Landmarks1Click(Sender: TObject);
 
207
procedure SetIniMenus;
 
208
procedure Batchclusterprobmaps1Batchclusterprobmaps1ClickClick(Sender: TObject);
 
209
procedure Batchprobmaps1Click(Sender: TObject);
 
210
procedure BatchROImean1Click(Sender: TObject);
 
211
procedure BrainMask1Click(Sender: TObject);
 
212
procedure ControlPanelDragDrop(Sender, Source: TObject; X, Y: Integer);
 
213
procedure GenerateSPM5maskslesions1Click(Sender: TObject);
 
214
procedure LoadOverlay (lFilename: string);
 
215
procedure  LoadOverlayIncludingRGB (lFilename: string);
 
216
procedure ApplyClusterThreshold1Click(Sender: TObject);
 
217
procedure BETmenuClick(Sender: TObject);
 
218
procedure C(Sender: TObject);
 
219
procedure CropMenuClick(Sender: TObject);
 
220
procedure ExportasRGBAnalyzeimage1Click(Sender: TObject);
 
221
procedure FormDropFiles(Sender: TObject; const FileNames: array of String);
 
222
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
 
223
procedure FormKeyPress(Sender: TObject; var Key: char);
 
224
procedure Header1Click(Sender: TObject);
 
225
procedure HistoMenuClick(Sender: TObject);
 
226
procedure LayerDropChange(Sender: TObject);
 
227
procedure LUTdropChange(Sender: TObject);
 
228
procedure AdjustimagessoVOIintensityiszero1Click(Sender: TObject);
 
229
procedure MirrorNII1Click(Sender: TObject);
 
230
procedure MNIMenuClick(Sender: TObject);
 
231
procedure N4DTraces1Click(Sender: TObject);
 
232
procedure NIIVOIClick(Sender: TObject);
 
233
//procedure OptimizeViewClick(Sender: TObject);
 
234
procedure PGImageCorDblClick(Sender: TObject);
 
235
procedure Preferences1Click(Sender: TObject);
 
236
procedure RescaleMenuClick(Sender: TObject);
 
237
procedure Resliceimage1Click(Sender: TObject);
 
238
procedure SaveasNIfTI1Click(Sender: TObject);
 
239
procedure SaveDialog1Close(Sender: TObject);
 
240
procedure UpdateColorSchemes;
 
241
        procedure UpdateTemplates;
 
242
        procedure UpdateMRU;
 
243
        procedure UpdateStatusLabel;
 
244
        procedure Exit1Click(Sender: TObject);
 
245
        procedure About1Click(Sender: TObject);
 
246
        procedure DisplayHdrClick(Sender: TObject);
 
247
        procedure Open1Click(Sender: TObject);
 
248
        procedure ToolSelectClick(Sender: TObject);
 
249
        procedure Copy1Click(Sender: TObject);
 
250
        procedure FormCreate(Sender: TObject);
 
251
        function OpenAndDisplayImg(var lFilename: string; lAdd2MRU: boolean): boolean;
 
252
        procedure OpenTemplateMRU(Sender: TObject);
 
253
        procedure XViewEditChange(Sender: TObject);
 
254
        procedure ReadIniFile; //read init file values
 
255
        procedure WriteIniFile;
 
256
 {$IFNDEF FPC}
 
257
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
 
258
 {$ELSE}
 
259
        procedure FormClose(Sender: TObject);
 
260
 
 
261
 {$ENDIF}
 
262
procedure MagnifyTimerTimer(Sender: TObject);
 
263
        procedure MagnifyPanelResize(Sender: TObject);
 
264
        procedure PGImageMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
 
265
        procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
 
266
          MousePos: TPoint; var Handled: Boolean);
 
267
        procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
 
268
          MousePos: TPoint; var Handled: Boolean);
 
269
        procedure PGImageMouseDown(Sender: TObject; Button: TMouseButton;
 
270
          Shift: TShiftState; X, Y: Integer);
 
271
        procedure PGImageMouseUp(Sender: TObject; Button: TMouseButton;
 
272
          Shift: TShiftState; X, Y: Integer);
 
273
        procedure LUTdropLoad(var lLayer: integer);
 
274
        procedure LUTdropSelect(Sender: TObject);
 
275
procedure ZoomDropChange(Sender: TObject);
 
276
        procedure ZoomDropSelect(Sender: TObject);
 
277
        procedure ColorBarBtnMouseDown(Sender: TObject; Button: TMouseButton;
 
278
          Shift: TShiftState; X, Y: Integer);
 
279
        //procedure OptimizeViewMenuItemClick(Sender: TObject);
 
280
        procedure Saveaspicture1Click(Sender: TObject);
 
281
        procedure XBarBtnClick(Sender: TObject);
 
282
        procedure XBarBtnMouseUp(Sender: TObject; Button: TMouseButton;
 
283
          Shift: TShiftState; X, Y: Integer);
 
284
 procedure XBarBtnMouseDown(Sender: TObject; Button: TMouseButton;
 
285
          Shift: TShiftState; X, Y: Integer);
 
286
        procedure AutoContrastBtnClick(Sender: TObject);
 
287
        procedure RefreshImagesTimerTimer(Sender: TObject);
 
288
        procedure MinContrastWindowEditChange(Sender: TObject);
 
289
        procedure ImgPanelClick(Sender: TObject);
 
290
        procedure MagnifyMenuItemClick(Sender: TObject);
 
291
        procedure CloseImagesClick(Sender: TObject);
 
292
        procedure UpdateLayerMenu;
 
293
        procedure OverlayOpenCore (var lFilename: string; lOverlayNum: integer);
 
294
        procedure OverlayOpenClick(Sender: TObject);
 
295
        procedure CloseOverlayImgClick(Sender: TObject);
 
296
        procedure BGtrans100Click(Sender: TObject);
 
297
        procedure OverlayTransClick(Sender: TObject);
 
298
        procedure LayerDropSelect(Sender: TObject);
 
299
 procedure OverlaySmoothMenuClick(Sender: TObject);
 
300
        procedure MaxContrastWindowEditChange(Sender: TObject);
 
301
        procedure ShowRenderClick(Sender: TObject);
 
302
        procedure PenBtnClick(Sender: TObject);
 
303
        procedure OpenVOIClick(Sender: TObject);
 
304
        procedure OpenVOICore(var lFilename : string);
 
305
        procedure SaveVOIClick(Sender: TObject);
 
306
        procedure VOIColorClick(Sender: TObject);
 
307
        procedure CloseVOIClick(Sender: TObject);
 
308
        procedure SetDimension8(lInPGHt,lInPGWid:integer; lBuff: ByteP; lUndoOnly: boolean);
 
309
        procedure Undo1Click(Sender: TObject);
 
310
        procedure Paste1Click(Sender: TObject);
 
311
        procedure HideROIBtnMouseDown(Sender: TObject; Button: TMouseButton;
 
312
          Shift: TShiftState; X, Y: Integer);
 
313
        procedure HideROIBtnMouseUp(Sender: TObject; Button: TMouseButton;
 
314
          Shift: TShiftState; X, Y: Integer);
 
315
 procedure XBarColor;
 
316
 procedure Applyintensityfiltertovolume1Click(Sender: TObject);
 
317
        procedure Quicksmooth1Click(Sender: TObject);
 
318
        procedure VOImaskClick(Sender: TObject);
 
319
        procedure Sagittal1Click(Sender: TObject);
 
320
        procedure ROIcomparisonClick(Sender: TObject);
 
321
        procedure RescaleImagesTimerTimer(Sender: TObject);
 
322
        procedure Fill3DBtnClick(Sender: TObject);
 
323
        procedure SmoothVOI1Click(Sender: TObject);
 
324
        procedure CreateOverlap(Sender: TObject);
 
325
        procedure Chisquare1Click(Sender: TObject);
 
326
        procedure ROIVOI1Click(Sender: TObject);
 
327
        procedure LUTinvertBtnClick(Sender: TObject);
 
328
        procedure LutFromZeroBtnClick(Sender: TObject);
 
329
        procedure ShowMultisliceClick(Sender: TObject);
 
330
        procedure DescriptiveMenuItemClick(Sender: TObject);
 
331
        procedure FormResize(Sender: TObject);
 
332
        procedure FormShow(Sender: TObject);
 
333
        procedure FlipLRmenuClick(Sender: TObject);
 
334
        procedure Menu2DSmoothClick(Sender: TObject);
 
335
        procedure VALclick(Sender: TObject);
 
336
        procedure VOI2NIIClick(Sender: TObject);
 
337
        procedure TtoP1Click(Sender: TObject);
 
338
        procedure DesignVALClick(Sender: TObject);
 
339
        procedure Up1Click(Sender: TObject);
 
340
        procedure SetShareMem (lXmm,lYmm,lZmm: single);
 
341
        procedure CreateShareMem;
 
342
        procedure CloseShareMem;
 
343
        procedure YokeTimerTimer(Sender: TObject);
 
344
        procedure FormDestroy(Sender: TObject);
 
345
        procedure YokeMenuClick(Sender: TObject);
 
346
        procedure DefaultControlPanel;
 
347
        procedure ControlPanelDblClick(Sender: TObject);
 
348
        procedure ResizeControlPanel (lRows: integer);
 
349
        procedure SaveOrCopyImages(lCopy: boolean);
 
350
 private
 
351
        { Private declarations }
 
352
{$IFNDEF FPC}
 
353
    EMemMap : TEMemMap;
 
354
        procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
 
355
        procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
 
356
{$ENDIF}
 
357
{$IFDEF COMPILEYOKE}
 
358
    FShmId : Integer;
 
359
    FSharePtr : Pointer;
 
360
    gShareIntBuf: PIntBuffer;
 
361
{$ENDIF}
 
362
{$IFDEF FPC} function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;MousePos: TPoint): Boolean; override;{$ENDIF}
 
363
  public
 
364
        { Public declarations }
 
365
public
 
366
   //procedure WMSysCommand (var Msg: TWMSysCommand) ; message WM_SYSCOMMAND;
 
367
  published
 
368
           property OnMouseWheel;
 
369
  end;
 
370
 
 
371
const
 
372
 kYokeItems= 12;
 
373
 knMRU = 5;//max items in most recently used list
 
374
 knMaxOverlay = 20;
 
375
 kVOIOverlayNum = knMaxOverlay;
 
376
 kBGOverlayNum = 0;
 
377
 knAutoLUT = 7;
 
378
 kVOIFilter =   'Volume of interest (*.voi)|*.voi|MRIcro ROI (*.roi)|*.roi|'+kImgFilter;
 
379
var
 
380
 gYoke: boolean = false;
 
381
  ImgForm: TImgForm;
 
382
  gBGImg: TBGImg;
 
383
  gMRIcroOverlay: array [0..knMaxOverlay] of TMRIcroHdr;
 
384
  gColorSchemeDir,gTemplateDir: String;
 
385
  gMRUstr: array [0..knMRU] of String; //most recently used files
 
386
  gMouseDownX,gMouseDownY: integer;
 
387
  gSelectOrigin: TPoint;
 
388
  gSelectRect: TRect;
 
389
  gOrigBGTransPct : integer= 50;
 
390
  //gMaxCPUThreads : integer = 8;
 
391
  gnCPUThreads : integer = 1;
 
392
  gUndoImg,gDrawImg: Tfx8;
 
393
 
 
394
Type
 
395
         SingleArr = Array[1..kYokeItems] Of Single;
 
396
         SingleArrPtr = ^SingleArr;
 
397
 
 
398
implementation
 
399
 
 
400
uses statclustertable,batch,imgutil, reslice_fsl,render,ROIfilt,autoroi, MultiSlice, Text,  histoform,
 
401
  about,clustering,ReadFloat;
 
402
 
 
403
{$IFNDEF FPC}
 
404
{$R *.DFM}
 
405
{$ENDIF}
 
406
procedure TImgForm.XBarColor;
 
407
begin
 
408
                ColorDialog1.Color := gBGImg.XBarClr;
 
409
                if not ColorDialog1.Execute then exit;
 
410
                gBGImg.XBarClr := ColorDialog1.Color;
 
411
                RefreshImagesTimer.Enabled := true;
 
412
                exit;
 
413
end;
 
414
 
 
415
 
 
416
procedure DecViewEdit(var lEdit: TSpinEdit);
 
417
begin
 
418
    if lEdit.Value > 1 then
 
419
       lEdit.value := lEdit.value -1
 
420
        else
 
421
        lEdit.Value := lEdit.MaxValue;
 
422
    {$IFDEF FPC} ImgForm.XViewEditChange(nil); {$ENDIF}
 
423
end; //DecViewEdit
 
424
 
 
425
procedure IncViewEdit(var lEdit: TSpinEdit);
 
426
begin
 
427
    if lEdit.Value < lEdit.MaxValue then
 
428
       lEdit.value := lEdit.value +1
 
429
    else
 
430
                lEdit.Value := 1;
 
431
    {$IFDEF FPC} ImgForm.XViewEditChange(nil); {$ENDIF}
 
432
end; //IncViewEdit
 
433
 
 
434
 
 
435
function TImgForm.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
 
436
  MousePos: TPoint): Boolean;
 
437
begin
 
438
     Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos);
 
439
     //ImgForm.Caption := inttostr(random(888));
 
440
     //... actions after a possible OnMouseWheel[Down|Up]
 
441
     //ImgForm.Caption := inttostr(WheelDelta)+'  '+inttostr(random(888))+'  '+inttostr(MousePos.X);
 
442
     if WheelDelta < 0 then begin
 
443
        Case SelectedImageNum of
 
444
             3: DecViewEdit(YViewEdit);
 
445
             2: DecViewEdit(XViewEdit);
 
446
             else DecViewEdit(ZViewEdit);
 
447
        end;
 
448
     end else begin
 
449
         Case SelectedImageNum of
 
450
              3: IncViewEdit(YViewEdit);
 
451
              2: IncViewEdit(XViewEdit);
 
452
              else IncViewEdit(ZViewEdit);
 
453
         end;
 
454
     end;
 
455
end;
 
456
 
 
457
 
 
458
 
 
459
procedure TImgForm.CloseShareMem;
 
460
var
 
461
   lInstances: single;
 
462
begin
 
463
{$IFNDEF FPC}
 
464
  EMemMap.Free;
 
465
{$ENDIF}
 
466
{$IFDEF COMPILEYOKE}
 
467
  //shared memory release START
 
468
  gShareIntBuf^[0] := gShareIntBuf^[0] -1;
 
469
  lInstances := gShareIntBuf^[0];
 
470
  if Assigned (FSharePtr) then
 
471
    shmdt (FSharePtr);
 
472
  //if FOwnShm then      zssss
 
473
  if lInstances = 0 then begin
 
474
    //last running instance - close shared memory
 
475
    if shmctl (FShmId, IPC_RMID, nil) = -1 then
 
476
      raise Exception.Create (strerror (errno));
 
477
  end;
 
478
  //shared memory release END
 
479
{$ENDIF}
 
480
end;
 
481
 
 
482
procedure TImgForm.SetShareMem (lXmm,lYmm,lZmm: single);
 
483
begin
 
484
{$IFNDEF FPC}
 
485
  if not gYoke then exit;
 
486
        EMemMap.EnterCriticalSection;
 
487
        Try
 
488
          SingleArrPtr(EMemMap.MemMap)^[1]:=(lXmm);
 
489
          SingleArrPtr(EMemMap.MemMap)^[2]:=(lYmm);
 
490
          SingleArrPtr(EMemMap.MemMap)^[3]:=(lZmm);
 
491
        Finally
 
492
          EMemMap.LeaveCriticalSection;
 
493
        end;
 
494
{$ENDIF}
 
495
{$IFDEF COMPILEYOKE}
 
496
  begin
 
497
    gShareIntBuf^[1] := (lXmm);
 
498
    gShareIntBuf^[2] := (lYmm);
 
499
    gShareIntBuf^[3] := (lZmm);
 
500
end;
 
501
{$ENDIF}
 
502
end;
 
503
 
 
504
procedure TImgForm.CreateShareMem;
 
505
{$IFDEF FPC}
 
506
{$IFDEF COMPILEYOKE}
 
507
begin
 
508
  //shared memory acquire START
 
509
  // create key
 
510
  Key := getUID;
 
511
  Key := ftok (PChar(GetModuleName(0)),Key  {1}); //use UserID so each user gets separate pool of shared memory
 
512
  // try to open existing shared memory
 
513
  FShmId := shmget (Key, 0, 0);
 
514
  if FShmId = -1 then
 
515
  begin
 
516
    // doesn't exist, create it
 
517
    FShmId := shmget (Key, kShareSegmentSize,
 
518
      IPC_CREAT or IPC_EXCL or AccessMode);
 
519
    if FShmId = -1 then
 
520
      raise Exception.Create (strerror (errno));
 
521
    lFOwnShm := true;
 
522
  end
 
523
  else
 
524
    lFOwnShm := false;
 
525
  // attach to shared memory
 
526
  FSharePtr := shmat (FShmId, nil, 0);
 
527
  if Integer(FSharePtr) = -1 then
 
528
  begin
 
529
    FSharePtr := nil;
 
530
    raise Exception.Create (strerror (errno));
 
531
  end;
 
532
  gShareIntBuf := FSharePtr;
 
533
  if lFOwnShm then
 
534
       gShareIntBuf^[0] := 0;
 
535
  gShareIntBuf^[0] := gShareIntBuf^[0]+1;
 
536
  SetShareMem (gXProj,gYProj,gZProj);
 
537
 
 
538
end;
 
539
{$ELSE}
 
540
begin
 
541
    //CompileYoke not set
 
542
end;
 
543
{$ENDIF}
 
544
{$ELSE}//not FPC - must be Delphi
 
545
var
 
546
 IArr    : SingleArrPtr;
 
547
 I: integer;
 
548
begin
 
549
  EMemMap:=TEMemMap.Create(Self);
 
550
  EMemMap.CreateMutex('MRICROMUTEX2');
 
551
  If NOT EMemMap.MapExisting('MRICROMAP2',SizeOf(SingleArr)) then begin
 
552
        New(IArr);
 
553
        For I:=1 To kYokeItems do
 
554
          IArr^[I]:=0;
 
555
        Try
 
556
          If NOT EMemMap.CreateMemMap('MRICROMAP2',SizeOf(SingleArr),IArr^) then
 
557
                EMemMap.RaiseMappingException;
 
558
        Finally
 
559
          Dispose(IArr);
 
560
        end;
 
561
         SetShareMem (0,0,0)
 
562
  end;
 
563
end;
 
564
{$ENDIF} //Delphi
 
565
 
 
566
procedure TImgForm.YokeTimerTimer(Sender: TObject);
 
567
var
 
568
lXmm,lYmm,lZmm: single;
 
569
lX,lY,lZ: integer;
 
570
begin
 
571
caption := inttostr(888);
 
572
        if not gYoke then begin
 
573
                YokeTimer.Enabled := false;
 
574
                exit;
 
575
        end;
 
576
        if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems=0 then
 
577
                exit;
 
578
{$IFDEF FPC}
 
579
    {$IFDEF COMPILEYOKE}
 
580
      lXmm:=gShareIntBuf^[1];
 
581
      lYmm:=gShareIntBuf^[2];
 
582
      lZmm:=gShareIntBuf^[3];
 
583
    {$ELSE}
 
584
    YokeTimer.Enabled := false;
 
585
    exit;
 
586
    {$ENDIF}
 
587
 
 
588
{$ELSE}
 
589
        EMemMap.EnterCriticalSection;
 
590
        Try
 
591
          lXmm:=SingleArrPtr(EMemMap.MemMap)^[1];
 
592
          lYmm:=SingleArrPtr(EMemMap.MemMap)^[2];
 
593
          lZmm:=SingleArrPtr(EMemMap.MemMap)^[3];
 
594
        Finally
 
595
          EMemMap.LeaveCriticalSection;
 
596
        end;
 
597
{$ENDIF}
 
598
        MMToImgCoord(lX,lY,lZ,lXmm,lYmm,lZmm);
 
599
        if lX <> XViewEdit.value then XViewEdit.value := lX;
 
600
        if lY <> YViewEdit.value then YViewEdit.value := lY;
 
601
        if lZ <> ZViewEdit.value then ZViewEdit.value := lZ;
 
602
    YokeTimer.Enabled := false;
 
603
end;
 
604
 
 
605
{$IFNDEF FPC}
 
606
procedure TImgForm.WMSysCommand;
 
607
begin
 
608
   if (Msg.CmdType = SC_MINIMIZE)  then
 
609
                Application.Minimize
 
610
        else
 
611
                DefaultHandler(Msg) ;
 
612
   if (Msg.CmdType = SC_MAXIMIZE) then RefreshImagesTimer.enabled := true;
 
613
end;
 
614
{$ENDIF}
 
615
 
 
616
function SelectedImagePanel: TScrollBox;
 
617
begin
 
618
        case SelectedImageNum of
 
619
                3: result := ImgForm.TriplePanel;
 
620
                2: result := ImgForm.TriplePanel;
 
621
                else result := ImgForm.TriplePanel;
 
622
        end;
 
623
end;
 
624
 
 
625
function DrawToolSelected: boolean;
 
626
begin
 
627
        if ( ImgForm.PenBtn.Down) or ( ImgForm.ClosedPenBtn.Down) or (ImgForm.FillBtn.Down) or (ImgForm.EllipseBtn.Down) then
 
628
                result := true
 
629
        else
 
630
                result := false;
 
631
end;
 
632
 
 
633
procedure TImgForm.WriteIniFile;
 
634
var
 
635
  lInc: integer;
 
636
  lIni: string;
 
637
  lIniFile: TIniFile;
 
638
begin
 
639
  lIni:= IniName;
 
640
  //  if not (gBGIMg.SaveDefaultIni) then
 
641
  //    showmessage(lIni+ inttostr(DiskFreeEx(lIni)));
 
642
  if (DiskFreeEx(lIni) < 1) or (not gBGIMg.SaveDefaultIni) then
 
643
        exit;
 
644
 
 
645
  //lIniFile := TIniFile.Create(changefileext(paramstr(0),'.ini'));
 
646
  lIniFile := TIniFile.Create(lIni);//DefaultsDir('')+ParseFileName(extractfilename(paramstr(0)))+'.ini');
 
647
  //recent files
 
648
  lIniFile.WriteString('MRU', 'file0', gMRIcroOverlay[kBGOverlayNum].HdrFilename);
 
649
  for lInc := 1 to knMRU do
 
650
          lIniFile.WriteString('MRU', 'file'+inttostr(lInc), gMRUstr[lINc]);
 
651
  //STR
 
652
  lIniFile.WriteString('STR', 'FSLDIR',gBGImg.FSLDIR);
 
653
  lIniFile.WriteString('STR', 'FSLOUTPUTTYPE',gBGImg.FSLOUTPUTTYPE);
 
654
  //Booleans
 
655
  lIniFile.WriteString('BOOL', 'Reslice',Bool2Char(gBGImg.ResliceOnLoad));
 
656
  lIniFile.WriteString('BOOL', 'ResliceOrtho',Bool2Char(gBGImg.OrthoReslice));
 
657
  lIniFile.WriteString('BOOL', 'ShowDraw',Bool2Char(ToolPanel.Visible));
 
658
  lIniFile.WriteString('BOOL', 'ThinPen',Bool2Char(gBGImg.ThinPen));
 
659
  lIniFile.WriteString('BOOL', 'Smooth2D',Bool2Char(Menu2DSmooth.checked));
 
660
  lIniFile.WriteString('BOOL', 'XBar',Bool2Char(XBarBtn.Down));
 
661
  lIniFile.WriteString('BOOL', 'OverlaySmooth',Bool2Char(OverlaySmoothMenu.Checked));
 
662
  lIniFile.WriteString('BOOL', 'LRmirror',Bool2Char(gBGImg.Mirror));
 
663
  lIniFile.WriteString('BOOL', 'Yoke',Bool2Char(gYoke));
 
664
  lIniFile.WriteString('BOOL', 'SingleRow',Bool2Char(gBGImg.SingleRow));
 
665
  lIniFile.WriteString('BOOL', 'FlipAx',Bool2Char(gBGImg.FlipAx));
 
666
  lIniFile.WriteString('BOOL', 'FlipSag',Bool2Char(gBGImg.FlipSag));
 
667
  YokeTimer.Enabled := gYoke;
 
668
  //Integers
 
669
  //lIniFile.WriteString('INT', 'ResizeBeforeRescale',IntToStr(gBGImg.ResizeBeforeRescale));
 
670
  lIniFile.WriteString('INT', 'FontSize',IntToStr(gBGImg.FontSize));
 
671
  lIniFile.WriteString('INT', 'MaxDim',IntToStr(gBGImg.MaxDim));
 
672
  lIniFile.WriteString('INT', 'LicenseID',IntToStr(gBGImg.LicenseID));
 
673
  lIniFile.WriteString('INT', 'Zoom',IntToStr(ZoomDrop.ItemIndex));
 
674
  lIniFile.WriteString('INT', 'LUT',IntToStr(gMRIcroOverlay[kBGOverlayNum].LUTindex));
 
675
  lIniFile.WriteString('INT', 'XBarGap',IntToStr(gBGImg.XBarGap));
 
676
  lIniFile.WriteString('INT', 'XBarThick',IntToStr(gBGImg.XBarThick));
 
677
  lIniFile.WriteString('INT', 'XBarClr',IntToStr(gBGIMg.XBarClr));
 
678
  lIniFile.WriteString('INT', 'VOIClr',IntToStr(gBGIMg.VOIClr));
 
679
  if (gBGImg.BGTransPct < 0) or (gBGImg.BGTransPct > 90) then
 
680
    gBGImg.BGTransPct := 20; //additive or transparent values can confuse users
 
681
  if (gBGImg.OverlayTransPct < 0) or (gBGImg.OverlayTransPct > 90) then
 
682
    gBGImg.OverlayTransPct := 20; //additive or transparent values can confuse users
 
683
  lIniFile.WriteString('INT', 'BGTransPct',IntToStr(gBGImg.BGTransPct));
 
684
  lIniFile.WriteString('INT', 'OverlayTransPct',IntToStr(gBGImg.OverlayTransPct));
 
685
  lIniFile.WriteString('INT','MaxThreads',IntToStr(gnCPUThreads));
 
686
  lIniFile.WriteString('INT', 'LesionSmooth',IntToStr(gBGImg.LesionSmooth));
 
687
//  {$ELSE}
 
688
//  lIniFile.WriteString('INT', 'MaxThreads',IntToStr(gMaxCPUThreads));
 
689
//  {$ENDIF}
 
690
    lIniFile.WriteString('INT', 'SigDigits',IntToStr(gBGImg.SigDig));
 
691
    lIniFile.WriteString('INT', 'ImageSeparation',IntToStr(gBGImg.ImageSeparation));
 
692
 
 
693
 
 
694
  lIniFile.WriteString('INT', 'SPMDefaultsStatsFmriT',IntToStr(gBGImg.SPMDefaultsStatsFmriT));
 
695
  lIniFile.WriteString('INT', 'SPMDefaultsStatsFmriT0',IntToStr(gBGImg.SPMDefaultsStatsFmriT0));
 
696
 
 
697
  lIniFile.Free;
 
698
end;
 
699
 
 
700
function registerfiletype(inft,inkey,desc,icon:string): boolean;
 
701
var myreg : treginifile;
 
702
        ct : integer;
 
703
        ft,key: string;
 
704
begin
 
705
         result := true;
 
706
         ft := inft;
 
707
         key := inkey;
 
708
         ct := pos('.',ft);
 
709
         while ct > 0 do begin
 
710
                   delete(ft,ct,1);
 
711
                   ct := pos('.',ft);
 
712
         end;
 
713
         if (ft = '') or (Application.ExeName = '') then exit; //not a valid file-ext or ass. app
 
714
         ft := '.'+ft;
 
715
         myreg := treginifile.create('');
 
716
         try
 
717
                myreg.rootkey := hkey_classes_root; // where all file-types are described
 
718
                if key = '' then key := copy(ft,2,maxint)+'_auto_file'; // if no key-name is given, create one
 
719
                myreg.writestring(ft,'',key); // set a pointer to the description-key
 
720
                myreg.writestring(key,'',desc); // write the description
 
721
                myreg.writestring(key+'\DefaultIcon','',icon); // write the def-icon if given
 
722
                myreg.writestring(key+'\shell\open\command','',Application.ExeName+' %1'); //association
 
723
         except
 
724
                   result := false;
 
725
                   showmessage('Only administrators can change file associations. You are currently logged in as a restricted user.');
 
726
         end;
 
727
         myreg.free;
 
728
end;
 
729
 
 
730
procedure TImgForm.SetIniMenus;
 
731
begin
 
732
  XBarBtn.Down := gBGImg.XBarVisible;
 
733
  YokeMenu.Checked := gYoke;
 
734
  Menu2DSmooth.checked := gBGImg.StretchQuality = sqHigh;
 
735
  Menu2DSmoothClick(nil);//set quality
 
736
end;
 
737
 
 
738
procedure TImgForm.ReadIniFile;
 
739
var
 
740
  lInc,lFilenum: integer;
 
741
  lFilename: string;
 
742
  lIniFile: TIniFile;
 
743
begin
 
744
  //lFilename := changefileext(paramstr(0),'.ini');
 
745
 
 
746
  lFilename := ininame;//DefaultsDir('')+ParseFileName(extractfilename(paramstr(0)))+'.ini';
 
747
  if not FileexistsEx(lFilename) then begin
 
748
    DrawMenu.Visible := ToolPanel.visible;
 
749
    exit;
 
750
  end;
 
751
 
 
752
  lIniFile := TIniFile.Create(lFilename);
 
753
  gMRUstr[0] := lIniFile.ReadString('MRU', 'file0', '');//file0 - last file viewed
 
754
  lFileNum := 0;
 
755
  for lInc := 1 to knMRU do begin
 
756
          lFilename := lIniFile.ReadString('MRU', 'file'+inttostr(lInc), '');
 
757
          if (length(lFilename) > 0) and (fileexistsex(lFilename)) then begin
 
758
                 Inc(lFileNum);
 
759
                 gMRUstr[lFileNum] := lFilename;
 
760
          end;
 
761
  end;
 
762
  gBGImg.FSLOUTPUTTYPE := lIniFile.ReadString('STR', 'FSLOUTPUTTYPE', '');
 
763
  gBGImg.FSLDIR := lIniFile.ReadString('STR', 'FSLDIR', '');
 
764
  gBGImg.ResliceOnLoad := IniBool(lIniFile,'Reslice',gBGImg.ResliceOnLoad);
 
765
  gBGImg.OrthoReslice := IniBool(lIniFile,'ResliceOrtho',gBGImg.OrthoReslice);
 
766
  gBGImg.ThinPen := IniBool(lIniFile, 'ThinPen',True);
 
767
  ToolPanel.Visible := IniBool(lIniFile, 'ShowDraw',False);
 
768
  DrawMenu.Visible := ToolPanel.visible;
 
769
  if IniBool(lIniFile,'Smooth2D',Menu2DSmooth.checked) then
 
770
     gBGImg.StretchQuality := sqHigh
 
771
  else
 
772
      gBGImg.StretchQuality := sqLow;
 
773
  //Menu2DSmooth.checked := IniBool(lIniFile,'Smooth2D',Menu2DSmooth.checked);
 
774
  Menu2DSmoothClick(nil);//set quality
 
775
  gBGImg.XBarVisible := IniBool(lIniFile,'XBar',XBarBtn.Down);
 
776
  gBGImg.OverlaySmooth := IniBool(lIniFile,'OverlaySmooth',gBGImg.OverlaySmooth);
 
777
  OverlaySmoothMenu.Checked := gBGImg.OverlaySmooth;
 
778
  gBGImg.Mirror := IniBool(lIniFile,'LRmirror',gBGImg.Mirror);
 
779
  FlipLRmenu.Checked := gBGImg.Mirror;
 
780
  gYoke := IniBool(lIniFile,'Yoke',gYoke);
 
781
    gBGImg.SingleRow := IniBool(lIniFile,'SingleRow',gBGImg.SingleRow);
 
782
   gBGImg.FlipAx := IniBool(lIniFile,'FlipAx',gBGImg.FlipAx);
 
783
  gBGImg.FlipSag := IniBool(lIniFile,'FlipSag',gBGImg.FlipSag);
 
784
  gBGImg.MaxDim := IniInt(lIniFile,'MaxDim',gBGImg.MaxDim);
 
785
  gBGImg.LicenseID := IniInt(lIniFile,'LicenseID',gBGImg.LicenseID);
 
786
{$IFNDEF FPC}
 
787
  ZoomDrop.SetItemIndex(IniInt(lIniFile,'Zoom',ZoomDrop.ItemIndex));
 
788
  LUTDrop.SetItemIndex(IniInt(lIniFile,'LUT',LUTDrop.ItemIndex));
 
789
{$ELSE}
 
790
  ZoomDrop.ItemIndex := (IniInt(lIniFile,'Zoom',ZoomDrop.ItemIndex));
 
791
  LUTDrop.ItemIndex:= (IniInt(lIniFile,'LUT',LUTDrop.ItemIndex));
 
792
{$ENDIF}
 
793
  gBGImg.XBarGap := IniInt(lIniFile,'XBarGap',gBGImg.XBarGap);
 
794
  gBGImg.XBarThick := IniInt(lIniFile,'XBarThick',gBGImg.XBarThick);
 
795
  gBGImg.XBarClr := IniInt(lIniFile,'XBarClr',gBGImg.XBarClr);
 
796
  gBGImg.VOIClr := IniInt(lIniFile,'VOIClr',gBGImg.VOIClr);
 
797
  gBGImg.BGTransPct := IniInt(lIniFile,'BGTransPct',gBGImg.BGTransPct);
 
798
  gBGImg.OverlayTransPct := IniInt(lIniFile,'OverlayTransPct',gBGImg.OverlayTransPct);
 
799
  gnCPUThreads := IniInt(lIniFile,'MaxThreads',gnCPUThreads);
 
800
    gBGImg.SigDig := IniInt(lIniFile,'SigDigits',gBGImg.SigDig);
 
801
    gBGImg.ImageSeparation := IniInt(lIniFile,'ImageSeparation',gBGImg.ImageSeparation);
 
802
     gBGImg.FontSize := IniInt(lIniFile,'FontSize',gBGImg.FontSize);
 
803
 
 
804
  gBGImg.SPMDefaultsStatsFmriT := IniInt(lIniFile,'SPMDefaultsStatsFmriT',gBGImg.SPMDefaultsStatsFmriT);
 
805
  gBGImg.SPMDefaultsStatsFmriT0 := IniInt(lIniFile,'SPMDefaultsStatsFmriT0',gBGImg.SPMDefaultsStatsFmriT0);
 
806
  gBGImg.LesionSmooth := IniInt(lIniFile,'LesionSmooth',gBGImg.LesionSmooth);
 
807
 
 
808
  SetSubmenuWithTag(BGTransPctMenu, gBGImg.BGTransPct);
 
809
  SetSubmenuWithTag(OverlayTransPctMenu, gBGImg.OverlayTransPct);
 
810
  lIniFile.Free;
 
811
 
 
812
end; //ReadIniFile
 
813
 
 
814
procedure TImgForm.UpdateColorSchemes;
 
815
var
 
816
        lSearchRec: TSearchRec;
 
817
begin
 
818
  LUTdrop.Items.Clear;
 
819
  LUTdrop.Items.Add('Grayscale');
 
820
  LUTdrop.Items.Add('Red');
 
821
  LUTdrop.Items.Add('Blue');
 
822
  LUTdrop.Items.Add('Green');
 
823
  LUTdrop.Items.Add('Violet [r+b]');
 
824
  LUTdrop.Items.Add('Yellow [r+g]');
 
825
  LUTdrop.Items.Add('Cyan [g+b]');
 
826
  if FindFirst(gColorSchemeDir+pathdelim+'*.lut', faAnyFile, lSearchRec) = 0 then
 
827
         repeat
 
828
                  LUTdrop.Items.Add(ParseFileName(ExtractFileName(lSearchRec.Name)));
 
829
         until (FindNext(lSearchRec) <> 0);
 
830
  FindClose(lSearchRec);
 
831
  //LUTDrop.DropDownCount := 66;//LUTDrop.Items.Count;
 
832
end;//UpdateColorSchemes
 
833
 
 
834
 
 
835
procedure TImgForm.BETmenuClick(Sender: TObject);
 
836
begin
 
837
  BetForm.show;
 
838
end;
 
839
 
 
840
procedure TImgForm.ApplyClusterThreshold1Click(Sender: TObject);
 
841
var
 
842
        lNumberofFiles,lC,lClusterSz: integer;
 
843
    lThresh: double;
 
844
        lFilename: string;
 
845
begin
 
846
        CloseImagesClick(nil);
 
847
        if not OpenDialogExecute(kImgFilter,'Select NIfTI format images to convert',true) then exit;
 
848
        lNumberofFiles:= HdrForm.OpenHdrDlg.Files.Count;
 
849
    lClusterSz := ReadIntForm.GetInt('Minimum cluster size [in voxels]: ', 1,32,9999);
 
850
    lThresh := ReadFloatForm.GetFloat('Include voxels with an intensity above: ', 0,2,9999);
 
851
        ProgressBar1.Min := 0;
 
852
        ProgressBar1.Max :=lNumberofFiles;
 
853
        ProgressBar1.Position := 0;
 
854
        for lC:= 1 to lNumberofFiles do begin
 
855
                lFilename := HdrForm.OpenHdrDlg.Files[lC-1];
 
856
                ImgForm.OpenAndDisplayImg(lFilename,True);
 
857
                //lFilename := changefileextX(lFilename,'I'+inttostr(round(lThresh))+'C'+inttostr(lClusterSz)+'.nii.gz');
 
858
                lFilename := changefileprefix(lFilename,'I'+inttostr(round(lThresh))+'C'+inttostr(lClusterSz));
 
859
                if ClusterFilterScrnImg (gMRIcroOverlay[kBGOverlayNum],lClusterSz,lThresh ) then
 
860
                if ImgVaries(gMRIcroOverlay[kBGOverlayNum]) then
 
861
                          SaveAsVOIorNIFTIcore (lFilename, gMRIcroOverlay[kBGOverlayNum].ImgBuffer,gMRIcroOverlay[kBGOverlayNum].ImgBufferItems,gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP,1,gMRIcroOverlay[kBGOverlayNum].NiftiHdr)
 
862
                else
 
863
                    showmessage('No clusters survive filter '+ HdrForm.OpenHdrDlg.Files[lC-1]);
 
864
                ProgressBar1.Position := lC;
 
865
        end;
 
866
        if fileexistsEX(lFilename) then
 
867
           ImgForm.OpenAndDisplayImg(lFilename,True);
 
868
        ProgressBar1.Position := 0;
 
869
end;
 
870
 
 
871
procedure TImgForm.C(Sender: TObject);
 
872
begin
 
873
 
 
874
end;
 
875
 
 
876
procedure TImgForm.CropMenuClick(Sender: TObject);
 
877
begin
 
878
  CropEdgeForm.Show;
 
879
end;
 
880
 
 
881
procedure TImgForm.ExportasRGBAnalyzeimage1Click(Sender: TObject);
 
882
var
 
883
   lFlip: boolean;
 
884
begin
 
885
     lFlip := gBGImg.Mirror;
 
886
     gBGImg.Mirror := true;
 
887
     CreateAnaRGB;
 
888
     gBGImg.Mirror := lFlip;
 
889
end;
 
890
 
 
891
procedure TImgForm.FormDropFiles(Sender: TObject;
 
892
  const FileNames: array of String);
 
893
var
 
894
   lFilename: string;
 
895
begin
 
896
  if length(FileNames) < 1 then
 
897
     exit;
 
898
  lFilename := Filenames[0];
 
899
  OpenAndDisplayImg(lFilename,true);
 
900
end;
 
901
 
 
902
procedure TImgForm.FormKeyDown(Sender: TObject; var Key: Word;
 
903
  Shift: TShiftState);
 
904
begin
 
905
  //ImgForm.caption := inttostr(Key);
 
906
  if (XViewEdit.focused) or (YViewEdit.focused) or (ZViewEdit.focused) or (MinWindowEdit.focused) or (MaxWindowEdit.focused) then
 
907
     exit;
 
908
  Case Key of
 
909
    36: DecViewEdit(YViewEdit);
 
910
    35: IncViewEdit(YViewEdit);
 
911
    37: DecViewEdit(XViewEdit);
 
912
    38: IncViewEdit(ZViewEdit);
 
913
    39: IncViewEdit(XViewEdit);
 
914
    40: DecViewEdit(ZViewEdit);
 
915
  
 
916
  end; //case Key
 
917
      (* if WheelDelta < 0 then begin
 
918
        Case SelectedImageNum of
 
919
             3: DecViewEdit(YViewEdit);
 
920
             2: DecViewEdit(XViewEdit);
 
921
             else DecViewEdit(ZViewEdit);
 
922
        end;
 
923
     end else begin
 
924
         Case SelectedImageNum of
 
925
              3: IncViewEdit(YViewEdit);
 
926
              2: IncViewEdit(XViewEdit);
 
927
              else IncViewEdit(ZViewEdit);
 
928
         end;
 
929
     end;*)
 
930
end;
 
931
 
 
932
procedure TImgForm.FormKeyPress(Sender: TObject; var Key: char);
 
933
begin
 
934
//imgform.caption := 'zzz';
 
935
end;
 
936
 
 
937
 
 
938
 
 
939
procedure TImgForm.Header1Click(Sender: TObject);
 
940
begin
 
941
  DisplayHdrClick(nil);
 
942
end;
 
943
 
 
944
 
 
945
function ActiveLayer:integer;
 
946
begin
 
947
     result := ImgForm.LayerDrop.ItemIndex;
 
948
     if result < 0 then
 
949
        result := 0;
 
950
end;
 
951
 
 
952
{$DEFINE noTEST}
 
953
 
 
954
{$IFDEF TEST}
 
955
procedure DrawBMP2( lx, ly: integer; var lBuff: RGBQuadp; var lImage: TImage);
 
956
//uses  GraphType, IntfGraphics
 
957
var
 
958
  IntfImage: TLazIntfImage;
 
959
  ScanLineImage: TLazIntfImage;
 
960
  ImgFormatDescription: TRawImageDescription;
 
961
  lBitmap: TBitmap;
 
962
begin
 
963
  lBitmap:=TBitmap.Create;
 
964
  ScanLineImage:=TLazIntfImage.Create(0,0);
 
965
  ImgFormatDescription.Init_BPP32_B8G8R8_BIO_TTB(lx,ly);
 
966
  ScanLineImage.DataDescription:=ImgFormatDescription;
 
967
  // call the pf24bit specific drawing function
 
968
  Move(lBuff^[1],PByte(ScanLineImage.GetDataLineStart(0))[1],lx*ly*sizeof(TRGBquad) );
 
969
  lBitmap.Width:=ScanLineImage.Width;
 
970
  lBitmap.Height:=ScanLineImage.Height;
 
971
  IntfImage:=lBitmap.CreateIntfImage;
 
972
  // convert the content from the very specific to the current format
 
973
  IntfImage.CopyPixels(ScanLineImage);
 
974
  lBitmap.LoadFromIntfImage(IntfImage);
 
975
  ScanLineImage.Free;
 
976
  IntfImage.Free;
 
977
  lImage.Picture.Bitmap := lBitmap;
 
978
  lBitmap.Free;
 
979
end;
 
980
 
 
981
procedure FZ;
 
982
var
 
983
   l2Time,lTime: DWord;
 
984
   y,x,lx, ly, lpos: integer;
 
985
   lBuff: RGBQuadp ;
 
986
begin
 
987
  lx := 320;
 
988
  ly := 320;
 
989
  getmem(lBuff,(lx*ly)*sizeof( TRGBquad));
 
990
  lpos := 0;
 
991
  for y := 1 to ly do begin
 
992
      for x := 1 to lx do begin
 
993
          inc(lpos);
 
994
          lBuff^[lpos].rgbblue := (y mod 255);
 
995
          lBuff^[lpos].rgbgreen :=(y mod 255);
 
996
          lBuff^[lpos].rgbred := (x mod 255) ;
 
997
          lBuff^[lpos].rgbreserved := 0;
 
998
      end;
 
999
  end;
 
1000
  l2Time := GetTickCount;
 
1001
  for y := 1 to 100 do
 
1002
      DrawBMP2( lx, ly, lBuff,HistogramForm.HistoImage{lImage});
 
1003
  l2Time := GetTickCount - l2Time;
 
1004
  lTime := GetTickCount;
 
1005
  for y := 1 to 100 do
 
1006
      DrawBMP( lx, ly, lBuff,HistogramForm.HistoImage{lImage});
 
1007
  lTime := GetTickCount - lTime;
 
1008
  HistogramForm.Caption := inttostr(lTime)+'  '+inttostr(l2Time);
 
1009
  freemem(lBuff);
 
1010
end;
 
1011
{$ENDIF}
 
1012
 
 
1013
procedure TImgForm.HistoMenuClick(Sender: TObject);
 
1014
VAR
 
1015
   lLayer: integer;
 
1016
begin
 
1017
     {$IFDEF TEST}
 
1018
     FZ;
 
1019
     {$ELSE}
 
1020
                lLayer := ActiveLayer;
 
1021
                DrawHistogram(gMRIcroOverlay[lLayer],HistogramForm.HistoImage{lImage});
 
1022
                HistogramForm.Caption := 'Histogram: '+extractfilename(gMRIcroOverlay[lLayer].HdrFileName);
 
1023
         {$ENDIF}
 
1024
   HistogramForm.show;
 
1025
  //HistogramForm.BringToFront;
 
1026
end;
 
1027
 
 
1028
 
 
1029
 
 
1030
procedure TImgForm.MNIMenuClick(Sender: TObject);
 
1031
begin
 
1032
  MNIForm.show;
 
1033
  //MNIForm.BringToFront;
 
1034
 
 
1035
end;
 
1036
 
 
1037
procedure TImgForm.N4DTraces1Click(Sender: TObject);
 
1038
begin
 
1039
    Graph4DForm.show;
 
1040
    //Graph4DForm.BringToFront;
 
1041
end;
 
1042
 
 
1043
procedure TImgForm.NIIVOIClick(Sender: TObject);
 
1044
 var
 
1045
        lNumberofFiles,lC: integer;
 
1046
        lFilename: string;
 
1047
begin
 
1048
        CloseImagesClick(nil);
 
1049
        if not OpenDialogExecute(kImgFilter {10/2007},'Select NIfTI format images to convert',true) then exit;
 
1050
        lNumberofFiles:= HdrForm.OpenHdrDlg.Files.Count;
 
1051
        ProgressBar1.Min := 0;
 
1052
        ProgressBar1.Max :=lNumberofFiles;
 
1053
        ProgressBar1.Position := 0;
 
1054
        for lC:= 1 to lNumberofFiles do begin
 
1055
                lFilename := HdrForm.OpenHdrDlg.Files[lC-1];
 
1056
                ImgForm.OpenAndDisplayImg(lFilename,True);
 
1057
                lFilename := changefileextx(lFilename,'.voi'); ////Xversion 10/2007 - removes .nii.gz not just gz
 
1058
                //SaveAsVOIorNIFTIcore (lFilename, lByteP, lVoxels, 1, gMRIcroOverlay[kBGOverlayNum].NiftiHdr);
 
1059
                SaveAsVOIorNIFTIcore (lFilename, gMRIcroOverlay[kBGOverlayNum].ScrnBuffer,gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems, 1,1,gMRIcroOverlay[kBGOverlayNum].NiftiHdr);
 
1060
                CloseVOIClick(nil);
 
1061
                ProgressBar1.Position := lC;
 
1062
        end;
 
1063
        ProgressBar1.Position := 0;
 
1064
 
 
1065
end;
 
1066
 
 
1067
 
 
1068
procedure TImgForm.PGImageCorDblClick(Sender: TObject);
 
1069
begin
 
1070
       if Graph4DForm.visible then
 
1071
        Graph4DForm.RefreshBtn.click;
 
1072
end;
 
1073
 
 
1074
procedure TImgForm.Preferences1Click(Sender: TObject);
 
1075
begin
 
1076
     PrefForm.ShowModal;
 
1077
end;
 
1078
 
 
1079
function RescaleImg( lRescaleIntercept,lRescaleSlope: double): boolean;
 
1080
var
 
1081
        //lRow,lNumberofFiles,lX,lY,lZ: integer;
 
1082
        //lFilename: string;
 
1083
        lHdr:TMRIcroHdr;
 
1084
        lImgSamples,lInc,lBPP: integer;
 
1085
        l32Buf,lo32Buf : SingleP;
 
1086
        l16Buf : SmallIntP;
 
1087
begin
 
1088
     //note ignores input slope/intercept scaling values
 
1089
     result := false;
 
1090
        if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 1 then begin
 
1091
                showmessage('Please load a background image for rescaling.');
 
1092
                exit;
 
1093
        end;
 
1094
        if ((gBGImg.ScrnDim[1] * gBGImg.ScrnDim[2] * gBGImg.ScrnDim[3]) <> gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems) then begin
 
1095
            showmessage('Unable to rescale.');
 
1096
            exit;
 
1097
        end;
 
1098
        lBPP := gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP;//check if BitsPerPixel is supported
 
1099
        if  (lBPP <> 4) and (lBPP <> 2) and (lBPP <> 1) then begin
 
1100
            showmessage('RescaleImg Error: Unsupported BPP: '+inttostr(lBPP));
 
1101
            exit;
 
1102
        end;
 
1103
        lImgSamples := gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems;
 
1104
        MakeStatHdr (gMRIcroOverlay[kBGOverlayNum],lHdr,0{min}, 0{max},0{p1},0{p2},0{p3},kNIFTI_INTENT_NONE,floattostr(lRescaleSlope) );
 
1105
        GetMem(lHdr.ImgBufferUnaligned ,(lImgSamples*4)+16);
 
1106
        //svn lHdr.ImgBuffer := ByteP($fffffff0 and (integer(lHdr.ImgBufferUnaligned)+15));
 
1107
        lHdr.ImgBuffer := align(lHdr.ImgBufferUnaligned, 16);
 
1108
        lo32Buf := SingleP( lHdr.ImgBuffer );
 
1109
        if lBPP = 4 then begin
 
1110
           l32Buf := SingleP( gMRIcroOverlay[kBGOverlayNum].ImgBuffer );
 
1111
           for lInc := 1 to lImgSamples do
 
1112
               lo32Buf^[lInc] :=  (l32Buf^[lInc]+lRescaleIntercept) * lRescaleSlope;
 
1113
        end else if lBPP = 2 then begin //lBPP=4 else
 
1114
           l16Buf := SmallIntP( gMRIcroOverlay[kBGOverlayNum].ImgBuffer );
 
1115
           for lInc := 1 to lImgSamples do
 
1116
               lo32Buf^[lInc] :=  (l16Buf^[lInc]+lRescaleIntercept) * lRescaleSlope;
 
1117
        end else if lBPP = 1 then begin //lBPP=2 else
 
1118
           for lInc := 1 to lImgSamples do
 
1119
               lo32Buf^[lInc] :=  (gMRIcroOverlay[kBGOverlayNum].ImgBuffer^[lInc]+lRescaleIntercept) * lRescaleSlope;
 
1120
        end;//lBPP = 1
 
1121
        SaveAsVOIorNIFTI(bytep(lo32Buf),lImgSamples,4,1,false,lHdr.NiftiHdr,'rscl'+extractfilename(gMRIcroOverlay[kBGOverlayNum].HdrFilename));
 
1122
        //SaveAsVOIorNIFTI(gMRIcroOverlay[lLayer].ImgBuffer,gMRIcroOverlay[lLayer].ImgBufferItems,gMRIcroOverlay[lLayer].ImgBufferBPP,1,false,gMRIcroOverlay[kBGOverlayNum].NiftiHdr,gMRIcroOverlay[lLayer].HdrFilename);
 
1123
        FreeMem(lHdr.ImgBufferUnaligned);
 
1124
        //lFilename := 'c:\striped2.hdr';
 
1125
        //SaveAsVOIorNIFTIcore (lFilename, gMRIcroOverlay[kBGOverlayNum].ScrnBuffer,gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems, 1,1,gMRIcroOverlay[kBGOverlayNum].NiftiHdr);
 
1126
     result := true;
 
1127
end;
 
1128
 
 
1129
 
 
1130
procedure TImgForm.RescaleMenuClick(Sender: TObject);
 
1131
var ldTE,lScale,lTE1,lTE2: double;
 
1132
    //lStr: string;
 
1133
begin
 
1134
        if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 1 then begin
 
1135
                showmessage('Please load a background image for rescaling.');
 
1136
                exit;
 
1137
        end;
 
1138
        if gBGImg.Resliced then begin
 
1139
           if not HdrForm.OpenAndDisplayHdr(gMRIcroOverlay[kBGOverlayNum].HdrFileName,gMRIcroOverlay[kBGOverlayNum]) then exit;
 
1140
           if not OpenImg(gBGImg,gMRIcroOverlay[0],true,false,false,false,false) then exit;
 
1141
        end;
 
1142
        if (gMRIcroOverlay[kBGOverlayNum].GlMinUnscaledS < 0) or (gMRIcroOverlay[kBGOverlayNum].GlMaxUnscaledS > 4096) then begin
 
1143
            showmessage('Error: you need to load a Siemens format Phase map with raw values in the range 0..4096');
 
1144
            exit;
 
1145
        end;
 
1146
        lTE1 := ReadFloatForm.GetFloat('Please enter the first TE (ms) used for phasemap. ', 0,5.19,9999);
 
1147
        lTE2 := ReadFloatForm.GetFloat('Please enter the second TE (ms) used for phasemap. ', 0,7.65,9999);
 
1148
        
 
1149
        (*lStr := floattostr(5.19); //use floattostr for local decimal separator
 
1150
        if not InputQuery('TEs used to create phasemap','Please enter the first TE in ms', lStr) then
 
1151
           exit;
 
1152
        try
 
1153
           lTE1 := strtofloat(lStr);
 
1154
        except
 
1155
             showmessage('Unable to convert the string '+lStr+' to a number');
 
1156
             exit;
 
1157
        end;
 
1158
        lStr := floattostr(7.65);
 
1159
        if not InputQuery('TEs used to create phasemap','Please enter the second TE in ms', lStr) then
 
1160
           exit;
 
1161
        try
 
1162
           lTE2 := strtofloat(lStr);
 
1163
        except
 
1164
             showmessage('Unable to convert the string '+lStr+' to a number');
 
1165
             exit;
 
1166
        end;*)
 
1167
        if lTE1 = lTE2 then begin
 
1168
           showmessage('In order to compute Rad/S the two TEs must be different.');
 
1169
           exit;
 
1170
        end;
 
1171
        //fx(lTE1,lTE2);
 
1172
        //exit;
 
1173
//the fieldmap is simply a phase
 
1174
//difference image and is not scaled to any particular units.  In Siemens
 
1175
//phase images the data goes from 0 to 4095 with 0 being -pi radians, 2048
 
1176
//is 0 radians, and 4095 is just short of +pi radians.
 
1177
  //So, to get units of radians/s you would need to know the difference in
 
1178
  //echo times (dTE) in units of s (not ms).  You would then take
 
1179
  //(x-2048)(2pi/4096)/dTE
 
1180
//Note ignore original intercept and scale values
 
1181
  //ldTE := abs(5.19 - 7.65)/1000; // div 1000 to scale ms to sec
 
1182
  ldTE := abs(lTE1 - lTE2)/1000; // div 1000 to scale ms to sec
 
1183
  lScale := (2*pi/4096)/ldTE;
 
1184
  //showmessage(floattostr(lScale));
 
1185
  rescaleImg(-2048,lScale);
 
1186
end;
 
1187
 
 
1188
procedure TImgForm.Resliceimage1Click(Sender: TObject);
 
1189
begin
 
1190
   ResliceFSL;
 
1191
end;
 
1192
 
 
1193
procedure TImgForm.SaveasNIfTI1Click(Sender: TObject);
 
1194
  var
 
1195
        lLayer: integer;
 
1196
begin
 
1197
        lLayer := ActiveLayer;
 
1198
        if gMRIcroOverlay[lLayer].ImgBufferItems=0 then begin
 
1199
                Showmessage('You must load an image [File/Open] before you can save the image.');
 
1200
                exit;
 
1201
        end;
 
1202
        if (not IsNifTiMagic(gMRIcroOverlay[lLayer].niftiHdr)) then
 
1203
                Showmessage('Warning: image will be saved with NIfTI spatial transform - ensure this image matches the orientation of the template images.');
 
1204
        SaveAsVOIorNIFTI(gMRIcroOverlay[lLayer].ImgBuffer,gMRIcroOverlay[lLayer].ImgBufferItems,gMRIcroOverlay[lLayer].ImgBufferBPP,1,false,gMRIcroOverlay[kBGOverlayNum].NiftiHdr,gMRIcroOverlay[lLayer].HdrFilename);
 
1205
end;
 
1206
 
 
1207
 
 
1208
procedure ApplySaveDlgFilter (lSaveDlg: TSaveDialog);
 
1209
var
 
1210
   lLen,lPos,lPipes,lPipesReq: integer;
 
1211
   lExt: string;
 
1212
begin
 
1213
     lPipesReq := (lSaveDlg.FilterIndex * 2)-1;
 
1214
     if lPipesReq < 1 then exit;
 
1215
     lLen := length(lSaveDlg.Filter);
 
1216
     lPos := 1;
 
1217
     lPipes := 0;
 
1218
     //Median(DeltaF, 1, N_inc) / LN2
 
1219
     while (lPos < lLen) and (lPipes < lPipesReq) do begin
 
1220
           if lSaveDlg.Filter[lPos] = '|' then
 
1221
              inc(lPipes);
 
1222
           inc(lPos);
 
1223
     end;
 
1224
     if (lPos >= lLen) or (lPipes < lPipesReq) then
 
1225
        exit;
 
1226
     lExt := '';
 
1227
     while (lPos <= lLen) and (lSaveDlg.Filter[lPos] <> '|') do begin
 
1228
           if lSaveDlg.Filter[lPos] <> '*' then
 
1229
              lExt := lExt + lSaveDlg.Filter[lPos];
 
1230
           inc(lPos);
 
1231
     end;
 
1232
     if lExt <> '' then
 
1233
        lSaveDlg.Filename := ChangeFileExt(lSaveDlg.Filename,lExt);
 
1234
end;
 
1235
 
 
1236
procedure TImgForm.SaveDialog1Close(Sender: TObject);
 
1237
begin
 
1238
  ApplySaveDlgFilter(SaveDialog1);
 
1239
end;
 
1240
 
 
1241
procedure Add2MRU (var lNewFilename: string); //add new file to most-recent list
 
1242
var
 
1243
  lStr: string;
 
1244
  lPos,lN : integer;
 
1245
begin
 
1246
  //first, increase position of all old MRUs
 
1247
  lN := 0; //Number of MRU files
 
1248
  for lPos := 1 to (knMRU) do begin//first, eliminate duplicates
 
1249
          lStr := gMRUstr[lPos];
 
1250
          if (lStr <> '') and (lStr <> lNewFileName) then begin
 
1251
                 inc(lN);
 
1252
                 gMRUstr[lN] := lStr;
 
1253
          end; //keep in MRU list
 
1254
  end; //for each MRU
 
1255
  //next, increment positions
 
1256
  if lN >= knMRU then
 
1257
         lN := knMRU - 1;
 
1258
  for lPos := lN downto 1 do
 
1259
          gMRUstr[lPos+1] := gMRUstr[lPos];
 
1260
  if (lN+2) < (knMRU) then //+1 as we have added a file
 
1261
         for lPos := (lN+2) to knMRU do
 
1262
           gMRUstr[lPos] := '';
 
1263
  gMRUstr[1] := lNewFilename;
 
1264
  ImgForm.UpdateMRU;
 
1265
  ImgForm.SaveDialog1.FileName := lNewFilename;
 
1266
end;//Add2MRU
 
1267
 
 
1268
procedure TImgForm.UpdateMRU;//most-recently-used menu
 
1269
var
 
1270
  NewItem: TMenuItem;
 
1271
        lPos,lN : integer;
 
1272
begin
 
1273
  While Recent1.Count > 0 do Recent1.Items[0].Free;
 
1274
  lN := 0;
 
1275
  for lPos := 1 to knMRU do begin//for each MRU
 
1276
      if gMRUstr[lPos] <> '' then begin
 
1277
                   inc(lN);
 
1278
                   NewItem := TMenuItem.Create(Self);
 
1279
                   NewItem.Caption :=ExtractFileName(gMRUstr[lPos]);//(ParseFileName(ExtractFileName(lFName)));
 
1280
                   NewItem.Tag := lN;
 
1281
                   {$IFDEF FPC}
 
1282
                    NewItem.onclick :=  @OpenTemplateMRU; //Lazarus
 
1283
                    {$ELSE}
 
1284
                     NewItem.onclick :=  OpenTemplateMRU;
 
1285
                     {$ENDIF}
 
1286
                   NewItem.ShortCut := ShortCut(Word('1')+ord(lN-1), [ssCtrl]);
 
1287
                   Recent1.Add(NewItem);
 
1288
      end;//if mru exists
 
1289
  end;//for each MRU
 
1290
end;  //UpdateMRU
 
1291
 
 
1292
procedure TImgForm.UpdateTemplates;
 
1293
var
 
1294
  NewItem: TMenuItem;
 
1295
        lN : integer;
 
1296
        lFName : String;
 
1297
        lSearchRec: TSearchRec;
 
1298
begin
 
1299
  While Templates1.Count > 0 do Templates1.Items[0].Free;
 
1300
  lN := 0;
 
1301
  if FindFirst(gTemplateDir+pathdelim+'*.*', faAnyFile, lSearchRec) = 0 then begin
 
1302
         repeat
 
1303
                  lFName := lSearchRec.Name;
 
1304
                  if IsNIfTIHdrExt (lFName) then begin
 
1305
                   inc(lN);
 
1306
                   NewItem := TMenuItem.Create(Self);
 
1307
                   NewItem.Caption :=ExtractFileName(lFName);//(ParseFileName(ExtractFileName(lFName)));
 
1308
                   NewItem.Tag := 0;
 
1309
                   {$IFDEF FPC}
 
1310
                    NewItem.onclick :=  @OpenTemplateMRU; //Lazarus
 
1311
                    {$ELSE}
 
1312
                     NewItem.onclick :=  OpenTemplateMRU;
 
1313
                     {$ENDIF}
 
1314
                   if (lN+knMRU) <= 9 then
 
1315
                      NewItem.ShortCut := ShortCut(Word('1')+knMRU+ord(lN-1), [ssCtrl]);
 
1316
                   Templates1.Add(NewItem);
 
1317
                  end;
 
1318
         until (FindNext(lSearchRec) <> 0)
 
1319
  end;
 
1320
  FindClose(lSearchRec);
 
1321
end;//UpdateTemplates
 
1322
 
 
1323
procedure TImgForm.OpenTemplateMRU(Sender: TObject);//open template or MRU
 
1324
//Templates have tag set to 0, Most-Recently-Used items have tag set to position in gMRUstr
 
1325
var
 
1326
        lFilename: string;
 
1327
begin
 
1328
         if sender = nil then begin
 
1329
                //autolaunch with last image, or last template image in list
 
1330
 
 
1331
                 lFilename :=  gMRUstr[0];
 
1332
                if (lFilename = '') or (not FileExistsEX(lFilename)) then begin
 
1333
                  if Templates1.Count > 0 then
 
1334
                        Templates1.Items[Templates1.Count-1].click;
 
1335
                  exit;
 
1336
                end;
 
1337
                  OpenAndDisplayImg(lFilename,true); //open but do not add templates to MRU
 
1338
         end else if (Sender as TMenuItem).tag = 0 then begin
 
1339
                lFilename := gTemplateDir+pathdelim+(Sender as TMenuItem).caption ;//+ '.hdr';
 
1340
                  OpenAndDisplayImg(lFilename,false); //open but do not add templates to MRU
 
1341
         end else if (Sender as TMenuItem).tag <= knMRU then begin
 
1342
                 lFilename := gMRUstr[(Sender as TMenuItem).tag];
 
1343
                 OpenAndDisplayImg(lFilename,true);
 
1344
         end else
 
1345
                 Showmessage('OpenTemplateMRU error.');
 
1346
end;
 
1347
 
 
1348
function TImgForm.OpenAndDisplayImg(var lFilename: string; lAdd2MRU: boolean): boolean;
 
1349
var
 
1350
   lVal: integer;
 
1351
begin
 
1352
         Result := false;
 
1353
         if not HdrForm.OpenAndDisplayHdr(lFilename,gMRIcroOverlay[kBGOverlayNum]) then exit;
 
1354
 
 
1355
 
 
1356
         //if (ssShift in KeyDataToShiftState(vk_Shift)) then begin
 
1357
         //    if not OpenImg(gBGImg,gMRIcroOverlay[0],true,false,false,not gBGImg.ResliceOnLoad,false) then exit
 
1358
         //end else
 
1359
             if not OpenImg(gBGImg,gMRIcroOverlay[0],true,false,false,gBGImg.ResliceOnLoad,false) then exit;
 
1360
 
 
1361
     XViewEdit.MaxValue := gBGImg.ScrnDim[1];//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[1];
 
1362
         YViewEdit.MaxValue := gBGImg.ScrnDim[2];//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[2];
 
1363
         ZViewEdit.MaxValue :=gBGImg.ScrnDim[3];// gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[3];
 
1364
         XViewEdit.Value := round(gBGImg.ScrnOri[1]);//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[1] div 2;
 
1365
         YViewEdit.Value := round(gBGImg.ScrnOri[2]);//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[2]div 2;
 
1366
         lVal :=    round(gBGImg.ScrnOri[3]);
 
1367
         if lVal < 1 then
 
1368
            lVal := 1;
 
1369
         ZViewEdit.Value := lVal;//gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.dim[3] div 2;
 
1370
         ImgForm.Caption := extractfilename(paramstr(0))+' - '+lFilename;
 
1371
         StatusLabel.caption := 'opened: '+lFilename;
 
1372
         Result := true;
 
1373
  //LayerDrop.ItemIndex := 0;
 
1374
  //LayerDropSelect(nil);
 
1375
  if lAdd2MRU then Add2MRU(lFilename);
 
1376
   if gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.datatype = kDT_RGB then begin   //RGB
 
1377
       //we have loaded the first [red] plane - now load green and blue...
 
1378
       OverlayOpenCore(lFilename,1);
 
1379
       OverlayOpenCore(lFilename,2);
 
1380
       //must use additive blending
 
1381
       //gBGImg.BGTransPct := -1;
 
1382
       //gBGImg.OverlayTransPct := -1;
 
1383
       OverlayAdditive.Click;
 
1384
       BGAdditive.Click;
 
1385
   end;
 
1386
  {$IFDEF FPC}
 
1387
  XViewEditChange(nil);
 
1388
  {$ENDIF}
 
1389
  //showmessage(lFilename+' 666  '+ChangeFileext(lFilename,'.anat'));
 
1390
   AnatForm.OpenAnat( ChangeFileextx(lFilename,'.anat'));
 
1391
end; //OpenAndDisplayImg
 
1392
 
 
1393
{$IFNDEF FPC}
 
1394
procedure TImgForm.WMDropFiles(var Msg: TWMDropFiles);  //implement drag and drop
 
1395
var
 
1396
  CFileName: array[0..MAX_PATH] of Char;
 
1397
  lFilename: string;
 
1398
begin
 
1399
  try
 
1400
    if DragQueryFile(Msg.Drop, 0, CFileName, MAX_PATH) > 0 then
 
1401
    begin
 
1402
         lFilename := CFilename;
 
1403
         OpenAndDisplayImg(lFilename,true);
 
1404
         Msg.Result := 0;
 
1405
    end;
 
1406
  finally
 
1407
        DragFinish(Msg.Drop);
 
1408
  end;
 
1409
end;
 
1410
{$ENDIF}
 
1411
 
 
1412
procedure TImgForm.Exit1Click(Sender: TObject);
 
1413
begin
 
1414
   ImgForm.Close;
 
1415
end;
 
1416
 
 
1417
function XToStr(lR: extended; lDec: integer): string;
 
1418
begin
 
1419
         result := FloatToStrF(lR, ffFixed,7,lDec);
 
1420
end;
 
1421
 
 
1422
 
 
1423
 
 
1424
procedure TImgForm.DisplayHdrClick(Sender: TObject);
 
1425
var
 
1426
        lLayer:integer;
 
1427
begin
 
1428
        lLayer := ActiveLayer;
 
1429
        HdrForm.SaveHdrDlg.Filename := gMRIcroOverlay[lLayer].HdrFilename;
 
1430
        HdrForm.WriteHdrForm (gMRIcroOverlay[lLayer]);
 
1431
        HdrForm.ShowModal;
 
1432
 //HdrForm.BringToFront;
 
1433
end;
 
1434
 
 
1435
procedure TImgForm.Open1Click(Sender: TObject);
 
1436
var
 
1437
        lFilename: string;
 
1438
begin
 
1439
     CloseImagesClick(nil);
 
1440
     if not OpenDialogExecute(kImgFilter,'Select background image',false) then exit;
 
1441
     lFilename := HdrForm.OpenHdrDlg.Filename;
 
1442
     OpenAndDisplayImg(lFilename,True);
 
1443
end;
 
1444
 
 
1445
procedure TImgForm.ToolSelectClick(Sender: TObject);
 
1446
begin
 
1447
        if (not ToolPanel.Visible) and ((Sender as TMenuItem).Tag > 0) then exit; //tools disabled
 
1448
         case (Sender as TMenuItem).Tag of
 
1449
                  0: begin
 
1450
                          XBarBtn.Down := not XBarBtn.Down;
 
1451
                      {$IFDEF Darwin} XBarbtnClick(nil); exit;{$ENDIF}
 
1452
                  end;
 
1453
                  2: PenBtn.Down := true;
 
1454
                  3: ClosedPenBtn.Down := true;
 
1455
                  4: FillBtn.Down := true;
 
1456
                  5: EllipseBtn.Down := true;
 
1457
                  6: begin
 
1458
                          PenBtn.Down := false;
 
1459
                          ClosedPenBtn.Down := false;
 
1460
                          FillBtn.Down := false;
 
1461
                          EllipseBtn.Down := false;
 
1462
                  end;
 
1463
         end; //case
 
1464
         RefreshImagesTimer.Enabled := true;
 
1465
end;
 
1466
 
 
1467
function SelectedImage: TImage;
 
1468
begin
 
1469
 case SelectedImageNum of
 
1470
          kSagView0: result := ImgForm.PGImageSag;
 
1471
          kCoroView0: result := ImgForm.PGImageCor;
 
1472
          else
 
1473
                  result := ImgForm.PGImageAx;
 
1474
 end;
 
1475
end;
 
1476
 
 
1477
procedure TImgForm.SetDimension8(lInPGHt,lInPGWid:integer; lBuff: ByteP; lUndoOnly: boolean);
 
1478
begin
 
1479
    DefineBuffFX8(gDrawImg, lInPGWid,lInPGHt,lBuff);
 
1480
    DefineBuffFX8(gUndoImg, lInPGWid,lInPGHt,lBuff);
 
1481
 
 
1482
end;
 
1483
 
 
1484
procedure WriteAxialVOI (lUndoOnly: boolean);
 
1485
var lX,lY,lSliceOffset,lSliceSz,lSlicePos: integer;
 
1486
        lInBuff: ByteP;
 
1487
begin
 
1488
        lX := gBGImg.ScrnDim[1];
 
1489
        lY := gBGImg.ScrnDim[2];
 
1490
        lSliceSz := lX*lY;
 
1491
        if lSliceSz < 1 then exit;
 
1492
        lSliceOffset := (ImgForm.ZViewEdit.Value-1)*lX*lY;
 
1493
        gBGImg.VOIUndoSlice := ImgForm.ZViewEdit.Value;
 
1494
        getmem(lInBuff,lSliceSz);
 
1495
        for lSlicePos := 1 to lSliceSz do
 
1496
                lInBuff^[lSlicePos]  :=  gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lSliceOffset+lSlicePos];
 
1497
        ImgForm.SetDimension8(lY,lX, lInBuff,lUndoOnly);
 
1498
        freemem(lInBuff);
 
1499
end;
 
1500
 
 
1501
procedure  WriteCorVOI (lUndoOnly: boolean);
 
1502
var lX,lY,lZ,lYOffset,lZOffset,lXYSliceSz,lPixel,lZPos,lXPos: integer;
 
1503
        lInBuff: ByteP;
 
1504
begin
 
1505
        lX := gBGImg.ScrnDim[1];
 
1506
        lY := gBGImg.ScrnDim[2];
 
1507
        lZ := gBGImg.ScrnDim[3];
 
1508
        lYOffset := (lX) * (round(ImgForm.YViewEdit.Value)-1);
 
1509
        gBGImg.VOIUndoSlice := ImgForm.YViewEdit.Value;
 
1510
        lXYSliceSz := (lX*lY);
 
1511
        getmem(lInBuff,lZ*lX);
 
1512
        lPixel := 0;
 
1513
        for lZPos := 1 to lZ do begin
 
1514
          lZOffset := (lZPos-1) * lXYSliceSz;
 
1515
          for lXPos := 1 to lX do begin
 
1516
                  inc(lPixel);
 
1517
                lInBuff^[lPixel] :=
 
1518
                        gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lZOffset+lYOffset+lXPos];
 
1519
          end; //for each Y
 
1520
        end; //for each Z
 
1521
        ImgForm.SetDimension8(lZ,lX, lInBuff,lUndoOnly);
 
1522
        freemem(lInBuff);
 
1523
end;
 
1524
 
 
1525
procedure WriteSagVOI (lUndoOnly: boolean);
 
1526
var lX,lY,lZ,lXOffset,lYOffset,lZOffset,lXYSliceSz,lPixel,lZPos,lYPos: integer;
 
1527
        lInBuff: ByteP;
 
1528
begin
 
1529
        lX := gBGImg.ScrnDim[1];
 
1530
        lY := gBGImg.ScrnDim[2];
 
1531
        lZ := gBGImg.ScrnDim[3];
 
1532
        lXYSliceSz := lX*lY;
 
1533
        lXOffset := round(ImgForm.XViewEdit.Value);
 
1534
  //dec(lXOffset);//999+8
 
1535
        gBGImg.VOIUndoSlice := ImgForm.XViewEdit.Value;
 
1536
        getmem(lInBuff,lZ*lY);
 
1537
        lPixel := 0;
 
1538
        for lZPos := 1 to lZ do begin
 
1539
          lZOffset := (lZPos-1) * lXYSliceSz;
 
1540
          lYOffset := 0;
 
1541
          for lYPos := 1 to lY do begin
 
1542
                  inc(lPixel);
 
1543
                  lInBuff^[lPixel] := gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lZOffset+lYOffset+lXOffset];
 
1544
                  lYOffset := lYOffset+ lX;
 
1545
          end; //for each Y
 
1546
        end; //for each Z
 
1547
        ImgForm.SetDimension8(lZ,lY, lInBuff, lUndoOnly);
 
1548
        freemem(lInBuff);
 
1549
end;
 
1550
 
 
1551
procedure WriteUndoVOI(lPanel: integer;lUndoOnly: boolean);
 
1552
begin
 
1553
        EnsureVOIOPen;
 
1554
        case lPanel of
 
1555
                3: WriteCorVOI(lUndoOnly);
 
1556
                2: WriteSagVOI(lUndoOnly);
 
1557
                else WriteAxialVOI(lUndoOnly);
 
1558
        end;
 
1559
        gBGImg.VOIchanged := true;
 
1560
        if gBGImg.VOIUndoOrient = 4 then
 
1561
                FreeUndoVol; //release 3D undo buffer when creating 2D buffer
 
1562
        gBGImg.VOIUndoOrient := lPanel;
 
1563
end;
 
1564
 
 
1565
procedure TImgForm.FormOpenFileMethod(const FileName : string);
 
1566
var
 
1567
   lFilename: string;
 
1568
begin
 
1569
    lFilename := Filename;
 
1570
    OpenAndDisplayImg(lFilename,true);
 
1571
end;
 
1572
 
 
1573
procedure TImgForm.Landmarks1Click(Sender: TObject);
 
1574
begin
 
1575
     //Graph4DForm.show;
 
1576
 AnatForm.show;
 
1577
end;
 
1578
 
 
1579
 
 
1580
procedure TImgForm.FormCreate(Sender: TObject);
 
1581
var
 
1582
   lInc: longint;
 
1583
begin
 
1584
 
 
1585
 Application.ShowButtonGlyphs := sbgNever;
 
1586
 KeyPreview := true;
 
1587
  {$IFDEF Darwin}
 
1588
       InitOpenDocHandler;//allows files to be associated...
 
1589
        {$IFNDEF LCLgtk} //only for Carbon compile
 
1590
            Open1.ShortCut := ShortCut(Word('O'), [ssMeta]);
 
1591
            SaveasNIfTI1.ShortCut := ShortCut(Word('S'), [ssMeta,ssAlt]);
 
1592
            Saveaspicture1.ShortCut := ShortCut(Word('S'), [ssMeta]);
 
1593
            Copy1.ShortCut := ShortCut(Word('C'), [ssMeta]);
 
1594
            Paste1.ShortCut := ShortCut(Word('V'), [ssMeta]);
 
1595
            Undo1.ShortCut := ShortCut(Word('Z'), [ssMeta]);
 
1596
            OverlayOpen.ShortCut := ShortCut(Word('A'), [ssMeta]);
 
1597
            Applyintensityfiltertovolume1.ShortCut := ShortCut(Word('F'), [ssMeta]);
 
1598
            HistoMenu.ShortCut := ShortCut(Word('H'), [ssMeta]);
 
1599
            ShowRender.ShortCut := ShortCut(Word('R'), [ssMeta]);
 
1600
            ShowMultislice.ShortCut := ShortCut(Word('M'), [ssMeta]);
 
1601
            N4DTraces1.ShortCut := ShortCut(Word('D'), [ssMeta]);
 
1602
            Header1.ShortCut := ShortCut(Word('I'), [ssMeta]);
 
1603
        {$ENDIF}
 
1604
 {$ENDIF}
 
1605
 
 
1606
 
 
1607
 
 
1608
{$IFDEF Darwin}
 
1609
        {$IFNDEF LCLgtk} //only for Carbon compile
 
1610
        Exit1.visible := false;//with OSX users quit from application menu
 
1611
        {$ENDIF}
 
1612
 {$ENDIF}
 
1613
     CreateFX8(gUndoImg);
 
1614
     CreateFX8(gDrawImg);
 
1615
           TriplePanel.OnMouseWheelDown:=  @FormMouseWheelDown;
 
1616
     TriplePanel.OnMouseWheelUp:=  @FormMouseWheelUp;
 
1617
     TriplePanel.OnMouseWheelDown:=  @FormMouseWheelDown;
 
1618
     TriplePanel.OnMouseWheelUp:=  @FormMouseWheelUp;
 
1619
     TriplePanel.OnMouseWheelDown:=  @FormMouseWheelDown;
 
1620
     TriplePanel.OnMouseWheelUp:=  @FormMouseWheelUp;
 
1621
     randomize;
 
1622
     gnCPUThreads := GetLogicalCpuCount;
 
1623
     gMouseDownX := -1;
 
1624
     ImgForm.Caption := extractfilename(paramstr(0));
 
1625
     ImgForm.DoubleBuffered := true;
 
1626
     TriplePanel.DoubleBuffered := true;
 
1627
     TriplePanel.DoubleBuffered := true;
 
1628
     TriplePanel.DoubleBuffered := true;
 
1629
         for lInc := 0 to knMaxOverlay do begin
 
1630
                FreeImgMemory(gMRIcroOverlay[lInc]);
 
1631
                NIFTIhdr_ClearHdr(gMRIcroOverlay[lInc]);
 
1632
                gMRIcroOverlay[lInc].ScrnBufferItems := 0;
 
1633
                gMRIcroOverlay[lInc].ImgBufferItems := 0;
 
1634
                if lInc < knAutoLUT then
 
1635
                        gMRIcroOverlay[lInc].LUTindex := lInc
 
1636
                else
 
1637
                        gMRIcroOverlay[lInc].LUTindex := lInc;//B&W
 
1638
                LoadMonochromeLUT(gMRIcroOverlay[lInc].LUTindex,gBGImg,gMRIcroOverlay[lInc]);
 
1639
         end;
 
1640
         lInc:=maxint;
 
1641
         LoadMonochromeLUT(lInc,gBGImg,gMRIcroOverlay[kVOIOverlayNum]);
 
1642
         SetBGImgDefaults(gBGImg);
 
1643
         CloseImagesClick(nil);
 
1644
         gColorSchemeDir := extractfilepath(paramstr(0))+'lut';
 
1645
         {$IFNDEF Unix} DragAcceptFiles(Handle, True); //engage drag and drop
 
1646
         {$ENDIF}
 
1647
         UpdateColorSchemes;
 
1648
        {$IFNDEF FPC}
 
1649
         LUTdrop.SetItemIndex(0);
 
1650
         Zoomdrop.SetItemIndex(0);
 
1651
         LayerDrop.SetItemIndex(0);
 
1652
  {$ELSE}
 
1653
         LUTdrop.ItemIndex:=(0);
 
1654
         Zoomdrop.ItemIndex:=(0);
 
1655
         LayerDrop.ItemIndex:=(0);
 
1656
         MagnifyMenuItem.visible := false;
 
1657
         {$IFNDEF COMPILEYOKE}
 
1658
         YokeMenu.visible := false;
 
1659
         {$ENDIF}
 
1660
{$ENDIF}
 
1661
         gTemplateDir := extractfilepath(paramstr(0))+'templates';
 
1662
         UpdateTemplates;
 
1663
 
 
1664
         for lInc := 1 to knMRU do
 
1665
                 gMRUstr[lInc] := '';
 
1666
 
 
1667
         (*if (ssShift in KeyDataToShiftState(vk_Shift))  then begin
 
1668
                case MessageDlg('Shift key down during launch: do you want to reset the default preferences?', mtConfirmation,
 
1669
                                [mbYes, mbNo], 0) of    { produce the message dialog box }
 
1670
                                mrNo: ReadIniFile;
 
1671
            end; //case
 
1672
 
 
1673
         end else*)
 
1674
 
 
1675
         if  ResetDefaults then
 
1676
             DrawMenu.Visible := ToolPanel.visible
 
1677
         else
 
1678
            ReadIniFile;
 
1679
 
 
1680
         SetIniMenus;
 
1681
         UpdateMRU;
 
1682
         DefaultControlPanel;
 
1683
         OverlaySmoothMenuClick(nil);
 
1684
         LUTDrop.OnSelect(nil);
 
1685
         ZoomDrop.OnSelect(nil);
 
1686
         CreateShareMem;
 
1687
         if YokeMenu.checked then YokeTimer.enabled := true;
 
1688
   //gBGIMg.SaveDefaultIni := true;
 
1689
end;
 
1690
 
 
1691
function ImgIntensity(var lHdr: TMRIcroHdr; lX,lY,lZ: integer): single;
 
1692
var
 
1693
        lPos: integer;
 
1694
        l16Buf : SmallIntP;
 
1695
        l32Buf : SingleP;
 
1696
begin
 
1697
  result := 0;
 
1698
  lPos := lX + ((lY-1)*gBGImg.ScrnDim[1])+((lZ-1)*gBGImg.ScrnDim[1]*gBGImg.ScrnDim[2]);
 
1699
  if (lPos > lHdr.ImgBufferItems) or (lPos < 1) then exit;
 
1700
  if (lHdr.ImgBufferBPP  = 4) then begin
 
1701
        l32Buf := SingleP(lHdr.ImgBuffer );
 
1702
        result := l32Buf^[lPos];
 
1703
  end else if (lHdr.ImgBufferBPP  = 2) then begin
 
1704
           l16Buf := SmallIntP(lHdr.ImgBuffer );
 
1705
        result := l16Buf^[lPos];
 
1706
  end else if lHdr.ImgBufferBPP  = 1 then
 
1707
         result := lHdr.ImgBuffer^[lPos]
 
1708
  else begin
 
1709
        showmessage('Unknown Image Buffer Bytes Per Pixel: '+inttostr(lHdr.ImgBufferBPP)+'  '+lHdr.HdrFileName);
 
1710
        exit;
 
1711
  end;
 
1712
  result := Raw2ScaledIntensity (lHdr,result);
 
1713
end;
 
1714
 
 
1715
function ImgIntensityString(var lHdr: TMRIcroHdr; lX,lY,lZ: integer): string;
 
1716
var
 
1717
        lPos: integer;
 
1718
begin
 
1719
  lPos := lX + ((lY-1)*gBGImg.ScrnDim[1])+((lZ-1)*gBGImg.ScrnDim[1]*gBGImg.ScrnDim[2]);
 
1720
  result := '';
 
1721
  if lHdr.ImgBufferItems < 1 then exit;
 
1722
  if not lHdr.UsesCustomPalette then begin
 
1723
        result := realtostr(ImgIntensity(lHdr,lX,lY,lZ),gBGImg.SigDig);
 
1724
(*              if lHdr.ScrnBuffer[lPos] = 0 then begin
 
1725
                        if lHdr.Slope8Bit < 0 then
 
1726
                                result := '>'+result
 
1727
                        else
 
1728
                                result := '<'+result
 
1729
                end else if lHdr.ScrnBuffer[lPos] = 255 then begin
 
1730
                        if lHdr.Slope8Bit < 0 then
 
1731
                                result := '<'+result
 
1732
                        else
 
1733
                                result := '>'+result
 
1734
                end else
 
1735
                        result := '~'+result;*)
 
1736
        exit;
 
1737
  end;
 
1738
  if (lPos > lHdr.ImgBufferItems) or (lPos < 1) then exit;
 
1739
  result := gBGImg.LabelStr20[lHdr.ImgBuffer^[lPos]];
 
1740
end;
 
1741
 
 
1742
procedure TImgForm.UpdateStatusLabel;
 
1743
var
 
1744
        lX,lY,lZ,lOverlay,lLen: integer;
 
1745
        lXmm,lYmm,lZmm: single;
 
1746
        lIntenStr : string;
 
1747
begin
 
1748
 
 
1749
        lX := XviewEdit.value;
 
1750
        lY := YviewEdit.value;
 
1751
        lZ := ZviewEdit.value;
 
1752
        ImgCoordToMM(lX,lY,lZ,lXmm,lYmm,lZmm);
 
1753
 
 
1754
 lIntenStr := '';
 
1755
//StatusLabel.Caption := realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0);
 
1756
//lIntenStr := realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0)+'= '+lIntenStr;;
 
1757
 
 
1758
//StatusLabel.Caption := lIntenStr;
 
1759
//StatusLabel.Caption := realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0)+'= '+lIntenStr;
 
1760
//crash!
 
1761
 for lOverlay := kBGOverlayNum to (kVOIOverlayNum-1) do
 
1762
                if gMRIcroOverlay[lOverlay].ImgBufferItems > 0 then
 
1763
                        lIntenStr := lIntenStr + ImgIntensityString(gMRIcroOverlay[lOverlay],lX,lY,lZ)+', ';
 
1764
        lLen := length (lIntenstr);
 
1765
        if lLen > 2 then
 
1766
                lIntenStr[lLen-1] := ' ';
 
1767
        //StatusLabel.Caption := realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0)+'= '+lIntenStr;
 
1768
        Caption := realtostr(lXmm,0)+'x'+realtostr(lYmm,0)+'x'+realtostr(lZmm,0)+'= '+lIntenStr;
 
1769
 
 
1770
//      SetShareMem (lXmm,lYmm,lZmm);
 
1771
end;
 
1772
 
 
1773
procedure TImgForm.XViewEditChange(Sender: TObject);
 
1774
begin
 
1775
         gBGImg.XViewCenter := XviewEdit.value;
 
1776
         gBGImg.YViewCenter := YviewEdit.value;
 
1777
         gBGImg.ZViewCenter := ZviewEdit.value;
 
1778
         RefreshImagesTimer.Enabled := true;
 
1779
         //UpdateStatusLabel;  //caused crash! - only with refreshimagestimes
 
1780
end;
 
1781
 
 
1782
  {$IFNDEF FPC}
 
1783
procedure TImgForm.FormClose(Sender: TObject; var Action: TCloseAction);
 
1784
  {$ELSE}
 
1785
procedure TImgForm.FormClose(Sender: TObject);
 
1786
  {$ENDIF}
 
1787
begin
 
1788
 
 
1789
 WriteIniFile;
 
1790
 CloseImagesClick(nil);
 
1791
 FreeFX8(gDrawImg);
 
1792
 FreeFX8(gUndoImg);
 
1793
end;
 
1794
 
 
1795
procedure TImgForm.MagnifyTimerTimer(Sender: TObject);
 
1796
  {$IFDEF FPC}
 
1797
  begin
 
1798
//      MagnifyTimer.Enabled := false;
 
1799
  end;
 
1800
  {$ELSE}
 
1801
  var
 
1802
  Srect,Drect,PosForme,ImgForme:TRect;
 
1803
  lZoomSlider,iWidth,iHeight,DmX,DmY:Integer;
 
1804
  iTmpX,iTmpY:Real;
 
1805
  C:TCanvas;
 
1806
  hDesktop: Hwnd;
 
1807
  Kursor:TPoint;
 
1808
begin
 
1809
 
 
1810
 MagnifyTimer.Enabled := false;
 
1811
 lZoomSlider := 2;
 
1812
 If not IsIconic(Application.Handle) then begin
 
1813
  hDesktop:= GetDesktopWindow;
 
1814
  GetCursorPos(Kursor);
 
1815
  ImgForme := Rect(ImgForm.Left+ImgForm.TriplePanel.Left,ImgForm.Top+ImgForm.TriplePanel.Top,ImgForm.Left+ImgForm.Width,ImgForm.Top+ImgForm.Height);
 
1816
  PosForme:=Rect(MagnifyPanel.Left,MagnifyPanel.Top,MagnifyPanel.Left+MagnifyPanel.Width,MagnifyPanel.Top+MagnifyPanel.Height);
 
1817
  if true then begin
 
1818
  iWidth:=MagnifyImage.Width;
 
1819
  iHeight:=MagnifyImage.Height;
 
1820
  if iHeight < 6 then exit;
 
1821
    Drect:=Rect(0,0,iWidth,iHeight);
 
1822
    iTmpX:=iWidth / (lZoomSlider*4);//(Slider.Position * 4);
 
1823
    iTmpY:=iHeight / (lZoomSlider*4);//(Slider.Position * 4);
 
1824
    Srect:=Rect(Kursor.x,Kursor.y,Kursor.x,Kursor.y);
 
1825
    InflateRect(Srect,Round(iTmpX),Round(iTmpY));
 
1826
        If Srect.Left<0 then OffsetRect(Srect,-Srect.Left,0);
 
1827
    If Srect.Top<0 then OffsetRect(Srect,0,-Srect.Top);
 
1828
    If Srect.Right>Screen.Width then OffsetRect(Srect,-(Srect.Right-Screen.Width),0);
 
1829
    If Srect.Bottom>Screen.Height then OffsetRect(Srect,0,-(Srect.Bottom-Screen.Height));
 
1830
   C:=TCanvas.Create;
 
1831
   try
 
1832
     C.Handle:=GetDC(GetDesktopWindow);
 
1833
      SetStretchBltMode(C.Handle,COLORONCOLOR);
 
1834
      //SetStretchBltMode(C.Handle, STRETCH_DELETESCANS);
 
1835
      //SetStretchBltMode(C.Handle,{BILINEAR}TransparencyEdit.value);
 
1836
     MagnifyImage.Canvas.CopyRect(Drect,C,Srect);
 
1837
    finally
 
1838
      ReleaseDC(hDesktop, C.Handle);
 
1839
      C.Free;
 
1840
    end;
 
1841
    If True then begin // show crosshair
 
1842
        MagnifyImage.Canvas.Pen.Color := gBGIMg.XBarClr;
 
1843
        with MagnifyImage.Canvas do begin
 
1844
        DmX:=lZoomSlider * 2 * (Kursor.X-Srect.Left);
 
1845
        DmY:=lZoomSlider * 2 * (Kursor.Y-Srect.Top);
 
1846
                 MoveTo(1,DmY); // -
 
1847
                 LineTo(iWidth,DmY); // -
 
1848
                 MoveTo(DmX,1); // |
 
1849
                 LineTo(DmX,iHeight); // |
 
1850
      end; // with MagnifyImage.Canvas
 
1851
    end; // show crosshair
 
1852
        Application.ProcessMessages;
 
1853
    end // Cursor not inside form
 
1854
 end; // IsIconic
 
1855
end;  //magnify image
 
1856
  {$ENDIF}
 
1857
 
 
1858
procedure TImgForm.MagnifyPanelResize(Sender: TObject);
 
1859
begin
 
1860
(* MagnifyImage.Picture:=nil;
 
1861
 if MagnifyPanel.Width < MagnifyPanel.Constraints.MinWidth then
 
1862
     MagnifyPanel.Width := MagnifyPanel.Constraints.MinWidth;
 
1863
     *)
 
1864
end; //Proc MagnifyPanelResize
 
1865
 
 
1866
procedure SelectPanel (lPanelNumber: integer);
 
1867
begin
 
1868
gSelectedImageNum := lPanelNumber;
 
1869
end; //Proc SelectPanel
 
1870
 
 
1871
procedure ShowFocusRect(lInRect: TRect);
 
1872
var LImage: TImage;
 
1873
begin
 
1874
        lImage := SelectedImage;
 
1875
   lImage.Canvas.DrawFocusRect(lInRect);
 
1876
end; //proc ShowFocusRect
 
1877
 
 
1878
procedure XYscrn2Img (lImage: TIMage;lPanel,lXinRaw,lYinRaw: integer; var lXout,lYOut,lZOut: integer);
 
1879
var
 
1880
        lYin,lXin,lZoom : integer;
 
1881
        lOffset: single;
 
1882
begin
 
1883
         //amx - must match XYscrn2Img and DrawXBar - e.g. +0.5 for middle of zoomed slice
 
1884
          lZoom := ImageZoomPct(lImage);
 
1885
          if lZoom = 0 then lZoom := 100;
 
1886
         if lZoom > 100 then lOffset := 0.5 else
 
1887
                lOffset := 0;
 
1888
         lXIn := lXinRaw + 1; //index from 0
 
1889
          lYin := lImage.Height-lYinRaw;
 
1890
          case lPanel of
 
1891
                   2: begin
 
1892
                      if gBGImg.FlipSag then
 
1893
                         lXin := lImage.Width-lXinRaw;
 
1894
                                lXOut := ImgForm.XViewEdit.value;
 
1895
                                lYOut := round((lXin*100) / lZoom +lOffset);
 
1896
                                lZOut := round((lYin*100) / lZoom +lOffset);
 
1897
                   end;
 
1898
                   3: begin
 
1899
                                lXOut := round((lXin*100) / lZoom +lOffset);
 
1900
                                lYOut := ImgForm.YViewEdit.value;
 
1901
                                lZOut := round((lYin*100) / lZoom +lOffset);
 
1902
 
 
1903
                   end;
 
1904
                   else begin
 
1905
                        if gBGImg.FlipAx then
 
1906
                                         lYin := lYinRaw;
 
1907
                                        lXOut := round((lXin*100) / lZoom +lOffset);
 
1908
                                lYOut := round((lYin*100) / lZoom +lOffset);
 
1909
                                lZOut := ImgForm.ZViewEdit.value;
 
1910
                   end; //else
 
1911
          end;//case lPanel
 
1912
          //ImgForm.Caption := inttostr(lXOut)+' '+inttostr(lYOut)+'  '+Inttostr(lZOut);
 
1913
end; //proc XYscrn2Img
 
1914
 
 
1915
procedure AdjustContrastRectangle (lImage: TImage);
 
1916
var
 
1917
 lXpos,lYPos,lXOut,lYOut,lZOut,lPanel,lLayer: integer;
 
1918
 lMinInten,lMaxInten,lVal: single;
 
1919
begin
 
1920
   lPanel := SelectedImageNum;
 
1921
   lLayer := ActiveLayer;
 
1922
   XYscrn2Img (lImage,lPanel,gSelectRect.Left,gSelectRect.Top, lXout,lYOut,lZOut);
 
1923
   lMinInten := ImgIntensity(gMRIcroOverlay[lLayer],lXout,lYOut,lZOut);
 
1924
   lMaxInten := lMinInten;
 
1925
   for lYpos := gSelectRect.Top to gSelectRect.Bottom do begin
 
1926
           for lXpos := gSelectRect.Left to gSelectRect.Right do begin
 
1927
                   XYscrn2Img (lImage,lPanel,lXpos,lYPos, lXout,lYOut,lZOut);
 
1928
                        lVal:= ImgIntensity(gMRIcroOverlay[lLayer],lXout,lYOut,lZOut);
 
1929
                        if lVal < lMinInten then lMinInten := lVal;
 
1930
                        if lVal > lMaxInten then lMaxInten := lVal;
 
1931
           end; //for PGX each column
 
1932
   end; //for PGY2 - each row
 
1933
   ImgForm.StatusLabel.caption := '^^Intensity range '+(RealToStr(lMinInten,4))+'..'+({x} RealToStr(lMaxInten,4));
 
1934
   if lMinInten = lMaxInten then exit; //no range
 
1935
   ImgForm.MinWindowEdit.value  := lMinInten;
 
1936
   ImgForm.MaxWindowEdit.value := lMaxInten;
 
1937
   {$IFDEF FPC} ImgForm.MinContrastWindowEditChange(nil) {$ENDIF}
 
1938
end;
 
1939
 
 
1940
procedure sortLTRB(var lXoutLow,lYOutLow,lXoutHi,lYOutHi: integer); //left<right, top<bottom
 
1941
var lXin1,lYin1,lXin2,lYin2: integer;
 
1942
begin
 
1943
        lXin1 := lXoutLow;
 
1944
        lYin1 := lYOutLow;
 
1945
        lXin2 := lXoutHi;
 
1946
        lYin2 := lYOutHi;
 
1947
        if lXIn1 < lXin2 then begin
 
1948
           lXoutLow := lXIn1;
 
1949
           lXOutHi := lXIn2;
 
1950
        end else begin
 
1951
           lXoutLow := lXIn2;
 
1952
           lXOutHi := lXIn1;
 
1953
        end;
 
1954
        if lYIn1 < lYin2 then begin
 
1955
           lYoutLow := lYIn1;
 
1956
           lYOutHi := lYIn2;
 
1957
        end else begin
 
1958
           lYoutLow := lYIn2;
 
1959
           lYOutHi := lYIn1;
 
1960
        end;
 
1961
end; //sortLTRB
 
1962
 
 
1963
procedure DrawEllipse (lImage: TImage;lRect: TRect; lShift: TShiftState; lPanel: integer);
 
1964
begin
 
1965
   ScaleBMP2Draw(gBGImg.VOIInvZoom, lRect.Left,lRect.Top,lPanel,Limage);
 
1966
   ScaleBMP2Draw(gBGImg.VOIInvZoom, lRect.Right,lRect.Bottom,lPanel,lImage);
 
1967
   if (ssCtrl in lShift) then
 
1968
      FillRectFX8(gDrawImg,lRect.Left,lRect.Top,lRect.Right,lRect.Bottom,kVOI8bit)
 
1969
   else
 
1970
        FillEllipseFX8(gDrawImg,lRect.Left,lRect.Top,lRect.Right,lRect.Bottom,kVOI8bit);
 
1971
end; //DrawEllipse
 
1972
 
 
1973
 
 
1974
procedure TImgForm.PGImageMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
 
1975
var lZoom,lPanel,lX, lY,lXout,lYOut,lZOut,lBasePenThick,lX2, lY2: integer;
 
1976
        lImage: TImage;
 
1977
begin
 
1978
   //ImgForm.GetFocus := true;
 
1979
   gSelectOrigin.X := -1;
 
1980
 
 
1981
   lX := X; lY := Y;
 
1982
   lImage := Sender as TImage;
 
1983
   if lImage.Name = PGImageCor.Name {'PGImageCor'} then lPanel := kCoroView0
 
1984
   else if lImage.Name = PGImageSag.Name {'PGImageSag'} then lPanel := kSagView0
 
1985
   else lPanel := kAxView0;
 
1986
   //lImage.Canvas.Pen.Width := 1;
 
1987
   //   lImage.Canvas.Pen.Color :=gBGImg.VOIClr;
 
1988
   SelectPanel(lPanel);
 
1989
   gBGImg.VOIInvZoom := ComputeInvZoomShl10(lPanel,lImage);
 
1990
 
 
1991
   if  DrawToolSelected then begin //paint tool
 
1992
           WriteUndoVOI(lPanel,false);
 
1993
           if (ssShift in Shift) then begin //erase
 
1994
                        lImage.Canvas.Brush.Color:=clBlack;
 
1995
                        lImage.Canvas.Pen.Color := clBlack;
 
1996
           end else begin
 
1997
                        lImage.Canvas.Brush.Color:=gBGImg.VOIClr;
 
1998
                        lImage.Canvas.Pen.Color := gBGImg.VOIClr;
 
1999
           end;
 
2000
           if gBGImg.ThinPen then
 
2001
                        lBasePenThick := 1
 
2002
           else begin //adjust pen thickness for zoom level
 
2003
                 if gBGImg.ZoomPct < 100 then begin
 
2004
                        lZoom := ComputeZoomPct(lPanel,lImage);
 
2005
                        if lZoom = 100 then
 
2006
                                lBasePenThick := 1
 
2007
                        else
 
2008
                          lBasePenThick :=  round((ComputeZoomPct(lPanel,lImage)+50) / 100);
 
2009
                 end else if gBGImg.ZoomPct > 100 then
 
2010
                        lBasePenThick := gBGImg.ZoomPct div 100
 
2011
                 else
 
2012
                        lBasePenThick := 1;
 
2013
           end; //if not thinpen
 
2014
                if (ssCtrl in Shift) then begin
 
2015
                        lImage.Canvas.Pen.Width := lBasePenThick*3;
 
2016
                        gDrawImg.PenThick := 3;
 
2017
                end else begin
 
2018
                        lImage.Canvas.Pen.Width := lBasePenThick;
 
2019
                        gDrawImg.PenThick := 1;
 
2020
                end;
 
2021
   end; //paint tool selected
 
2022
   //lImage.Canvas.Pen.Width := 1;//abba
 
2023
   if  (FillBtn.Down) and (ssCtrl in Shift) then begin  //3D fill
 
2024
                        XYscrn2Img (lImage,lPanel,lX,lY, lXout,lYOut,lZOut);
 
2025
                                XViewEdit.value := lXOut;
 
2026
                                YViewEdit.value := lYOut;
 
2027
                                ZViewEdit.value := lZOut;
 
2028
                        if (ssShift in Shift) then //erase
 
2029
                                ROICluster(gBGImg.ScrnDim[1], gBGImg.ScrnDim[2], gBGImg.ScrnDim[3],XViewEdit.value,YViewEdit.value,ZViewEdit.value,true)
 
2030
                        else //draw
 
2031
                                ROICluster(gBGImg.ScrnDim[1], gBGImg.ScrnDim[2], gBGImg.ScrnDim[3],XViewEdit.value,YViewEdit.value,ZViewEdit.value,false);
 
2032
                        exit;
 
2033
   end; //end 3D fill
 
2034
   if (not PenBtn.Down) and (not ClosedPenBtn.Down) and (not FillBtn.Down)  then begin
 
2035
                if  (EllipseBtn.Down) or (ssRight in Shift) then begin
 
2036
                        lImage.Canvas.Brush.Color:=gBGImg.VOIClr;
 
2037
                        //lImage.Canvas.Pen.Color :=gBGImg.VOIClr;
 
2038
                        ScaleScrn2BMP(lX,lY, lImage);
 
2039
                        gSelectRect.Left := lX;
 
2040
                        gSelectRect.Top := lY;
 
2041
                        gSelectRect.Right := lX;
 
2042
                        gSelectRect.Bottom := lY;
 
2043
                        ShowFocusRect(gSelectRect);
 
2044
                        gSelectOrigin.X := gSelectRect.Left;
 
2045
                        gSelectOrigin.Y := gSelectRect.Top;
 
2046
                        exit;
 
2047
                end;
 
2048
                //next no paint tools selected - show position where click occurred
 
2049
                XYscrn2Img (lImage,lPanel,lX,lY, lXout,lYOut,lZOut);
 
2050
                                XViewEdit.value := lXOut;
 
2051
                                YViewEdit.value := lYOut;
 
2052
                                ZViewEdit.value := lZOut;
 
2053
                                //showmessage(floattostr(lXOut)+'x'+floattostr(lYOut)+'x'+floattostr(lZOut));
 
2054
                                //ImgCoordToMM(lXOut,lYOut,lZOut,lXmm,lYmm,lZmm);
 
2055
                                //showmessage(floattostr(lXmm)+'x'+floattostr(lYmm)+'x'+floattostr(lZmm));
 
2056
 
 
2057
                                //showmessage(floattostr(gBGImg.ScrnOri[1])+'x'+floattostr(gBGImg.ScrnOri[2])+'x'+floattostr(gBGImg.ScrnOri[3]));
 
2058
                                //MMToImgCoord(lXOut,lYOut,lZOut,lXmm,lYmm,lZmm);
 
2059
                                //showmessage(floattostr(lXOut)+'x'+floattostr(lYOut)+'x'+floattostr(lZOut));
 
2060
 
 
2061
                                //SetShareMem (lXmm,lYmm,lZmm);
 
2062
 
 
2063
        {$IFDEF FPC}
 
2064
  XViewEditChange(nil);
 
2065
  {$ENDIF}
 
2066
        exit;
 
2067
   end;
 
2068
   ScaleScrn2BMP(lX,lY, lImage);
 
2069
   lImage.Canvas.MoveTo(lX,lY);
 
2070
 
 
2071
   lX2 := X; lY2 := Y;
 
2072
   ScaleBMP2Draw(gBGImg.VOIInvZoom, lX2,lY2,lPanel,lImage);
 
2073
   if  (FillBtn.Down) or(ssRight in Shift) then begin
 
2074
 
 
2075
           if (ssShift in Shift) then
 
2076
              FloodFillFX8 (gDrawImg, lX2,lY2,kVOI8bit,0,true)
 
2077
              //FloodFillX(DrawImg2,lX2-1,lY2-1,gBGImg.VOIClr, fsSurface)
 
2078
           else
 
2079
               FloodFillFX8 (gDrawImg, lX2,lY2,kVOI8bit,kVOI8bit,false);
 
2080
        //FloodFillX(DrawImg2,lX2-1,lY2-1,gBGImg.VOIClr, fsBorder);
 
2081
 
 
2082
           exit;
 
2083
   end;
 
2084
   //ImgForm.caption := inttostr(lX2);
 
2085
   MoveToFX8(gDrawImg,lX2,lY2);
 
2086
   if lImage.Canvas.Pen.Color = clBlack then //ensure single pixel is drawn if user clicks without dragging
 
2087
      LineToFX8(gDrawImg,lX2,lY2,0)
 
2088
   else
 
2089
       LineToFX8(gDrawImg,lX2,lY2,kVOI8bit);
 
2090
   gMouseDownX := lX;
 
2091
   gMouseDownY := lY;
 
2092
 
 
2093
end; //PGImageMouseDown
 
2094
 
 
2095
var
 
2096
   gDragX,gDragY,gDragZ : integer;
 
2097
   //gDragRefresh : boolean = false; //only redraw one snapshot at a time
 
2098
 
 
2099
procedure TImgForm.PGImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
 
2100
var lX, lY,lPanel,lXOut,lYOut,lZOut: integer;
 
2101
        lImage: TImage;
 
2102
begin
 
2103
         lImage := Sender as TImage;
 
2104
         lX := X; lY := Y;
 
2105
         ScaleScrn2BMP(lX,lY,lImage);
 
2106
         //if MagnifyImage.Height > 10 then
 
2107
        //      MagnifyTimer.Enabled := true;//MagnifyBtn.Down;
 
2108
         //StatusLabel.Caption := inttostr(lX)+','+inttostr(lY);
 
2109
         if {(ssShift in Shift) and} (gSelectOrigin.X > 0) then begin
 
2110
                ShowFocusRect(gSelectRect);
 
2111
                gSelectRect.Left := gSelectOrigin.X;
 
2112
                gSelectRect.Top := gSelectOrigin.Y;
 
2113
                gSelectRect.Right := lX;
 
2114
                gSelectRect.Bottom := lY;
 
2115
                sortLTRB(gSelectRect.Left,gSelectRect.Top,gSelectRect.Right,gSelectRect.Bottom);
 
2116
                ShowFocusRect(gSelectRect);
 
2117
                exit;
 
2118
         end;
 
2119
         if (not DrawToolSelected) and ((ssLeft in Shift)) then begin
 
2120
            //RefreshImagesTimer.Enabled := false;
 
2121
            //gDragRefresh := true;
 
2122
            if lImage.Name = PGImageCor.Name then lPanel := kCoroView0
 
2123
            else if lImage.Name = PGImageSag.Name then lPanel := kSagView0
 
2124
            else lPanel := kAxView0;
 
2125
            XYscrn2Img (lImage,lPanel,lX,lY, lXout,lYOut,lZOut);
 
2126
            if (lXout = gDragX) and (lYout = gDragY) and (lZOut = gDragZ) then
 
2127
               exit;//no change
 
2128
            XViewEdit.value := lXOut;
 
2129
            YViewEdit.value := lYOut;
 
2130
            ZViewEdit.value := lZOut;
 
2131
 
 
2132
            {$IFDEF FPC}XViewEditChange(nil);{$ENDIF}   //can generate crash!
 
2133
            //gDragRefresh := false;
 
2134
            exit;
 
2135
         end;
 
2136
 
 
2137
         if (not (ssLeft in Shift)) or (gMouseDownX < 0) then exit;
 
2138
         if PenBtn.Down or ClosedPenBtn.Down then begin
 
2139
                lImage.Canvas.LineTo(lX,lY);
 
2140
                lX := X; lY := Y;
 
2141
                ScaleBMP2Draw(gBGImg.VOIInvZoom, lX,lY,lPanel,lImage);
 
2142
                //DrawImg2.Canvas.LineTo(lX,lY);
 
2143
                if lImage.Canvas.Pen.Color = clBlack then
 
2144
                    LineToFX8(gDrawImg,lX,lY,0)//zzzxx
 
2145
                else
 
2146
                    LineToFX8(gDrawImg,lX,lY,kVOI8bit);//zzzxx
 
2147
         end;
 
2148
end; //PGImageMouseMove
 
2149
 
 
2150
(*procedure Scrn2VOI (var lImage: TImage; lXvoi,lYvoi: integer; var lVOIBuffer: ByteP);
 
2151
 
 
2152
const
 
2153
 kSh = 10; //bits to shift
 
2154
var
 
2155
        lInc,lXpos,lYPos,lVOISliceSz: integer;
 
2156
        srcBmp : TBitmap;
 
2157
begin
 
2158
  srcBmp := lImage.Picture.Bitmap;
 
2159
  lVOISliceSz := lXvoi*lYvoi;
 
2160
  GetMem (lVOIBuffer , lVOISliceSz);
 
2161
  lInc := 0;
 
2162
  for lYpos:=(lYvoi-1) downto 0 do begin
 
2163
      for lXpos:=0 to lXvoi-1 do begin
 
2164
        inc(lInc);                   //zax
 
2165
        if srcBmp.Canvas.Pixels[lXpos,lYPos] = clBlack then
 
2166
           lVOIBuffer^[lInc] := 0
 
2167
        else
 
2168
            lVOIBuffer^[lInc] := 100;
 
2169
      end;
 
2170
  end;
 
2171
end; //Scrn2VOI *)
 
2172
 
 
2173
 
 
2174
procedure ReadCorVOI (var lImage: TFX8; lSlice: integer);
 
2175
var lX,lY,lZ,lYOffset,lZOffset,lXYSliceSz,lPixel,lZPos,lXPos: integer;
 
2176
begin
 
2177
        lX := gBGImg.ScrnDim[1];
 
2178
        lY := gBGImg.ScrnDim[2];
 
2179
        lZ := gBGImg.ScrnDim[3];
 
2180
        lYOffset := (lX) * (round(lSlice)-1);
 
2181
        lXYSliceSz := (lX*lY);
 
2182
        //Scrn2VOI (lImage,lX,lZ, lInBuff);
 
2183
        lPixel := 0;
 
2184
        for lZPos := 1 to lZ do begin
 
2185
          lZOffset := (lZPos-1) * lXYSliceSz;
 
2186
          for lXPos := 1 to lX do begin
 
2187
                  inc(lPixel);
 
2188
                gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lZOffset+lYOffset+lXPos] :=lImage.Img^[lPixel];
 
2189
          end; //for each Y
 
2190
        end; //for each Z
 
2191
end;
 
2192
 
 
2193
procedure ReadSagVOI (var lImage: TFX8;lSlice: integer);
 
2194
var lX,lY,lZ,lXOffset,lYOffset,lZOffset,lXYSliceSz,lPixel,lZPos,lYPos: integer;
 
2195
begin
 
2196
        lX := gBGImg.ScrnDim[1];
 
2197
        lY := gBGImg.ScrnDim[2];
 
2198
        lZ := gBGImg.ScrnDim[3];
 
2199
        lXYSliceSz := lX*lY;
 
2200
        lXOffset := round(lSlice);
 
2201
 // dec(lXOffset);//999+8
 
2202
        lPixel := 0;
 
2203
        for lZPos := 1 to lZ do begin
 
2204
          lZOffset := (lZPos-1) * lXYSliceSz;
 
2205
          lYOffset := 0;
 
2206
          for lYPos := 1 to lY do begin
 
2207
                  inc(lPixel);
 
2208
                gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lZOffset+lYOffset+lXOffset] := lImage.Img^[lPixel];
 
2209
                  lYOffset := lYOffset+ lX;
 
2210
          end; //for each Y
 
2211
        end; //for each Z
 
2212
        //freemem(lInBuff);
 
2213
end;
 
2214
 
 
2215
procedure ReadAxialVOI (var lImage: TFX8;lSlice: integer);
 
2216
var lX,lY,lSliceOffset,lSliceSz: integer;
 
2217
begin
 
2218
        lX := gBGImg.ScrnDim[1];
 
2219
        lY := gBGImg.ScrnDim[2];
 
2220
        lSliceSz := lX*lY;
 
2221
        lSliceOffset := (lSlice-1)*lX*lY;
 
2222
        //Scrn2VOI (lImage,lX,lY, lInBuff);
 
2223
        for lX := 1 to lSliceSz do
 
2224
                gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lSliceOffset+lX] := lImage.Img^[lX];
 
2225
 
 
2226
end;
 
2227
 
 
2228
procedure ReadScrnVOI (lImage: TImage);
 
2229
var
 
2230
        lView: integer;
 
2231
begin
 
2232
         if (gBGImg.VOIUndoSlice < 1) or (gBGImg.VOIUndoOrient < 1) or (gBGImg.VOIUndoOrient > 3) then exit;
 
2233
        if (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems  < 1) or (lImage.Picture.Bitmap.Width < 1) or (lImage.Picture.Bitmap.Height < 1) then
 
2234
                exit;
 
2235
        EnsureVOIOpen;
 
2236
        lView := SelectedImageNum;
 
2237
        case lView of
 
2238
                3: ReadCorVOI(gDrawImg,ImgForm.YViewEdit.Value);
 
2239
                2: ReadSagVOI(gDrawImg,ImgForm.XViewEdit.Value);
 
2240
                1: ReadAxialVOI(gDrawImg,ImgForm.ZViewEdit.Value);
 
2241
        end;
 
2242
        ImgForm.RefreshImagesTimer.Enabled := true;
 
2243
end;
 
2244
 
 
2245
procedure TImgForm.PGImageMouseUp(Sender: TObject; Button: TMouseButton;
 
2246
  Shift: TShiftState; X, Y: Integer);
 
2247
var lX, lY,lPanel: integer;
 
2248
lImage: TImage;
 
2249
begin
 
2250
       lPanel := SelectedImageNum;
 
2251
 lImage := Sender as TImage;
 
2252
         lX := X; lY := Y;
 
2253
         ScaleScrn2BMP(lX,lY,lImage);
 
2254
if (gSelectOrigin.X > 0)  then begin
 
2255
         sortLTRB(gSelectRect.Left,gSelectRect.Top,gSelectRect.Right,gSelectRect.Bottom);
 
2256
         ShowFocusRect(gSelectRect);
 
2257
         gSelectOrigin.X := -1;
 
2258
         if (EllipseBtn.Down) then
 
2259
                DrawEllipse(Limage,gSelectRect,Shift,lPanel)
 
2260
         else begin
 
2261
                AdjustContrastRectangle(lImage);
 
2262
                exit;
 
2263
         end;
 
2264
end;
 
2265
 
 
2266
         if  ((PenBtn.Down) or (ClosedPenBtn.Down)) and (gMouseDownX > 0) then begin
 
2267
                ScaleBMP2Draw(gBGImg.VOIInvZoom, gMouseDownX,gMouseDownY,lPanel,lImage);
 
2268
                //next: draw single pxiel if user clicks on image without moving the mouse
 
2269
                //DrawImg2.Canvas.Pixels[gMouseDownX,gMouseDownY] := DrawImg2.Canvas.Pen.Color;
 
2270
                if  (ClosedPenBtn.Down) then begin
 
2271
                    if lImage.Canvas.Pen.Color = clBlack then
 
2272
                        LineToFX8(gDrawImg,gMouseDownX,gMouseDownY,0)
 
2273
                    else
 
2274
                        LineToFX8(gDrawImg,gMouseDownX,gMouseDownY,kVOI8Bit);
 
2275
                end;
 
2276
         end;
 
2277
 
 
2278
         gMouseDownX := -1; //disable draws
 
2279
         //if DrawToolSelected then
 
2280
         if DrawToolSelected  and (not (ssAlt in Shift)) then
 
2281
                ReadScrnVOI (lImage);
 
2282
end; //PGImageMouseUp
 
2283
 
 
2284
 
 
2285
procedure TImgForm.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
 
2286
  MousePos: TPoint; var Handled: Boolean);
 
2287
begin
 
2288
  Case SelectedImageNum of
 
2289
          3: DecViewEdit(YViewEdit);
 
2290
      2: DecViewEdit(XViewEdit);
 
2291
      else DecViewEdit(ZViewEdit);
 
2292
  end;
 
2293
end;
 
2294
 
 
2295
procedure TImgForm.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
 
2296
  MousePos: TPoint; var Handled: Boolean);
 
2297
begin
 
2298
  Case SelectedImageNum of
 
2299
          3: IncViewEdit(YViewEdit);
 
2300
          2: IncViewEdit(XViewEdit);
 
2301
          else IncViewEdit(ZViewEdit);
 
2302
  end;
 
2303
end;
 
2304
 
 
2305
procedure TImgForm.ZoomDropSelect(Sender: TObject);
 
2306
begin
 
2307
         gBGImg.ZoomPct := (ZoomDrop.ItemIndex-1)*100;
 
2308
         RefreshImagesTimer.Enabled := true;
 
2309
end;
 
2310
 
 
2311
procedure TImgForm.ColorBarBtnMouseDown(Sender: TObject;
 
2312
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
 
2313
  var lLTRB,lLayer: integer;
 
2314
  lImage: TImage;
 
2315
begin
 
2316
         if (ssAlt in Shift) then begin
 
2317
                //lImage := SelectedImage;
 
2318
                lLayer := ActiveLayer;
 
2319
                DrawHistogram(gMRIcroOverlay[lLayer],HistogramForm.HistoImage{lImage});
 
2320
                HistogramForm.Caption := 'Histogram: '+extractfilename(gMRIcroOverlay[lLayer].HdrFileName);
 
2321
                HistogramForm.show;
 
2322
                if (ssCtrl in Shift) then
 
2323
                   TextReportHisto(gMRIcroOverlay[lLayer]);
 
2324
                exit;
 
2325
         end;
 
2326
         lLTRB := 1;
 
2327
     if  (ssRight in Shift) then
 
2328
           lLTRB := lLTRB + 1;
 
2329
     if (ssCtrl in Shift) then
 
2330
           lLTRB := lLTRB + 2;
 
2331
         lImage := SelectedImage;
 
2332
         intenBar(lImage,gMRIcroOverlay[ActiveLayer],lLTRB,0,0);
 
2333
end;
 
2334
 
 
2335
 
 
2336
 
 
2337
 
 
2338
 
 
2339
procedure TImgForm.XBarBtnClick(Sender: TObject);
 
2340
begin
 
2341
  gBGImg.XBarVisible := XBarBtn.Down;
 
2342
  RefreshImagesTimer.Enabled := true;
 
2343
end;
 
2344
 
 
2345
procedure RepositionOrigin;
 
2346
begin
 
2347
     gBGImg.ScrnOri[1] := ImgForm.XviewEdit.value;
 
2348
     gBGImg.ScrnOri[2] := ImgForm.YviewEdit.value;
 
2349
     gBGImg.ScrnOri[3] := ImgForm.ZviewEdit.value;
 
2350
end;
 
2351
 
 
2352
procedure TImgForm.XBarBtnMouseUp(Sender: TObject; Button: TMouseButton;
 
2353
          Shift: TShiftState; X, Y: Integer);
 
2354
begin
 
2355
 
 
2356
end;
 
2357
   
 
2358
procedure TImgForm.XBarBtnMouseDown(Sender: TObject; Button: TMouseButton;
 
2359
  Shift: TShiftState; X, Y: Integer);
 
2360
label 555;
 
2361
begin
 
2362
         if not (ssRight in shift) then exit;
 
2363
         if (ssShift in Shift) then begin
 
2364
             RepositionOrigin;
 
2365
             goto 555;
 
2366
         end;
 
2367
         if (ssAlt in Shift) and (ssCtrl in Shift) then begin
 
2368
                inc(gBGImg.FontSize,2);
 
2369
                if gBGImg.FontSize > 24 then
 
2370
                        gBGImg.FontSize := 8;
 
2371
                goto 555;
 
2372
         end;
 
2373
         if (ssAlt in Shift) then begin
 
2374
                inc(gBGImg.XBarThick,2);
 
2375
                if gBGImg.XBarThick > 10 then
 
2376
                        gBGImg.XBarThick := 1;
 
2377
                goto 555;
 
2378
         end;
 
2379
         if (ssCtrl in Shift) then begin
 
2380
                ColorDialog1.Color := gBGImg.XBarClr;
 
2381
                if not ColorDialog1.Execute then exit;
 
2382
                gBGImg.XBarClr := ColorDialog1.Color;
 
2383
                goto 555;
 
2384
         end;
 
2385
         inc(gBGImg.XBarGap);
 
2386
         if gBGImg.XBarGap > 10 then
 
2387
                gBGImg.XBarGap := 0;
 
2388
555:
 
2389
    RefreshImagesTimer.Enabled := true;
 
2390
    if MultiSliceForm.Visible then
 
2391
       MultiSliceForm.CreateMultiSlice;
 
2392
end; //XBarBtnMouseDown
 
2393
 
 
2394
 
 
2395
 
 
2396
procedure TImgForm.RefreshImagesTimerTimer(Sender: TObject);
 
2397
begin
 
2398
         RefreshImagesTimer.Enabled := false;
 
2399
         RefreshImages;
 
2400
  UpdateStatusLabel;
 
2401
 
 
2402
 
 
2403
end;
 
2404
 
 
2405
procedure TImgForm.ImgPanelClick(Sender: TObject);
 
2406
begin
 
2407
         SelectPanel((Sender as TScrollBox).tag);
 
2408
end;
 
2409
 
 
2410
procedure TImgForm.MagnifyMenuItemClick(Sender: TObject);
 
2411
begin
 
2412
  (*if MagnifyPanel.Height < 20 then //Height constrained by Y
 
2413
         MagnifyPanel.Height := 128
 
2414
  else
 
2415
          MagnifyPanel.Height := MagnifyPanel.Constraints.MinHeight;  *)
 
2416
end;
 
2417
 
 
2418
procedure TImgForm.CloseImagesClick(Sender: TObject);
 
2419
var
 
2420
        lC: integer;
 
2421
begin
 
2422
        CloseVOIClick(nil);
 
2423
        FreeUndoVol;
 
2424
        for lC := 0 to knMaxOverlay do //background, all overlays, VOI
 
2425
                FreeImgMemory(gMRIcroOverlay[lC]);
 
2426
        gBGImg.VOIUndoSlice := 0;
 
2427
 
 
2428
        //next- set layers menu
 
2429
        LayerDrop.Items.Clear;
 
2430
        LayerDrop.Items.Add('Background');
 
2431
   {$IFNDEF FPC}
 
2432
    LayerDrop.SetItemIndex(0);
 
2433
  {$ELSE}
 
2434
    LayerDrop.ItemIndex :=(0);
 
2435
  {$ENDIF}
 
2436
        LayerDropSelect(nil);
 
2437
end;
 
2438
 
 
2439
procedure TImgForm.OverlayOpenCore (var lFilename: string; lOverlayNum: integer);
 
2440
begin
 
2441
     if not HdrForm.OpenAndDisplayHdr(lFilename,gMRIcroOverlay[lOverlayNum]) then exit;
 
2442
     //if not OpenImg(gBGImg,gMRIcroOverlay[lOverlayNum],false,false,false) then exit;
 
2443
         //if (ssShift in KeyDataToShiftState(vk_Shift)) then begin
 
2444
         //    if not OpenImg(gBGImg,gMRIcroOverlay[lOverlayNum],false,false,false,not gBGImg.ResliceOnLoad,false) then exit;
 
2445
         //end else
 
2446
             if not OpenImg(gBGImg,gMRIcroOverlay[lOverlayNum],false,false,false,gBGImg.ResliceOnLoad,false) then exit;
 
2447
     ImgForm.UpdateLayerMenu;
 
2448
     ImgForm.RefreshImagesTimer.Enabled := true;
 
2449
end;
 
2450
 
 
2451
procedure TImgForm.LoadOverlay (lFilename: string);
 
2452
var
 
2453
lOverlay,lC: integer;
 
2454
begin
 
2455
         lOverlay := 0;
 
2456
         for lC := 1 to (knMaxOverlay-1) do //-1: save final overlay for VOI
 
2457
                  if (lOverlay = 0) and (gMRIcroOverlay[lC].ImgBufferItems = 0) then
 
2458
                        lOverlay := lC;
 
2459
         if lOverlay = 0 then begin
 
2460
                showmessage('Unable to add an overlay. You have loaded the maximum number of overlays.');
 
2461
                exit;
 
2462
         end;
 
2463
         OverlayOpenCore ( lFilename, lOverlay);
 
2464
end;
 
2465
 
 
2466
procedure  TImgForm.LoadOverlayIncludingRGB (lFilename: string);
 
2467
var
 
2468
lOverlay,lC: integer;
 
2469
begin
 
2470
         lOverlay := 0;
 
2471
         for lC := 1 to (knMaxOverlay-1) do //-1: save final overlay for VOI
 
2472
                  if (lOverlay = 0) and (gMRIcroOverlay[lC].ImgBufferItems = 0) then
 
2473
                        lOverlay := lC;
 
2474
         if lOverlay = 0 then begin
 
2475
                showmessage('Unable to add an overlay. You have loaded the maximum number of overlays.');
 
2476
                exit;
 
2477
         end;
 
2478
         OverlayOpenCore ( lFilename, lOverlay);
 
2479
   if (gMRIcroOverlay[lOverlay].NIFTIhdr.datatype = kDT_RGB) then begin
 
2480
    OverlayOpenCore ( lFilename, lOverlay+1);
 
2481
    OverlayOpenCore ( lFilename, lOverlay+2);
 
2482
    OverlayAdditive.click;
 
2483
   end;
 
2484
end;
 
2485
 
 
2486
procedure TImgForm.BrainMask1Click(Sender: TObject);
 
2487
var
 
2488
   lInc: integer;
 
2489
begin
 
2490
        if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 1 then begin
 
2491
                showmessage('Please load a background image for rescaling.');
 
2492
                exit;
 
2493
        end;
 
2494
        //lImgSamples := gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems;
 
2495
        for lInc := 1 to gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems do
 
2496
            if gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc] <> 0 then
 
2497
               gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc] := 1;
 
2498
        SaveAsVOIorNIFTI(gMRIcroOverlay[kBGOverlayNum].ScrnBuffer,gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems,1,1,true,gMRIcroOverlay[kBGOverlayNum].NiftiHdr,gMRIcroOverlay[kVOIOverlayNum].HdrFileName);
 
2499
end;
 
2500
 
 
2501
procedure TImgForm.ControlPanelDragDrop(Sender, Source: TObject; X, Y: Integer);
 
2502
begin
 
2503
 
 
2504
end;
 
2505
 
 
2506
procedure DescribeVOIonLabels (lOverlayNum: integer; lShowFilename: boolean);
 
2507
var
 
2508
   lLocalMax,lLocalSum : HistoDoubleRA;
 
2509
   l16Buf : SmallIntP;
 
2510
   l32Buf : SingleP;
 
2511
   l8Buf: byteP;
 
2512
   lInten: double;
 
2513
   lXmm,lYmm,lZmm: single;
 
2514
   lHisto,lRegionVol,lLocalMaxPos: HistoRA;
 
2515
   lInc,lRegion: Integer;
 
2516
   lLabelStr: string;
 
2517
   lVOI: boolean;
 
2518
   lLabelStr20 : Array[0..kHistoBins] of kstr20;
 
2519
begin
 
2520
     lInten := 0;//just to hide compiler hint...
 
2521
     if (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP = 2) and ('ratlas.nii.gz' = (extractfilename( gMRIcroOverlay[kBGOverlayNum].HdrFileName))) then begin
 
2522
        // specific for PCDescribeVOIonLabelsRAT(lOverlayNum,lShowFilename);
 
2523
        exit;
 
2524
     end;
 
2525
     if (gMRIcroOverlay[lOverlayNum].ScrnBufferItems <> gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems) or (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP <> 1) or (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 2) then
 
2526
        exit;
 
2527
     TextForm.Memo1.Lines.add(' Custom Region Analysis');
 
2528
     TextForm.Memo1.Lines.add(' For Speculative Brodmann Map: 0=not cortical and 48=no Brodmann label');
 
2529
     lVOI := IsVOIROIExt(gMRIcroOverlay[lOverlayNum].HdrFileName);
 
2530
     if (not lVOI) and (lOverlayNum = kVOIOverlayNum) then
 
2531
        lVOI := true;
 
2532
     //next describe format
 
2533
     if lShowfilename then
 
2534
        lLabelStr := ' Filename,'
 
2535
     else
 
2536
         lLabelStr := ' ';
 
2537
     if lVOI then //intensity min/max position are not important
 
2538
        TextForm.Memo1.Lines.add(lLabelStr+'Area,N>0,%N>0')
 
2539
     else
 
2540
         TextForm.Memo1.Lines.add(lLabelStr+'Area,N>0,%N>0,Sum>0,Mean>0,Max,MaxX,MaxY,MaxZ');
 
2541
   //next initialize
 
2542
   if lShowFilename then
 
2543
      lLabelStr := gMRIcroOverlay[lOverlayNum].HdrFileName+','
 
2544
   else
 
2545
       lLabelStr := '';
 
2546
     for lInc := 0 to kHistoBins do begin
 
2547
         lHisto[lInc] := 0;
 
2548
         lLocalMax[lInc] := 0;
 
2549
         lLocalSum[lInc] := 0;
 
2550
         lRegionVol[lInc] := 0;
 
2551
         if (gMRIcroOverlay[kBGOverlayNum].UsesCustomPalette) then
 
2552
            lLabelStr20[lInc] := gBGImg.LabelStr20[lInc]
 
2553
         else
 
2554
             lLabelStr20[lInc] := inttostr(lInc);
 
2555
     end;
 
2556
     for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do
 
2557
         if gMRIcroOverlay[lOverlayNum].ScrnBuffer^[lInc] > 0 then
 
2558
            inc(lHisto[gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc]]);
 
2559
     //local max start
 
2560
     l32Buf := SingleP(gMRIcroOverlay[lOverlayNum].ImgBuffer );
 
2561
     l16Buf := SmallIntP(gMRIcroOverlay[lOverlayNum].ImgBuffer );
 
2562
     //NEXT if..else July07 - ROIs only use screen buffer, not imgbuffer...
 
2563
     if gMRIcroOverlay[lOverlayNum].ScrnBufferItems = gMRIcroOverlay[lOverlayNum].ImgBufferItems then
 
2564
        l8Buf := gMRIcroOverlay[lOverlayNum].ImgBuffer
 
2565
     else
 
2566
         l8Buf := gMRIcroOverlay[lOverlayNum].ScrnBuffer;
 
2567
     for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do begin
 
2568
         if (gMRIcroOverlay[lOverlayNum].ImgBufferBPP  = 4) then
 
2569
           lInten := l32Buf^[lInc]
 
2570
         else if (gMRIcroOverlay[lOverlayNum].ImgBufferBPP  = 2) then
 
2571
              lInten := l16Buf^[lInc]
 
2572
         else if gMRIcroOverlay[lOverlayNum].ImgBufferBPP  = 1 then
 
2573
              lInten := l8Buf^[lInc];//July07
 
2574
         lRegion := gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc];
 
2575
         if lInten > 0 then
 
2576
            lLocalSum[lRegion] := lLocalSum[lRegion]+lInten;
 
2577
         if  lInten > lLocalMax[lRegion] then begin
 
2578
             lLocalMax[lRegion] := lInten;//intensity
 
2579
             lLocalMaxPos[lRegion] := lInc;//location
 
2580
         end;
 
2581
         inc(lRegionVol[lRegion]);
 
2582
     end;
 
2583
     for lInc := 0 to kHistoBins do  begin
 
2584
         if (not lVOI) and (lLocalMax[lInc] > 0) then begin
 
2585
            lLocalMax[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalMax[lInc]);
 
2586
            lLocalSum[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalSum[lInc]);
 
2587
            ImgPosToMM(lLocalMaxPos[lInc], lXmm,lYmm,lZmm);
 
2588
            TextForm.Memo1.Lines.Add(lLabelStr+ lLabelStr20[lInc] + ', ' + inttostr(lHisto[lInc])+','+floattostr( lHisto[lInc]/lRegionVol[lInc])
 
2589
               +','+floattostr( lLocalSum[lInc])+','+floattostr( lLocalSum[lInc]/lRegionVol[lInc]) //Sum>0, mean>0
 
2590
               +', ' + floattostr(lLocalMax[lInc])+','+floattostr(lXmm)+','+floattostr(lYmm)+','+floattostr(lZmm) );
 
2591
         end else if (lHisto[lInc] > 0) {necessarily also and (lRegionVol[lInc] > 0)} then
 
2592
                        TextForm.Memo1.Lines.Add(lLabelStr+ lLabelStr20[lInc] + ', ' + inttostr(lHisto[lInc])+','+floattostr( lHisto[lInc]/lRegionVol[lInc])) ;
 
2593
     end; //for each row
 
2594
end;
 
2595
 
 
2596
procedure ShowDescriptive (lOverlayNum: integer; lShowFilename: boolean);
 
2597
var
 
2598
        lROIVol: array [1..3] of integer;
 
2599
        lInc: integer;
 
2600
        lCenterOfMass,lROISum,lROISumSqr,lROImin,lROImax:array [1..3] of double;
 
2601
        lCC,lVal,lSD,lROImean: double;
 
2602
        lLabelStr,lStr: string;
 
2603
procedure  AddVal( lRA: integer);
 
2604
begin
 
2605
                        inc(lROIVol[lRA]);
 
2606
                        lROISum[lRA] := lROISum[lRA]+lVal;
 
2607
                        lROISumSqr[lRA] := lROISumSqr[lRA] + sqr(lVal);
 
2608
                        if lVal > lROImax[lRA] then
 
2609
                                lROImax[lRA] := lVal;
 
2610
                        if lVal < lROImin[lRA] then
 
2611
                                lROImin[lRA] := lVal;
 
2612
end; //proc AddVal
 
2613
begin //proc ShowDescript
 
2614
   if gMRIcroOverlay[lOverlayNum].ScrnBufferItems <> gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems then
 
2615
      exit;
 
2616
 
 
2617
   if lShowFilename then
 
2618
      lLabelStr := gMRIcroOverlay[lOverlayNum].HdrFileName
 
2619
   else
 
2620
       lLabelStr := '';
 
2621
   for lInc := 1 to 3 do begin
 
2622
                lROIVol[lInc] := 0;
 
2623
                lROISum[lInc] := 0;
 
2624
                lROISumSqr[lInc] := 0;
 
2625
                lROImin[lInc] := maxint;
 
2626
                lROImax[lInc] := -maxint;
 
2627
   end;
 
2628
        for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do begin
 
2629
                if gMRIcroOverlay[lOverlayNum].ScrnBuffer^[lInc] > 0 then begin
 
2630
      //fx(lInc);
 
2631
                        lVal := RawBGIntensity(lInc);
 
2632
                        AddVal(1);
 
2633
                        if lVal <> 0 then
 
2634
                                AddVal(2);
 
2635
                        if lVal > 0 then
 
2636
                                AddVal(3);
 
2637
                end; //if VOI voxel
 
2638
        end; //for each voxel
 
2639
        //next - compute StDev
 
2640
        //compute descriptives for each set of values
 
2641
           if lOverlayNum =  kVOIOverlayNum then
 
2642
              lStr :=  'VOI notes '
 
2643
           else
 
2644
               lStr := 'Overlay #'+inttostr(lOverlayNum);
 
2645
        if not lShowFilename then begin
 
2646
           TextForm.Memo1.Lines.Add(lStr+'  '+gMRIcroOverlay[lOverlayNum].HdrFileName);
 
2647
        end;
 
2648
        //TextForm.Memo1.Lines.Add('CoM');
 
2649
        if  CenterOfMass (lOverlayNum, lCenterOfMass[1],lCenterOfMass[2],lCenterOfMass[3]) > 0 then
 
2650
            TextForm.Memo1.Lines.Add(' '+lLabelStr+' Center of mass XYZ '+RealToStr(lCenterOfMass[1],2)+'x'+RealToStr(lCenterOfMass[2],2)+'x'+RealToStr(lCenterOfMass[3],2));
 
2651
        for lInc := 1 to 3 do begin
 
2652
                if lROIVol[lInc] > 1 then begin
 
2653
                        lSD := (lROISumSqr[lInc] - ((Sqr(lROISum[lInc]))/lROIVol[lInc]));
 
2654
                        if  (lSD > 0) then
 
2655
                                lSD :=  Sqrt ( lSD/(lROIVol[lInc]-1))
 
2656
                        else
 
2657
                                lSD := 0;
 
2658
                end else
 
2659
                        lSD := 0;
 
2660
                //next compute mean
 
2661
                if lROIVol[lInc] > 0 then begin
 
2662
                        lROImean := lROISum[lInc]/lROIVol[lInc];
 
2663
                        //next - calibrate values
 
2664
                        lROImin[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[kBGOverlayNum],lROImin[lInc]);
 
2665
                        lROIMean := Raw2ScaledIntensity (gMRIcroOverlay[kBGOverlayNum],lROIMean);
 
2666
                        lROImax[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[kBGOverlayNum],lROImax[lInc]);
 
2667
                        lSD := Raw2ScaledIntensity (gMRIcroOverlay[kBGOverlayNum],lSD);
 
2668
 
 
2669
                end else begin //2/2008
 
2670
                     lROImin[lInc] := 0;
 
2671
                     lROImax[lInc] := 0;
 
2672
                     lROImean := 0;
 
2673
                end;
 
2674
                lcc := ((lROIVol[lInc]/1000)*gBGImg.ScrnMM[1]*gBGImg.ScrnMM[2]*gBGImg.ScrnMM[3]);
 
2675
                case lInc of
 
2676
                        3: lStr := 'VOI  >0 ';
 
2677
                        2: lStr := 'VOI <>0 ';
 
2678
                        else lStr := 'VOI     ';
 
2679
                end;
 
2680
                lStr := lStr+' n=min/mean/max=SD: '+inttostr(round(lROIVol[lInc]))+'['+RealToStr(lCC,2)+'cc]='+RealToStr(lROIMin[lInc],4)+'/'+realToStr(lROIMean,4)+'/'+realToStr(lROIMax[lInc],4)+'='+realtostr(lSD,4);
 
2681
                TextForm.Memo1.Lines.Add(lLabelStr+ lStr);
 
2682
        end;
 
2683
        //June07 if (gMRIcroOverlay[kBGOverlayNum].UsesCustomPalette) or (lShowFilename) then
 
2684
                DescribeVOIonLabels(lOverlayNum,lShowfilename);
 
2685
        TextForm.Memo1.Lines.Add('');
 
2686
        ImgForm.SaveDialog1.Filename := ExtractFileDirWithPathDelim(gMRIcroOverlay[lOverlayNum].HdrFileName)+'desc.csv';
 
2687
end;
 
2688
 
 
2689
 
 
2690
procedure TImgForm.BatchROImean1Click(Sender: TObject);
 
2691
var
 
2692
        lInc,lNumberofFiles: integer;
 
2693
        lFilename:string;
 
2694
begin
 
2695
        if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 1 then begin
 
2696
                showmessage('Please load a background image for rescaling.');
 
2697
                exit;
 
2698
        end;
 
2699
        for lInc := 1 to (knMaxOverlay-1) do
 
2700
            FreeImgMemory(gMRIcroOverlay[lInc]);
 
2701
        UpdateLayerMenu;
 
2702
        if not OpenDialogExecute(kImgFilter,'Select images you wish to analyze',true) then exit;
 
2703
        lNumberofFiles:= HdrForm.OpenHdrDlg.Files.Count;
 
2704
        if  lNumberofFiles < 1 then
 
2705
                exit;
 
2706
        TextForm.Memo1.Lines.Clear;
 
2707
        for lInc:= 1 to lNumberofFiles do begin
 
2708
                lFilename := HdrForm.OpenHdrDlg.Files[lInc-1];
 
2709
                OverlayOpenCore ( lFilename, 2);
 
2710
                ShowDescriptive(2,true);
 
2711
                //LayerDrop.SetItemIndex(LayerDrop.Items.Count-1);
 
2712
                //LayerDropSelect(nil);
 
2713
        end;
 
2714
        FreeImgMemory(gMRIcroOverlay[2]);
 
2715
        UpdateLayerMenu;
 
2716
        //SaveDialog1.Filename := ExtractFileDirWithPathDelim(HdrForm.OpenHdrDlg.Files[0])+'desc.csv';
 
2717
        TextForm.Show;
 
2718
end;
 
2719
 
 
2720
procedure TImgForm.Batchprobmaps1Click(Sender: TObject);
 
2721
begin
 
2722
       BatchVOI;
 
2723
end;
 
2724
 
 
2725
procedure TImgForm.Batchclusterprobmaps1Batchclusterprobmaps1ClickClick(
 
2726
  Sender: TObject);
 
2727
begin
 
2728
       BatchCluster;
 
2729
end;
 
2730
 
 
2731
procedure TImgForm.GenerateSPM5maskslesions1Click(Sender: TObject);
 
2732
begin
 
2733
     VOISmoothForm.SmoothVOI_SPM5masks;
 
2734
end;
 
2735
 
 
2736
 
 
2737
procedure TImgForm.OverlayOpenClick(Sender: TObject);
 
2738
var
 
2739
        lFilename: string;
 
2740
        lOverlay,lInc: integer;
 
2741
begin
 
2742
        if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 1 then begin
 
2743
                showmessage('Please load a background image (''File''/''Open'') before adding an overlay.');
 
2744
                exit;
 
2745
        end;
 
2746
        if not OpenDialogExecute(kImgFilter,'Select overlay image[s]',true) then exit;
 
2747
  if HdrForm.OpenHdrDlg.Files.Count < 1 then
 
2748
    exit;
 
2749
  for lInc := 1 to HdrForm.OpenHdrDlg.Files.Count do begin //vcx
 
2750
    lFilename := HdrForm.OpenHdrDlg.Files[lInc-1];
 
2751
    LoadOverlayIncludingRGB{LoadOverlay}(lFilename);
 
2752
    LayerDrop.ItemIndex := (LayerDrop.Items.Count-1);
 
2753
    {$IFNDEF FPC}
 
2754
        LayerDrop.SetItemIndex(LayerDrop.Items.Count-1);
 
2755
    {$ELSE}
 
2756
        LayerDrop.ItemIndex :=(LayerDrop.Items.Count-1);
 
2757
    {$ENDIF}
 
2758
  end;
 
2759
 
 
2760
 
 
2761
(*      //HdrForm.OpenHdrDlg.Filter := kImgFilter;
 
2762
        // if not HdrForm.OpenHdrDlg.Execute then exit;
 
2763
        if not OpenDialogExecute(kImgFilter,'Select overlay image',false) then exit;
 
2764
         lOverlay := 0;
 
2765
         for lC := 1 to (knMaxOverlay-1) do //-1: save final overlay for VOI
 
2766
                  if (lOverlay = 0) and (gMRIcroOverlay[lC].ImgBufferItems = 0) then
 
2767
                        lOverlay := lC;
 
2768
         if lOverlay = 0 then begin
 
2769
                showmessage('Unable to add an overlay. You have loaded the maximum number of overlays.');
 
2770
                exit;
 
2771
         end;
 
2772
         lFilename := HdrForm.OpenHdrDlg.Filename;
 
2773
         OverlayOpenCore ( lFilename, lOverlay);
 
2774
    *)
 
2775
          LayerDropSelect(nil);
 
2776
end; //OverlayOpenClick
 
2777
 
 
2778
procedure TImgForm.BGtrans100Click(Sender: TObject);
 
2779
begin
 
2780
        (sender as TMenuItem).checked := true;
 
2781
        gBGImg.BGTransPct := (sender as TMenuItem).tag;
 
2782
        RefreshImagesTimer.Enabled := true;
 
2783
end;
 
2784
 
 
2785
procedure TImgForm.OverlayTransClick(Sender: TObject);
 
2786
begin
 
2787
        (sender as TMenuItem).checked := true;
 
2788
        gBGImg.OverlayTransPct := (sender as TMenuItem).tag;
 
2789
        RefreshImagesTimer.Enabled := true;
 
2790
end;
 
2791
 
 
2792
procedure TImgForm.LayerDropSelect(Sender: TObject);
 
2793
var
 
2794
        lLayer: integer;
 
2795
begin
 
2796
         lLayer := ActiveLayer;
 
2797
         MaxWindowEdit.Value := gMRIcroOverlay[lLayer].WindowScaledMax;
 
2798
         MinWindowEdit.Value := gMRIcroOverlay[lLayer].WindowScaledMin;
 
2799
         if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems=0 then exit;
 
2800
  {$IFNDEF FPC}
 
2801
         LUTdrop.SetItemIndex(gMRIcroOverlay[lLayer].LUTindex);
 
2802
  {$ELSE}
 
2803
         LUTdrop.ItemIndex :=(gMRIcroOverlay[lLayer].LUTindex);
 
2804
  {$ENDIF}
 
2805
         //LUTinvertBtn.down := gMRIcroOverlay[lLayer].LUTinvert;
 
2806
         LutFromZeroBtn.down := gMRIcroOverlay[lLayer].LutFromZero;
 
2807
end;
 
2808
 
 
2809
procedure TImgForm.UpdateLayerMenu;
 
2810
var
 
2811
        lStrings: TStringList;
 
2812
        lPos,lLayer:integer;
 
2813
begin
 
2814
        lStrings := TStringList.Create;
 
2815
        lStrings.Add('Background');
 
2816
        lLayer := 0;
 
2817
        for lPos := 1 to (knMaxOverlay-1) do //-1 as max overlay is VOI
 
2818
          if (gMRIcroOverlay[lPos].ImgBufferItems > 0) then begin
 
2819
                   lStrings.Add(ParseFileName(ExtractFileName(gMRIcroOverlay[lPos].HdrFileName)));
 
2820
                   inc(lLayer);
 
2821
                   LUTdropLoad(lLayer);
 
2822
          end;
 
2823
        LayerDrop.Items := lStrings;
 
2824
 
 
2825
   {$IFNDEF FPC}
 
2826
        if LayerDrop.ItemIndex >= LayerDrop.Items.Count then
 
2827
                LayerDrop.SetItemIndex(LayerDrop.Items.Count-1);
 
2828
  {$ELSE}
 
2829
        if LayerDrop.ItemIndex >= LayerDrop.Items.Count then
 
2830
                LayerDrop.ItemIndex :=(LayerDrop.Items.Count-1);
 
2831
    {$ENDIF}
 
2832
 
 
2833
        LayerDropSelect(nil);
 
2834
        lStrings.Free;
 
2835
end;
 
2836
 
 
2837
procedure TImgForm.CloseOverlayImgClick(Sender: TObject);
 
2838
var
 
2839
        lOverlay: integer;
 
2840
begin
 
2841
  for lOverlay := 1 to (knMaxOverlay-1) do
 
2842
        FreeImgMemory(gMRIcroOverlay[lOverlay]);
 
2843
  UpdateLayerMenu;
 
2844
  RefreshImagesTimer.Enabled := true;
 
2845
end;
 
2846
 
 
2847
procedure TImgForm.LUTdropLoad(var lLayer: integer);
 
2848
var
 
2849
   lStr: string;
 
2850
begin
 
2851
         if gMRIcroOverlay[lLayer].UsesCustomPalette then begin
 
2852
                exit;
 
2853
         end;
 
2854
         //gMRIcroOverlay[lLayer].LUTindex := LUTdrop.ItemIndex;
 
2855
         if gMRIcroOverlay[lLayer].LUTindex < knAutoLUT then begin
 
2856
                LoadMonochromeLUT(gMRIcroOverlay[lLayer].LUTindex,gBGImg,gMRIcroOverlay[lLayer]);
 
2857
                RefreshImagesTimer.Enabled := true;
 
2858
                exit;
 
2859
         end; //if B&W lut
 
2860
         lStr := gColorSchemeDir+pathdelim+LUTdrop.Items.Strings[gMRIcroOverlay[lLayer].LUTindex]+'.lut';
 
2861
         if not FileExistsEX(lStr) then
 
2862
                showmessage('Can not find '+lStr);
 
2863
         LoadColorScheme(lStr, gMRIcroOverlay[lLayer]);
 
2864
         RefreshImagesTimer.Enabled := true;
 
2865
end;
 
2866
 
 
2867
procedure TImgForm.LUTdropSelect(Sender: TObject);
 
2868
var
 
2869
   lLayer: integer;
 
2870
begin
 
2871
         lLayer := ActiveLayer;
 
2872
         gMRIcroOverlay[lLayer].LUTindex := LUTdrop.ItemIndex;
 
2873
         //gMRIcroOverlay[lLayer].LUTinvert := LUTinvertBtn.down;
 
2874
         //gMRIcroOverlay[lLayer].LutFromZero := LutFromZeroBtn.down;
 
2875
         LUTdropLoad(lLayer);
 
2876
         //RescaleImagesTimer.Enabled := true;
 
2877
end; //proc LUTdropSelect
 
2878
 
 
2879
 
 
2880
 
 
2881
procedure TImgForm.AutoContrastBtnClick(Sender: TObject);
 
2882
var
 
2883
        lLayer: integer;
 
2884
begin
 
2885
         lLayer := ActiveLayer;
 
2886
        MinWindowEdit.Value := raw2ScaledIntensity(gMRIcroOverlay[lLayer], gMRIcroOverlay[lLayer].AutoBalMinUnscaled);
 
2887
        MaxWindowEdit.Value := raw2ScaledIntensity(gMRIcroOverlay[lLayer],gMRIcroOverlay[lLayer].AutoBalMaxUnscaled);{}
 
2888
 
 
2889
        gMRIcroOverlay[lLayer].WindowScaledMin := MinWindowEdit.Value;
 
2890
        gMRIcroOverlay[lLayer].WindowScaledMax := MaxWindowEdit.Value;
 
2891
        RescaleImgIntensity(gBGImg,gMRIcroOverlay[lLayer],lLayer);
 
2892
 
 
2893
        RefreshImagesTimer.Enabled := true;
 
2894
end;
 
2895
 
 
2896
procedure TImgForm.MinContrastWindowEditChange(Sender: TObject);
 
2897
var
 
2898
        lLayer: integer;
 
2899
begin
 
2900
        lLayer := ActiveLayer;
 
2901
        if gMRIcroOverlay[lLayer].WindowScaledMin = MinWindowEdit.Value then exit;
 
2902
        gMRIcroOverlay[lLayer].WindowScaledMin := MinWindowEdit.Value;
 
2903
        RescaleImagesTimer.Enabled := true;
 
2904
end;
 
2905
 
 
2906
procedure TImgForm.MaxContrastWindowEditChange(Sender: TObject);
 
2907
var
 
2908
        lLayer: integer;
 
2909
begin
 
2910
         lLayer := ActiveLayer;
 
2911
         if gMRIcroOverlay[lLayer].WindowScaledMax = MaxWindowEdit.Value then exit;
 
2912
         gMRIcroOverlay[lLayer].WindowScaledMax := MaxWindowEdit.Value;
 
2913
        RescaleImagesTimer.Enabled := true;
 
2914
end;
 
2915
 
 
2916
procedure TImgForm.OverlaySmoothMenuClick(Sender: TObject);
 
2917
var
 
2918
        lC: integer;
 
2919
begin
 
2920
         if Sender = nil then begin
 
2921
                gBGImg.OverlaySmooth := OverlaySmoothMenu.Checked;
 
2922
                 exit;
 
2923
         end;
 
2924
         OverlaySmoothMenu.Checked := not OverlaySmoothMenu.Checked;
 
2925
         gBGImg.OverlaySmooth := OverlaySmoothMenu.Checked;
 
2926
         for lC := 1 to knMaxOverlay do
 
2927
                if gMRIcroOverlay[lC].ScrnBufferItems > 0 then
 
2928
                RescaleImgIntensity(gBGImg,gMRIcroOverlay[lC],lC);
 
2929
        RefreshImagesTimer.Enabled := true;
 
2930
end;
 
2931
 
 
2932
procedure TImgForm.ShowRenderClick(Sender: TObject);
 
2933
begin
 
2934
        RenderForm.Show;
 
2935
 //RenderForm.BringToFront;
 
2936
end;
 
2937
 
 
2938
procedure TImgForm.PenBtnClick(Sender: TObject);
 
2939
begin
 
2940
        RefreshImagesTimer.Enabled := true;
 
2941
end;
 
2942
 
 
2943
procedure OpenMRIcroROI (lFilename: string);
 
2944
const
 
2945
                  kMax12bit = 4095;
 
2946
         kMax16bit = (256*256)-1;
 
2947
         kMax15bit = kMax16bit shr 1;
 
2948
         //kMax20bit = (16*256*256)-1;
 
2949
        // k20v16bit = kMax20bit - kMax16bit;
 
2950
        //kMaxRuns = 10000;
 
2951
        //kMaxFile =  65536;
 
2952
         //k16v12bit = kMax16bit - kMax12bit;
 
2953
var
 
2954
        lFile32bitItems,lFileSz,lFilePos,lSliceSz,lZ,lRunsOnSlice,
 
2955
        lRunLength,lRun,lRunOffset,lOutputSliceOffset,lRunPos: integer;
 
2956
        lROIformatRA: LongIntp;
 
2957
        lF: File;
 
2958
        lBigFormat: boolean;
 
2959
begin
 
2960
        lFileSz := FSize(lFilename);
 
2961
        if (lFileSz < 1) or ((lFileSz mod 4) <> 0) then begin
 
2962
                showmessage('Unable to open ROI: file size should be divisible by 4.');
 
2963
                exit;
 
2964
        end;
 
2965
        lFile32bitItems := lFileSz div 4; //how many 32-bit items?
 
2966
        lSliceSz := gBGImg.ScrnDim[1]*gBGImg.ScrnDim[2];
 
2967
        lZ := gBGImg.ScrnDim[3];
 
2968
        if gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems > 0 then
 
2969
                freemem(gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer);
 
2970
        gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems := lSliceSz * lZ;
 
2971
        getmem(gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer,lSliceSz * lZ);
 
2972
        fillchar(gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^,gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems,0);
 
2973
        if lSliceSz > 65535 then
 
2974
                lBigFormat := true
 
2975
        else
 
2976
                lBigFormat := false;
 
2977
        getmem(lROIformatRA,lFileSz); //file size must be divisible by 4
 
2978
  {$I-}
 
2979
  AssignFile(lF, lFilename);
 
2980
  FileMode := 0;  { Set file access to read only }
 
2981
  Reset(lF, 1);
 
2982
  BlockRead(lF,lROIformatRA^,lFileSz);
 
2983
  CloseFile(lF);
 
2984
  FileMode := 2;
 
2985
  {$I+}
 
2986
  //next: check MSB of first byte to see if this is big format images
 
2987
  if lBigFormat <> odd((lROIformatRA^[1] and kMax16bit) shr 15) then
 
2988
        Showmessage('Warning: this ROI does not appear to be designed for the currently loaded background image.');
 
2989
  lFilePos := 1;
 
2990
if lBigFormat then begin //20-byte offset, 12-byte runlength
 
2991
  while lFilePos < lFile32bitItems do begin
 
2992
                lRunsOnSlice := (lROIformatRA^[lFilePos] shr 17) - 1; //shr 17: shift 16 bits, then div 2 (words instead of longints). Subtract 1 as the we have read slice number/ number of runs
 
2993
                lZ := (lROIformatRA^[lFilePos]  and kMax15bit);
 
2994
                inc(lFilePos);
 
2995
                lOutputSliceOffset := (lZ-1) * lSliceSz;
 
2996
                for lRun := 1 to lRunsOnSlice do begin
 
2997
                        if (lFilePos <= lFileSz) then begin
 
2998
                                lRunLength := (lROIformatRA^[lFilePos] shr 16) and kMax12bit;
 
2999
                                lRunOffset := (lROIformatRA^[lFilePos]  and kMax16bit)+ ((lROIformatRA^[lFilePos] shr 28) shl 16);
 
3000
                                if (lOutputSliceOffset+lRunLength+lRunOffset-1)> gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems then
 
3001
                                        //showmessage('Overrun on slice '+inttostr(lZ))
 
3002
                                else for lRunPos := lRunOffset to (lRunLength+lRunOffset-1) do
 
3003
                                        gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lRunPos+lOutputSliceOffset] := kVOI8bit;
 
3004
                        end;
 
3005
                        inc(lFilePos);
 
3006
                end;//for all runs
 
3007
  end; //while lPos < lFSz
 
3008
end else begin //not big format format - 16-byte offset, 16-byte length
 
3009
  while lFilePos < lFile32bitItems do begin
 
3010
                //lRunsOnSlice := (lROIformatRA[lFilePos] shr 16) and kMax16bit;
 
3011
                lRunsOnSlice := (lROIformatRA^[lFilePos] shr 17) - 1; //shr 17: shift 16 bits, then div 2 (words instead of longints). Subtract 1 as the we have read slice number/ number of runs
 
3012
                lZ := (lROIformatRA^[lFilePos]  and kMax15bit);
 
3013
                inc(lFilePos);
 
3014
                lOutputSliceOffset := (lZ-1) * lSliceSz;
 
3015
                //showmessage(inttostr(lZ)+'  '+inttostr(lRunsOnSlice)+'  '+inttostr(lFilePos)+'  '+inttostr(lFileSz));
 
3016
                for lRun := 1 to lRunsOnSlice do begin
 
3017
                        if (lFilePos <= lFileSz) then begin
 
3018
                                lRunLength := (lROIformatRA^[lFilePos] shr 16) and kMax16bit;
 
3019
                                lRunOffset := (lROIformatRA^[lFilePos]  and kMax16bit);
 
3020
                                {if (lRunLength+lRunOffset-1)> gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems then
 
3021
                                        showmessage('Overrun on slice '+inttostr(lZ))
 
3022
                                else} for lRunPos := lRunOffset to (lRunLength+lRunOffset-1) do
 
3023
                                        gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lRunPos+lOutputSliceOffset] := kVOI8bit;
 
3024
                        end;
 
3025
                        inc(lFilePos);
 
3026
                end;//for all runs
 
3027
  end; //while lPos < lFSz
 
3028
end; //if bigformat ... else little format
 
3029
  freemem(lROIformatRA);
 
3030
  lRun := maxint;
 
3031
  LoadMonochromeLUT(lRun,gBGImg,gMRIcroOverlay[kVOIOverlayNum]);
 
3032
end;
 
3033
 
 
3034
procedure TImgForm.OpenVOICore(var lFilename : string);
 
3035
var
 
3036
        lExt: string;
 
3037
begin
 
3038
         if gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems > 0 then
 
3039
                ImgForm.CloseVOIClick(nil);
 
3040
        lExt := UpCaseExt(lFileName);
 
3041
        gBGImg.VOIchanged := false;
 
3042
        if (lExt='.ROI') then begin
 
3043
                Showmessage('Warning: MRIcro ROI format does not save image dimensions. The background image must be in the same dimensions as the ROI.');
 
3044
                OpenMRIcroROI (lFileName);
 
3045
                ImgForm.RefreshImagesTimer.Enabled := true;
 
3046
                exit;
 
3047
        end;
 
3048
        if not HdrForm.OpenAndDisplayHdr(lFilename,gMRIcroOverlay[kVOIOverlayNum]) then exit;
 
3049
        if not OpenImg(gBGImg,gMRIcroOverlay[kVOIOverlayNum],false,true,false,gBGImg.ResliceOnLoad,false) then exit;
 
3050
        ImgForm.RefreshImagesTimer.Enabled := true;
 
3051
end;//OpenVOIClick
 
3052
 
 
3053
 
 
3054
procedure TImgForm.OpenVOIClick(Sender: TObject);
 
3055
var
 
3056
        lFilename: string;
 
3057
begin
 
3058
        if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 1 then begin
 
3059
                showmessage('Please load a background image (''File''/''Open'') before adding a VOI.');
 
3060
                exit;
 
3061
        end;
 
3062
        //HdrForm.OpenHdrDlg.Filter := '*.roi';//kVOIFilter;
 
3063
        //if not HdrForm.OpenHdrDlg.Execute then exit;
 
3064
         if not OpenDialogExecute(kVOIFilter,'Select Volume of Interest drawing',false) then exit;
 
3065
        lFilename := HdrForm.OpenHdrDlg.Filename;
 
3066
        OpenVOICore(lFilename);
 
3067
end;//OpenVOIClick
 
3068
 
 
3069
(*procedure TImgForm.SaveVOIClick(Sender: TObject);
 
3070
var lHdr: TMRIcroHdr;
 
3071
begin
 
3072
  if  gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems= 0 then begin
 
3073
                Showmessage('You need to create a VOI before you can save it.');
 
3074
                exit;
 
3075
  end;
 
3076
  if gBGImg.Mirror then begin
 
3077
     lHdr.ScrnBufferItems := gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems;
 
3078
     Getmem(lHdr.ScrnBuffer,gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems);
 
3079
     Move(gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[1],lHdr.ScrnBuffer^[1],lHdr.ScrnBufferItems);
 
3080
     MirrorScrnBuffer(gBGImg,lHdr);
 
3081
     SaveAsVOIorNIFTI(lHdr.ScrnBuffer,lHdr.ScrnBufferItems,1,1,true,gMRIcroOverlay[kBGOverlayNum].NiftiHdr,gMRIcroOverlay[kVOIOverlayNum].HdrFileName);
 
3082
     Freemem(lHdr.ScrnBuffer);
 
3083
     exit; //sept2007
 
3084
  end;
 
3085
  SaveAsVOIorNIFTI(gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer,gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems,1,1,true,gMRIcroOverlay[kBGOverlayNum].NiftiHdr,gMRIcroOverlay[kVOIOverlayNum].HdrFileName);
 
3086
end;*)
 
3087
procedure TImgForm.SaveVOIClick(Sender: TObject);
 
3088
   var lHdr: TMRIcroHdr;
 
3089
   lNIFTIhdr: TNIFTIhdr;
 
3090
begin
 
3091
  if  gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems= 0 then begin
 
3092
                Showmessage('You need to create a VOI before you can save it.');
 
3093
                exit;
 
3094
  end;
 
3095
  //Start 10/2007: adjust scl_slope;? 10/2007
 
3096
  CopyNiftiHdr(gMRIcroOverlay[kBGOverlayNum].NiftiHdr,lNIFTIhdr);
 
3097
  lNIFTIhdr.scl_slope := 1;
 
3098
  lNIFTIhdr.scl_inter := 0;
 
3099
  //end
 
3100
  if gBGImg.Mirror then begin
 
3101
     lHdr.ScrnBufferItems := gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems;
 
3102
     Getmem(lHdr.ScrnBuffer,gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems);
 
3103
     Move(gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[1],lHdr.ScrnBuffer^[1],lHdr.ScrnBufferItems);
 
3104
     MirrorScrnBuffer(gBGImg,lHdr);
 
3105
     SaveAsVOIorNIFTI(lHdr.ScrnBuffer,lHdr.ScrnBufferItems,1,1,true,lNIFTIhdr,gMRIcroOverlay[kVOIOverlayNum].HdrFileName);
 
3106
     Freemem(lHdr.ScrnBuffer);
 
3107
     exit; //sept2007
 
3108
  end;
 
3109
  SaveAsVOIorNIFTI(gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer,gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems,1,1,true,lNiftiHdr,gMRIcroOverlay[kVOIOverlayNum].HdrFileName);
 
3110
end;
 
3111
 
 
3112
procedure TImgForm.VOIColorClick(Sender: TObject);
 
3113
var
 
3114
        lMaxi: longint;
 
3115
begin
 
3116
                ColorDialog1.Color := gBGImg.VOIClr;
 
3117
                if not ColorDialog1.Execute then exit;
 
3118
                gBGImg.VOIClr := ColorDialog1.Color;
 
3119
                if gBGImg.VOIClr = clBlack then
 
3120
                        gBGImg.VOIClr := 1; //reserve 0 for deleting
 
3121
                lMaxi:=maxint;
 
3122
                LoadMonochromeLUT(lMaxi,gBGImg,gMRIcroOverlay[kVOIOverlayNum]);
 
3123
                RefreshImagesTimer.Enabled := true;
 
3124
end;
 
3125
 
 
3126
procedure TImgForm.CloseVOIClick(Sender: TObject);
 
3127
begin
 
3128
  if (gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems>0) and (gBGImg.VOIChanged) then begin
 
3129
        case MessageDlg('Do you wish to save the VOI drawing?', mtConfirmation,
 
3130
                                [mbYes, mbNo], 0) of    { produce the message dialog box }
 
3131
                                {id_Yes}mrYes: SaveVOIClick(nil);
 
3132
        end; //case
 
3133
  end;//if changed
 
3134
  FreeUndoVol;
 
3135
  FreeImgMemory(gMRIcroOverlay[kVOIOverlayNum]);
 
3136
  gBGImg.VOIUndoSlice := 0;
 
3137
  gBGImg.VOIchanged := false;
 
3138
  gBGImg.VOIUndoOrient := 0;
 
3139
  RefreshImagesTimer.Enabled := true;
 
3140
end;
 
3141
 
 
3142
procedure ImageRB (var lMaxR,lMaxB: integer; var lImage: TImage);
 
3143
var
 
3144
  lPos: integer;
 
3145
begin
 
3146
    if not lImage.Visible then
 
3147
      exit;
 
3148
    lPos := lImage.Left+lImage.Width;
 
3149
    if lPos > lMaxR then
 
3150
      lMaxR := lPos;
 
3151
    lPos := lImage.Top+lImage.Height;
 
3152
    if lPos > lMaxB then
 
3153
      lMaxB := lPos;
 
3154
end;
 
3155
 
 
3156
procedure CopyImg(var lSourceImg,lDestImg: TImage);
 
3157
var
 
3158
  lPos: integer;
 
3159
begin
 
3160
    if not lSourceImg.Visible then
 
3161
      exit;
 
3162
    lDestImg.Canvas.Draw(lSourceImg.Left,lSourceImg.Top,lSourceImg.Picture.Graphic);
 
3163
end;
 
3164
 
 
3165
procedure TImgForm.SaveOrCopyImages(lCopy: boolean);
 
3166
var
 
3167
  lMaxR,lMaxB: integer;
 
3168
  lOutImg: TImage;
 
3169
begin
 
3170
  lMaxR := 0;
 
3171
  lMaxB := 0;
 
3172
  ImageRB(lMaxR,lMaxB,ImgForm.PGImageAx);
 
3173
  ImageRB(lMaxR,lMaxB,ImgForm.PGImageCor);
 
3174
  ImageRB(lMaxR,lMaxB,ImgForm.PGImageSag);
 
3175
  if (lMaxR < 1) or (lMaxB < 1) then
 
3176
    exit;
 
3177
  lOutImg :=  TImage.Create(ImgForm);
 
3178
  try
 
3179
    //use the object
 
3180
    {$IFDEF FPC}
 
3181
    lOutImg.Width := lMaxR;
 
3182
    lOutImg.Height := lMaxB;
 
3183
    {$ELSE}
 
3184
    CreateImg(lMaxB,lMaxR,lOutImg);
 
3185
    {$ENDIF}
 
3186
    lOutImg.Canvas.Brush.color := ImgForm.TriplePanel.color;
 
3187
    lOutImg.Canvas.Rectangle(0,0,lMaxR+1,lMaxB+1);
 
3188
    CopyImg(ImgForm.PGImageAx,lOutImg);
 
3189
    CopyImg(ImgForm.PGImageCor,lOutImg);
 
3190
    CopyImg(ImgForm.PGImageSag,lOutImg);
 
3191
    if lCopy then begin
 
3192
       {$IFDEF FPC}
 
3193
       lOutImg.Picture.Bitmap.SaveToClipboardFormat(2);
 
3194
       {$ELSE}
 
3195
       Clipboard.Assign(lOutImg.Picture.Graphic);
 
3196
       {$ENDIF}
 
3197
    end else
 
3198
        SaveImgAsPNGBMP (lOutImg);
 
3199
  finally
 
3200
    FreeAndNil (lOutImg);
 
3201
  end;
 
3202
end;
 
3203
 
 
3204
procedure TImgForm.Saveaspicture1Click(Sender: TObject);
 
3205
begin
 
3206
  SaveOrCopyImages(false);
 
3207
end;
 
3208
(*var
 
3209
  lImage: TImage;
 
3210
begin
 
3211
         lImage := SelectedImage;
 
3212
        SaveImgAsPNGBMP (lImage);
 
3213
end; //Proc Saveaspicture1Click
 
3214
*)
 
3215
procedure TImgForm.Copy1Click(Sender: TObject); //Requires 'ClipBrd' in uses section
 
3216
begin
 
3217
  SaveOrCopyImages(true);
 
3218
end;
 
3219
 
 
3220
(*procedure TImgForm.Copy1Click(Sender: TObject); //Requires 'ClipBrd' in uses section
 
3221
var
 
3222
  MyFormat : Word;
 
3223
  lImage: TImage;
 
3224
  AData: THandle;
 
3225
  {$IFNDEF FPC}APalette : HPalette;{$ENDIF}
 
3226
begin
 
3227
         lImage := SelectedImage;
 
3228
         if (lImage.Picture.Graphic = nil) then begin //1420z
 
3229
                Showmessage('You need to load an image before you can copy it to the clipboard.');
 
3230
                exit;
 
3231
         end;
 
3232
    {$IFNDEF FPC}
 
3233
         lImage.Picture.Bitmap.SaveToClipBoardFormat(MyFormat,AData,APalette);
 
3234
         ClipBoard.SetAsHandle(MyFormat,AData);
 
3235
  {$ELSE}
 
3236
         lImage.Picture.Bitmap.SaveToClipboardFormat(2);
 
3237
  {$ENDIF}
 
3238
         if (gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems>0) then
 
3239
                WriteUndoVOI(SelectedImageNum,false);
 
3240
   
 
3241
end;  *)
 
3242
 
 
3243
procedure TImgForm.Undo1Click(Sender: TObject);
 
3244
begin
 
3245
        if gBGImg.VOIUndoSlice < 1 then exit;
 
3246
        case gBGImg.VOIUndoOrient of
 
3247
                4: UndoVolVOI;
 
3248
                3: ReadCorVOI(gUndoImg,gBGImg.VOIUndoSlice);
 
3249
                2: ReadSagVOI(gUndoImg,gBGImg.VOIUndoSlice);
 
3250
                1: ReadAxialVOI(gUndoImg,gBGImg.VOIUndoSlice);
 
3251
        end;
 
3252
        ImgForm.RefreshImagesTimer.Enabled := true;
 
3253
end;
 
3254
 
 
3255
procedure TImgForm.Paste1Click(Sender: TObject);
 
3256
begin
 
3257
        if (gBGImg.VOIUndoSlice < 1) then exit;
 
3258
  if gBGImg.VOIUndoOrient <> SelectedImageNum then //12/2007
 
3259
    exit;
 
3260
        WriteUndoVOI(SelectedImageNum,true);
 
3261
        case gBGImg.VOIUndoOrient of
 
3262
                3: ReadCorVOI(gDrawImg,ImgForm.YViewEdit.Value);
 
3263
                2: ReadSagVOI(gDrawImg,ImgForm.XViewEdit.Value);
 
3264
                1: ReadAxialVOI(gDrawImg,ImgForm.ZViewEdit.Value);
 
3265
                else exit;
 
3266
        end;
 
3267
        ImgForm.RefreshImagesTimer.Enabled := true;
 
3268
end;
 
3269
 
 
3270
procedure TImgForm.HideROIBtnMouseDown(Sender: TObject;
 
3271
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
 
3272
begin
 
3273
        gOrigBGTransPct := gBGImg.BGTransPct;
 
3274
        gBGImg.BGTransPct := 100;
 
3275
        refreshimagestimer.enabled := true;
 
3276
end;
 
3277
 
 
3278
procedure TImgForm.HideROIBtnMouseUp(Sender: TObject; Button: TMouseButton;
 
3279
  Shift: TShiftState; X, Y: Integer);
 
3280
begin
 
3281
        gBGImg.BGTransPct := gOrigBGTransPct;
 
3282
        Refreshimagestimer.enabled := true;
 
3283
end;
 
3284
 
 
3285
procedure TImgForm.Applyintensityfiltertovolume1Click(Sender: TObject);
 
3286
begin
 
3287
  if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems=0 then begin
 
3288
        showmessage('You must have open a background image in order to apply an intensity filter (use File/Open).');
 
3289
        exit;
 
3290
  end;
 
3291
         FilterROIform.showmodal;
 
3292
end;
 
3293
 
 
3294
procedure TImgForm.Quicksmooth1Click(Sender: TObject);
 
3295
var
 
3296
 lHdr: TMRicroHdr;
 
3297
 lXDim,lYDim,lZDim,lSum,lMinWt,lMaxWt,lMinInten,lMaxInten,lOutVolVox,lOutSliceSz,lX,lY,lZ,lXxi,l2,lZyi: integer;
 
3298
 lSum32,lMinInten32,lMaxInten32: single;
 
3299
 lTempBuff,lSrcBuff: Bytep;
 
3300
 l16TempBuff,l16SrcBuff: SmallIntP;
 
3301
 l32TempBuff,l32SrcBuff: SingleP;
 
3302
procedure AddPoint (lInten,lWeight:integer);
 
3303
begin
 
3304
        lSum := lSum + (lInten*lWeight);
 
3305
        if lInten <= lMinInten then begin
 
3306
           lMinWt := lWeight;
 
3307
           lMinInten := lInten;
 
3308
        end else if lInten >= lMaxInten then begin
 
3309
           lMaxWt := lWeight;
 
3310
           lMaxInten := lInten;
 
3311
        end;
 
3312
end;  //nested AddPoint
 
3313
procedure AddPoint32 (lInten32: single; lWeight:integer);
 
3314
begin
 
3315
        lSum32 := lSum32 + (lInten32*lWeight);
 
3316
        if lInten32 <= lMinInten32 then begin
 
3317
           lMinWt := lWeight;
 
3318
           lMinInten32 := lInten32;
 
3319
        end else if lInten32 >= lMaxInten32 then begin
 
3320
       lMaxWt := lWeight;
 
3321
           lMaxInten32 := lInten32;
 
3322
        end;
 
3323
end;  //nested AddPoint32
 
3324
begin
 
3325
  lHdr := gMRIcroOverlay[kBGOverlayNum];
 
3326
  lXDim := gBGImg.ScrnDim[1];
 
3327
  lYDim := gBGImg.ScrnDim[2];
 
3328
  lZDim := gBGImg.ScrnDim[3];
 
3329
  lOutSliceSz := gBGImg.ScrnDim[1] * gBGImg.ScrnDim[2];
 
3330
  lOutVolVox :=  lOutSliceSz * lZDim;
 
3331
  if (lXDim < 3) or (lYDim < 3) or (lZDim < 3) or (lOutVolVox < 36) then begin
 
3332
         showmessage('The 3D smoothing can only be applied to images with at least 3 slices in each dimension.'); 
 
3333
         exit;
 
3334
  end;
 
3335
  if (lHdr.ImgBufferItems < 1) then begin
 
3336
          showmessage('Please first load the image you would like to smooth.');
 
3337
          exit;
 
3338
  end;
 
3339
  ProgressBar1.Min := 0;
 
3340
  ProgressBar1.Max :=lZDim;
 
3341
  StatusLabel.caption := 'Removing noise speckles and smoothing data [blur]';
 
3342
  if  lHdr.ImgBufferBPP = 4 then begin //32-bit float data
 
3343
        l32SrcBuff := SingleP(lHdr.ImgBuffer);
 
3344
        GetMem(l32TempBuff,lOutVolVox*sizeof(single));
 
3345
    Move(l32SrcBuff^,l32TempBuff^,lOutVolVox*sizeof(single));
 
3346
        for lZ := 1 to lOutVolVox do
 
3347
                l32SrcBuff^[lZ] := 0;
 
3348
        for lZ := lZDim-1 downto 2 do begin
 
3349
                ProgressBar1.Position := (lZDim-lZ);
 
3350
                for lY := lYDim-1 downto 2 do begin
 
3351
                        lZyi := ((lZ-1)*lOutSliceSz) + ((lY-1) * lXDim);
 
3352
                        for lX := lXDim-1 downto 2 do begin
 
3353
                lXxi := lZyi + lX;
 
3354
                                //next: gaussian mean after min/max values are excluded
 
3355
                lSum32 := 0;
 
3356
                                lMinInten32 := l32TempBuff^[lXxi];
 
3357
                lMaxInten32 := l32TempBuff^[lXxi];
 
3358
                                lMinWt := 12;
 
3359
                lMaxWt := 12;
 
3360
                                AddPoint32(l32TempBuff^[lXxi],12);//quad-weight center
 
3361
                                AddPoint32(l32TempBuff^[lXxi-lOutSliceSz],2);//prev slice
 
3362
                                AddPoint32(l32TempBuff^[lXxi+lOutSliceSz],2);//next slices
 
3363
                                AddPoint32(l32TempBuff^[lXxi-1],2);//Left
 
3364
                                AddPoint32(l32TempBuff^[lXxi+1],2);//right
 
3365
                                AddPoint32(l32TempBuff^[lXxi-lXDim],2);//up
 
3366
                                AddPoint32(l32TempBuff^[lXxi+lXDim],2);//down
 
3367
                                AddPoint32(l32TempBuff^[lXxi-lOutSliceSz-1],1);
 
3368
                                AddPoint32(l32TempBuff^[lXxi-lOutSliceSz+1],1);
 
3369
                                AddPoint32(l32TempBuff^[lXxi-lOutSliceSz-lXDim],1);
 
3370
                                AddPoint32(l32TempBuff^[lXxi-lOutSliceSz+lXDim],1);
 
3371
                                AddPoint32(l32TempBuff^[lXxi+lOutSliceSz-1],1);
 
3372
                                AddPoint32(l32TempBuff^[lXxi+lOutSliceSz+1],1);
 
3373
                                AddPoint32(l32TempBuff^[lXxi+lOutSliceSz-lXDim],1);
 
3374
                                AddPoint32(l32TempBuff^[lXxi+lOutSliceSz+lXDim],1);
 
3375
                                AddPoint32(l32TempBuff^[lXxi-lXDim-1],1);
 
3376
                                AddPoint32(l32TempBuff^[lXxi+lXDim-1],1);
 
3377
                                AddPoint32(l32TempBuff^[lXxi-lXDim+1],1);
 
3378
                                AddPoint32(l32TempBuff^[lXxi+lXDim+1],1);
 
3379
                                if lMinInten32 = lMaxInten32 then
 
3380
                                   l32SrcBuff^[lXxi] := lMaxInten32 //no variability in data
 
3381
                                else begin
 
3382
                                         l2 := 36 - lMinWt -lMaxWt;  //weight after we exceed brightest and darkest
 
3383
                                         lSum32 := lSum32 -(lMinWt*lMinInten32) - (lMaxWt*lMaxInten32); //exclude brightest/darkest
 
3384
                                         l32SrcBuff^[lXxi] := (lSum32/l2);
 
3385
                                end;
 
3386
                        end; //forX
 
3387
                end; //forY
 
3388
        end; //forZ
 
3389
        Freemem(l32TempBuff);
 
3390
  end else if (lHdr.ImgBufferBPP = 2) then begin //16-bit int data*)
 
3391
        l16SrcBuff :=  SmallIntP(lHdr.ImgBuffer );
 
3392
        GetMem(l16TempBuff,lOutVolVox*sizeof(word));
 
3393
        Move(l16SrcBuff^,l16TempBuff^,lOutVolVox*sizeof(word));
 
3394
        for lZ := 1 to lOutVolVox do
 
3395
                l16SrcBuff^[lZ] := 0;
 
3396
        for lZ := lZDim-1 downto 2 do begin
 
3397
                ProgressBar1.Position := (lZDim-lZ);
 
3398
                for lY := lYDim-1 downto 2 do begin
 
3399
                        lZyi := ((lZ-1)*lOutSliceSz) + ((lY-1) * lXDim);
 
3400
                        for lX := lXDim-1 downto 2 do begin
 
3401
                                lXxi := lZyi + lX;
 
3402
                                //next: gaussian mean after min/max values are excluded
 
3403
                                lSum := 0;
 
3404
                                lMinInten := l16TempBuff^[lXxi];
 
3405
                                lMaxInten := l16TempBuff^[lXxi];
 
3406
                                lMinWt := 12;
 
3407
                                lMaxWt := 12;
 
3408
                                AddPoint(l16TempBuff^[lXxi],12);//quad-weight center
 
3409
                                AddPoint(l16TempBuff^[lXxi-lOutSliceSz],2);//prev slice
 
3410
                                AddPoint(l16TempBuff^[lXxi+lOutSliceSz],2);//next slices
 
3411
                AddPoint(l16TempBuff^[lXxi-1],2);//Left
 
3412
                                AddPoint(l16TempBuff^[lXxi+1],2);//right
 
3413
                                AddPoint(l16TempBuff^[lXxi-lXDim],2);//up
 
3414
                                AddPoint(l16TempBuff^[lXxi+lXDim],2);//down
 
3415
                AddPoint(l16TempBuff^[lXxi-lOutSliceSz-1],1);
 
3416
                                AddPoint(l16TempBuff^[lXxi-lOutSliceSz+1],1);
 
3417
                                AddPoint(l16TempBuff^[lXxi-lOutSliceSz-lXDim],1);
 
3418
                                AddPoint(l16TempBuff^[lXxi-lOutSliceSz+lXDim],1);
 
3419
                                AddPoint(l16TempBuff^[lXxi+lOutSliceSz-1],1);
 
3420
                                AddPoint(l16TempBuff^[lXxi+lOutSliceSz+1],1);
 
3421
                AddPoint(l16TempBuff^[lXxi+lOutSliceSz-lXDim],1);
 
3422
                                AddPoint(l16TempBuff^[lXxi+lOutSliceSz+lXDim],1);
 
3423
                                AddPoint(l16TempBuff^[lXxi-lXDim-1],1);
 
3424
                                AddPoint(l16TempBuff^[lXxi+lXDim-1],1);
 
3425
                AddPoint(l16TempBuff^[lXxi-lXDim+1],1);
 
3426
                                AddPoint(l16TempBuff^[lXxi+lXDim+1],1);
 
3427
                if lMinInten = lMaxInten then
 
3428
                                   l16SrcBuff^[lXxi] := lMaxInten //no variability in data
 
3429
                else begin
 
3430
                                         l2 := 36 - lMinWt -lMaxWt;  //weight after we exceed brightest and darkest
 
3431
                     lSum := lSum -(lMinWt*lMinInten) - (lMaxWt*lMaxInten); //exclude brightest/darkest
 
3432
                                         l16SrcBuff^[lXxi] := round(lSum/l2);
 
3433
                end;
 
3434
                        end; //forX
 
3435
                end; //forY
 
3436
        end; //forZ
 
3437
        Freemem(l16TempBuff);
 
3438
        //OptimizeSingle(nil);
 
3439
  end else if lHdr.ImgBufferBPP = 1 then begin //8-bit data
 
3440
          lSrcBuff := lHdr.ImgBuffer;
 
3441
   GetMem(lTempBuff,lOutVolVox);
 
3442
   Move(lSrcBuff^,lTempBuff^,lOutVolVox);
 
3443
   fillchar(lSrcBuff^,lOutVolVox,0); //set edges to 0, as outside voxel is not smoothed
 
3444
   for lZ := lZDim-1 downto 2 do begin
 
3445
                ProgressBar1.Position := (lZDim-lZ);
 
3446
                for lY := lYDim-1 downto 2 do begin
 
3447
                        lZyi := ((lZ-1)*lOutSliceSz) + ((lY-1) * lXDim);
 
3448
                        for lX := lXDim-1 downto 2 do begin
 
3449
                                lXxi := lZyi + lX;
 
3450
                                //next: gaussian mean after min/max values are excluded
 
3451
                                lSum := 0;
 
3452
                                lMinInten := lTempBuff^[lXxi];
 
3453
                                lMaxInten := lTempBuff^[lXxi];
 
3454
                                lMinWt := 12;
 
3455
                                lMaxWt := 12;
 
3456
                                AddPoint(lTempBuff^[lXxi],12);//quad-weight center
 
3457
                                AddPoint(lTempBuff^[lXxi-lOutSliceSz],2);//prev slice
 
3458
                AddPoint(lTempBuff^[lXxi+lOutSliceSz],2);//next slices
 
3459
                                AddPoint(lTempBuff^[lXxi-1],2);//Left
 
3460
                                AddPoint(lTempBuff^[lXxi+1],2);//right
 
3461
                                AddPoint(lTempBuff^[lXxi-lXDim],2);//up
 
3462
                AddPoint(lTempBuff^[lXxi+lXDim],2);//down
 
3463
                                AddPoint(lTempBuff^[lXxi-lOutSliceSz-1],1);
 
3464
                AddPoint(lTempBuff^[lXxi-lOutSliceSz+1],1);
 
3465
                                AddPoint(lTempBuff^[lXxi-lOutSliceSz-lXDim],1);
 
3466
                AddPoint(lTempBuff^[lXxi-lOutSliceSz+lXDim],1);
 
3467
                                AddPoint(lTempBuff^[lXxi+lOutSliceSz-1],1);
 
3468
                                AddPoint(lTempBuff^[lXxi+lOutSliceSz+1],1);
 
3469
                                AddPoint(lTempBuff^[lXxi+lOutSliceSz-lXDim],1);
 
3470
                AddPoint(lTempBuff^[lXxi+lOutSliceSz+lXDim],1);
 
3471
                                AddPoint(lTempBuff^[lXxi-lXDim-1],1);
 
3472
                AddPoint(lTempBuff^[lXxi+lXDim-1],1);
 
3473
                                AddPoint(lTempBuff^[lXxi-lXDim+1],1);
 
3474
                                AddPoint(lTempBuff^[lXxi+lXDim+1],1);
 
3475
                                if lMinInten = lMaxInten then
 
3476
                                   lSrcBuff^[lXxi] := lMaxInten //no variability in data
 
3477
                                else begin
 
3478
                                         l2 := 36 - lMinWt -lMaxWt;  //weight after we exceed brightest and darkest
 
3479
                                         lSum := lSum -(lMinWt*lMinInten) - (lMaxWt*lMaxInten); //exclude brightest/darkest
 
3480
                                         lSrcBuff^[lXxi] := round(lSum/l2);
 
3481
                                end;
 
3482
                        end; //forX
 
3483
                end; //forY
 
3484
        end; //forZ
 
3485
        Freemem(lTempBuff);
 
3486
  end else begin //8bit data
 
3487
      showmessage('Unknown bits per pixel '+inttostr(lHdr.ImgBufferBPP) );
 
3488
  end;
 
3489
        ProgressBar1.Position := 0;
 
3490
                RescaleImgIntensity(gBGImg,gMRIcroOverlay[kBGOverlayNum],kBGOverlayNum);
 
3491
        RefreshImagesTimer.Enabled := true;
 
3492
end; //quicksmooth
 
3493
 
 
3494
procedure TImgForm.VOImaskClick(Sender: TObject);
 
3495
var
 
3496
 lPreserve: integer;
 
3497
 lHdr,lMaskHdr: TMRicroHdr;
 
3498
 lXDim,lYDim,lZDim,lOutVolVox,lOutSliceSz,lZ: integer;
 
3499
 lSrcBuff,lMaskBuff: Bytep;
 
3500
 l16SrcBuff: SmallIntP;
 
3501
 l32SrcBuff: SingleP;
 
3502
begin
 
3503
        lPreserve := (sender as TMenuItem).tag;
 
3504
  lHdr := gMRIcroOverlay[kBGOverlayNum];
 
3505
  lMaskHdr := gMRIcroOverlay[kVOIOverlayNum];
 
3506
 
 
3507
  lXDim := gBGImg.ScrnDim[1];
 
3508
  lYDim := gBGImg.ScrnDim[2];
 
3509
  lZDim := gBGImg.ScrnDim[3];
 
3510
  lOutSliceSz := gBGImg.ScrnDim[1] * gBGImg.ScrnDim[2];
 
3511
  lOutVolVox :=  lOutSliceSz * lZDim;
 
3512
  if (lXDim < 2) or (lYDim < 2) or (lZDim < 2) then begin
 
3513
         showmessage('Masking can only be applied to images with multiple slices in 3 dimensions.');
 
3514
         exit;
 
3515
  end;
 
3516
  if (lHdr.ImgBufferItems <>  lMaskHdr.ScrnBufferItems) or (lHdr.ImgBufferItems < 8) then begin
 
3517
          showmessage('Please first load both an image (File/Open) and a masking VOI (Draw/Open).');
 
3518
          exit;
 
3519
  end;
 
3520
  if gBGImg.Mirror then
 
3521
     MirrorScrnBuffer(gBGImg,lMaskHdr);//4/2008
 
3522
  lMaskBuff := (lMaskHdr.ScrnBuffer);
 
3523
  ProgressBar1.Min := 0;
 
3524
  ProgressBar1.Max :=lZDim;
 
3525
  StatusLabel.caption := 'Masking data';
 
3526
  if  lHdr.ImgBufferBPP = 4 then begin //32-bit float data
 
3527
        l32SrcBuff := SingleP(lHdr.ImgBuffer);
 
3528
        if lPreserve = 1 then begin
 
3529
                for lZ := 1 to lOutVolVox do
 
3530
                        if lMaskBuff^[lZ] = 0 then
 
3531
                                l32SrcBuff^[lZ] := 0;
 
3532
        end else begin
 
3533
                for lZ := 1 to lOutVolVox do
 
3534
                        if lMaskBuff^[lZ] <> 0 then
 
3535
                                l32SrcBuff^[lZ] := 0;
 
3536
        end; //if preserve
 
3537
  end else if (lHdr.ImgBufferBPP = 2) then begin //16-bit int data*)
 
3538
        l16SrcBuff :=  SmallIntP(lHdr.ImgBuffer );
 
3539
        if lPreserve = 1 then begin
 
3540
                for lZ := 1 to lOutVolVox do
 
3541
                        if lMaskBuff^[lZ] = 0 then
 
3542
                                l16SrcBuff^[lZ] := 0;
 
3543
        end else begin
 
3544
                for lZ := 1 to lOutVolVox do
 
3545
                        if lMaskBuff^[lZ] <> 0 then
 
3546
                                l16SrcBuff^[lZ] := 0;
 
3547
        end;
 
3548
  end else if lHdr.ImgBufferBPP = 1 then begin //8-bit data
 
3549
          lSrcBuff := lHdr.ImgBuffer;
 
3550
        if lPreserve = 1 then begin
 
3551
                for lZ := 1 to lOutVolVox do
 
3552
                        if lMaskBuff^[lZ] = 0 then
 
3553
                                lSrcBuff^[lZ] := 0
 
3554
        end else begin
 
3555
                for lZ := 1 to lOutVolVox do
 
3556
                        if lMaskBuff^[lZ] <> 0 then
 
3557
                                lSrcBuff^[lZ] := 0;
 
3558
        end;
 
3559
  end else begin //8bit data
 
3560
          showmessage('Unknown bits per pixel '+inttostr(lHdr.ImgBufferBPP) );
 
3561
  end;
 
3562
  if gBGImg.Mirror then
 
3563
     MirrorScrnBuffer(gBGImg,lMaskHdr);//4/2008
 
3564
 
 
3565
  ProgressBar1.Position := 0;
 
3566
  RescaleImgIntensity(gBGImg,gMRIcroOverlay[kBGOverlayNum],kBGOverlayNum);
 
3567
  RefreshImagesTimer.Enabled := true;
 
3568
end;  //VOImaskClick
 
3569
 
 
3570
procedure TImgForm.Sagittal1Click(Sender: TObject);
 
3571
begin
 
3572
      gBGImg.SliceView :=  (Sender as TMenuItem).Tag;
 
3573
    RefreshImagesTimer.Enabled := true;
 
3574
end;
 
3575
 
 
3576
procedure TImgForm.ROIcomparisonClick(Sender: TObject);
 
3577
var lComparison,lVolItems,lOverlay,lnOverlays,lPos: integer;
 
3578
begin
 
3579
        lComparison := (Sender as TMenuItem).tag; //0=intersect AND,1=union OR ,2=mask
 
3580
        lVolItems := gBGImg.ScrnDim[1]*gBGImg.ScrnDim[2]* gBGImg.ScrnDim[3];
 
3581
        if (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems <> lVolItems) or (gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems <> lVolItems) then begin
 
3582
                Showmessage('VOI comparisons require a VOI loaded onto a background image (Draw/Open).');
 
3583
                exit;
 
3584
        end;
 
3585
        lnOverlays := 0;
 
3586
        for lOverlay := 1 to knMaxOverlay do
 
3587
                if gMRIcroOverlay[lOverlay].ScrnBufferItems = lVolItems then
 
3588
                        inc(lnOverlays);
 
3589
        if (lnOverlays = 0) then begin
 
3590
                Showmessage('VOI comparisons require loaded overlays (Overlay/Add).');
 
3591
                exit;
 
3592
        end;
 
3593
        CreateUndoVol;
 
3594
        if lComparison = 0 then begin //intersect AND
 
3595
          for lOverlay := 1 to (knMaxOverlay-1) do begin
 
3596
                if gMRIcroOverlay[lOverlay].ScrnBufferItems = lVolItems then begin
 
3597
                        for lPos := 1 to lVolItems do
 
3598
                                if gMRIcroOverlay[lOverlay].ScrnBuffer^[lPos] = 0 then
 
3599
                                        gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lPos] := 0;
 
3600
                end; //if overlay loaded
 
3601
          end; //for each overlay
 
3602
        end else if lComparison = 1 then begin //if intersect else UNION OR
 
3603
          for lOverlay := 1 to (knMaxOverlay-1) do begin
 
3604
                if gMRIcroOverlay[lOverlay].ScrnBufferItems = lVolItems then begin
 
3605
                        for lPos := 1 to lVolItems do
 
3606
                                if gMRIcroOverlay[lOverlay].ScrnBuffer^[lPos] > 0 then
 
3607
                                        gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lPos] := kVOI8bit;
 
3608
                end; //if overlay loaded
 
3609
          end; //for each overlay
 
3610
        end else if lComparison = 2 then begin //if union else MASK
 
3611
          for lOverlay := 1 to (knMaxOverlay-1) do begin
 
3612
                if gMRIcroOverlay[lOverlay].ScrnBufferItems = lVolItems then begin
 
3613
                        for lPos := 1 to lVolItems do
 
3614
                                if gMRIcroOverlay[lOverlay].ScrnBuffer^[lPos] > 0 then
 
3615
                                        gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^[lPos] := 0;
 
3616
                end; //if overlay loaded
 
3617
          end; //for each overlay
 
3618
        end; //if ..else MASK
 
3619
        RefreshImagesTimer.Enabled := true;
 
3620
end;  //ROIcomparisonClick
 
3621
 
 
3622
procedure TImgForm.RescaleImagesTimerTimer(Sender: TObject);
 
3623
var
 
3624
        lLayer: integer;
 
3625
begin
 
3626
        lLayer := ActiveLayer;
 
3627
         RescaleImagesTimer.Enabled := false;
 
3628
         RescaleImgIntensity(gBGImg,gMRIcroOverlay[lLayer],lLayer);
 
3629
         RefreshImages;
 
3630
end;
 
3631
 
 
3632
procedure TImgForm.Fill3DBtnClick(Sender: TObject);
 
3633
begin
 
3634
        AutoROIForm.Show;
 
3635
end;
 
3636
 
 
3637
 
 
3638
procedure TImgForm.SmoothVOI1Click(Sender: TObject);
 
3639
begin
 
3640
 voismoothform.showmodal;
 
3641
 //SmoothVOIForm.Showmodal
 
3642
end;
 
3643
 
 
3644
procedure TImgForm.CreateOverlap(Sender: TObject);
 
3645
var
 
3646
        lNumberofFiles,lC,lOverlay,lPos: integer;
 
3647
        lFilename,lExt: string;
 
3648
        lOverlapBuffer: ByteP;
 
3649
begin
 
3650
        if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 1 then begin
 
3651
                showmessage('Please load a background image (''File''/''Open'') before adding an overlay.');
 
3652
                exit;
 
3653
        end;
 
3654
         lOverlay := 0;
 
3655
         for lC := 1 to (knMaxOverlay-1) do //-1: save final overlay for VOI
 
3656
                  if (lOverlay = 0) and (gMRIcroOverlay[lC].ImgBufferItems = 0) then
 
3657
                        lOverlay := lC;
 
3658
         if lOverlay = 0 then begin
 
3659
                showmessage('Unable to add an overlay. You have loaded the maximum number of overlays.');
 
3660
                exit;
 
3661
         end;
 
3662
        if not OpenDialogExecute(kVOIFilter,'Select VOIs you wish to combine',true) then exit;
 
3663
        lNumberofFiles:= HdrForm.OpenHdrDlg.Files.Count;
 
3664
        if  lNumberofFiles < 2 then begin
 
3665
                Showmessage('Error: This function is designed to overlay MULTIPLE images. You selected less than two images.');
 
3666
                exit;
 
3667
        end;
 
3668
  ProgressBar1.Min := 0;
 
3669
  ProgressBar1.Max :=lNumberofFiles;
 
3670
  ProgressBar1.Position := 0;
 
3671
        getmem(lOverlapBuffer,gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems);
 
3672
        fillchar(lOverlapBuffer^,gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems,0);
 
3673
        for lC:= 1 to lNumberofFiles do begin
 
3674
                lFilename := HdrForm.OpenHdrDlg.Files[lC-1];
 
3675
                lExt := UpCaseExt(lFileName);
 
3676
                gBGImg.VOIchanged := false;
 
3677
                if not HdrForm.OpenAndDisplayHdr(lFilename,gMRIcroOverlay[lOverlay]) then exit;
 
3678
                if not OpenImg(gBGImg,gMRIcroOverlay[lOverlay],false,false,false,gBGImg.ResliceOnLoad,false) then exit;
 
3679
                ProgressBar1.Position := lC;
 
3680
                for lPos := 1 to gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems do
 
3681
                        if gMRIcroOverlay[lOverlay].ScrnBuffer^[lPos] > 0 then
 
3682
                                lOverlapBuffer^[lPos] :=  lOverlapBuffer^[lPos]+1;
 
3683
                FreeImgMemory(gMRIcroOverlay[lOverlay]);
 
3684
        end; //for each image
 
3685
        //July07 getmem for unaligned buffer getmem(gMRIcroOverlay[lOverlay].ImgBuffer,gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems);
 
3686
        GetMem(gMRIcroOverlay[lOverlay].ImgBufferUnaligned ,gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems + 16); //July072007
 
3687
        //gMRIcroOverlay[lOverlay].ImgBuffer := ByteP($fffffff0 and (integer(gMRIcroOverlay[lOverlay].ImgBufferUnaligned)+15));
 
3688
         gMRIcroOverlay[lOverlay].ImgBuffer := system.align(gMRIcroOverlay[lOverlay].ImgBufferUnaligned, 16);
 
3689
        gMRIcroOverlay[lOverlay].ImgBufferItems := gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems;
 
3690
        for lPos := 1 to gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems do
 
3691
                gMRIcroOverlay[lOverlay].ImgBuffer[lPos] := lOverlapBuffer[lPos];
 
3692
        freemem(lOverlapBuffer);
 
3693
        MakeStatHdr (gMRIcroOverlay[kBGOverlayNum],gMRIcroOverlay[lOverlay],0, lNumberofFiles,1,0,0,kNIFTI_INTENT_ESTIMATE,'N'+inttostr(lNumberofFiles) );
 
3694
        UpdateLayerMenu;
 
3695
        RescaleImgIntensity(gBGImg,gMRIcroOverlay[lOverlay],lOverlay);
 
3696
        ProgressBar1.Position := 0;
 
3697
        //SaveAsVOIorNIFTI(gMRIcroOverlay[lOverlay].ImgBuffer,gMRIcroOverlay[lOverlay].ScrnBufferItems,1,false,gMRIcroOverlay[lOverlay].niftiHdr,'sum'+inttostr(lNumberofFiles));
 
3698
        SaveAsVOIorNIFTI(gMRIcroOverlay[lOverlay].ImgBuffer,gMRIcroOverlay[lOverlay].ScrnBufferItems,1,1,false,gMRIcroOverlay[lOverlay].niftiHdr,'sum'+inttostr(lNumberofFiles));
 
3699
        RefreshImagesTimer.Enabled := true;
 
3700
end;//proc CreateOverlap
 
3701
 
 
3702
procedure TImgForm.Chisquare1Click(Sender: TObject);
 
3703
var
 
3704
        lNegativeNumbers: boolean;
 
3705
        lVolVoxels,lPos,lnTotalThreshold,lLoop,lnVoxelsTested:integer;
 
3706
        lMinExp,lChi,lChip,luChi, luChiP: double;
 
3707
        lMaxChi,lMinChi: single;
 
3708
        lBufferAligned,lBufferUnAligned,lBuffer: ByteP;
 
3709
        l32Buf : SingleP;
 
3710
        lFilename: string;
 
3711
        lTotal,lYes,lNo: array [1..2] of integer;
 
3712
        lMRIcroHdr: TMRIcroHdr;
 
3713
begin
 
3714
        lVolVoxels := gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems;
 
3715
        if lVolVoxels < 1 then begin
 
3716
                showmessage('Please load a background image (''File''/''Open'') before adding an overlay.');
 
3717
                exit;
 
3718
        end;
 
3719
        CloseOverlayImgClick(nil);
 
3720
        for lLoop := 1 to 2 do begin //open two images
 
3721
                if lLoop = 1 then begin
 
3722
                        if not OpenDialogExecute(kImgFilter,'Select POSITIVE overlap image',false) then exit
 
3723
                end else begin
 
3724
                        if not OpenDialogExecute(kImgFilter,'Select NEGATIVE overlap image',false) then exit;
 
3725
                end;
 
3726
                lFilename := HdrForm.OpenHdrDlg.Filename;
 
3727
                if not HdrForm.OpenAndDisplayHdr(lFilename,gMRIcroOverlay[lLoop]) then exit;
 
3728
                if not OpenImg(gBGImg,gMRIcroOverlay[lLoop],false,false,true,gBGImg.ResliceOnLoad,false) then exit;
 
3729
                lTotal[lLoop] := round(gMRIcroOverlay[lLoop].NIFTIhdr.glmax);
 
3730
                if (gMRIcroOverlay[lLoop].NIFTIhdr.intent_code <> kNIFTI_INTENT_ESTIMATE) then
 
3731
                        showmessage('Warning: header intent_code is not set to ESTIMATE. Compute Chi-squared only with cumulative maps created with this program.');
 
3732
                if (gMRIcroOverlay[lLoop].NIFTIhdr.intent_name[1] <> 'N') then
 
3733
                        showmessage('Warning: header intention not N. Compute Chi-squared only with cumulative maps created with this program.');
 
3734
                UpdateLayerMenu;
 
3735
                RefreshImagesTimer.Enabled := true;
 
3736
        end;
 
3737
        if (lVolVoxels<> gMRIcroOverlay[1].ScrnBufferItems)
 
3738
                or (lVolVoxels<> gMRIcroOverlay[2].ScrnBufferItems) then begin
 
3739
                showmessage('Error loading images.');
 
3740
                exit;
 
3741
        end;
 
3742
        //next - chi squared
 
3743
        lnTotalThreshold:= ReadIntForm.GetInt('Only test voxels damaged in at least N patients [A+B]', 1,1,(lTotal[1]+lTotal[2]));
 
3744
        GetMem(lBufferUnaligned ,(lVolVoxels *sizeof(single) )+16);
 
3745
        //lBufferAligned := ByteP($fffffff0 and (integer(lBufferUnaligned)+15));
 
3746
        lBufferAligned := system.align(lBufferUnaligned, 16);
 
3747
        l32Buf := SingleP(lBufferAligned);
 
3748
        lnVoxelsTested := 0;
 
3749
        lNegativeNumbers := false;
 
3750
        lMaxChi := 0;
 
3751
        lMinChi := 0;
 
3752
        for lPos := 1 to lVolVoxels do begin
 
3753
                l32Buf^[lPos] := 0;
 
3754
                lYes[1] := gMRIcroOverlay[1].ScrnBuffer^[lPos];
 
3755
                lNo[1] := lTotal[1]-lYes[1];
 
3756
                lYes[2] := gMRIcroOverlay[2].ScrnBuffer^[lPos];
 
3757
                lNo[2] := lTotal[2]-lYes[2];
 
3758
                if (lYes[1] < 0) or (lNo[1] < 0) or (lYes[2] < 0) or (lNo[2] < 0) then
 
3759
                        lNegativeNumbers := true
 
3760
                else if (lYes[1]+lYes[2]) >= lnTotalThreshold then begin//e.g. at least 30% of all patients
 
3761
                                  inc(lnVoxelsTested);
 
3762
                                  //showmessage(inttostr(lYes[1])+'x'+inttostr(lNo[1])+'x'+ inttostr(lYes[2])+'x'+inttostr(lNo[2]) );
 
3763
                                  Chi2x2 (lYes[1], lNo[1], lYes[2], lNo[2],lMinExp,lChi,lChip,luChi, luChiP);
 
3764
                                  if (luChi) > lMaxChi then
 
3765
                                        lMaxChi := (luChi)
 
3766
                                  else if (luChi < lMinChi) then
 
3767
                                        lMinChi := luChi;
 
3768
                                  if (lYes[1]/lTotal[1]) > (lYes[2]/lTotal[2]) then
 
3769
                                         l32Buf^[lPos] := luChi//100-(100*luChip) //positives more likely than negative
 
3770
                                  else
 
3771
                                          l32Buf^[lPos] := -luChi;//-100+(100*luChip); //negatives more common
 
3772
                end;//> threshold
 
3773
        end; //for each voxel
 
3774
        MakeStatHdr (gMRIcroOverlay[kBGOverlayNum],lMRIcroHdr,lMinChi, lMaxChi,1{df},0,lnVoxelsTested,kNIFTI_INTENT_CHISQ,inttostr(lnVoxelsTested) );
 
3775
        if lNegativeNumbers then
 
3776
                Showmessage('Serious error: some group sizes were negative. This should be impossible with a Chi-Squared.');
 
3777
        //SaveAsVOIorNIFTI(lBufferAligned,lVolVoxels,4,false,lMRIcroHdr.NiftiHdr,'chi'+inttostr(lnTotalThreshold));
 
3778
        SaveAsVOIorNIFTI(lBufferAligned,lVolVoxels,4,1,false,lMRIcroHdr.NiftiHdr,'log10p'+inttostr(lnTotalThreshold));
 
3779
        //next - save log10 p values...
 
3780
        MakeStatHdr (gMRIcroOverlay[kBGOverlayNum],lMRIcroHdr,lMinChi, lMaxChi,1{df},0,lnVoxelsTested,NIFTI_INTENT_LOG10PVAL,inttostr(lnVoxelsTested) );
 
3781
        for lPos := 1 to lVolVoxels do 
 
3782
                if l32Buf^[lPos] > 0 then
 
3783
                         l32Buf^[lPos] := -log(abs(gammq(0.5, 0.5 * l32Buf^[lPos])),10)
 
3784
                else
 
3785
                        l32Buf^[lPos] :=0;
 
3786
        SaveAsVOIorNIFTI(lBufferAligned,lVolVoxels,4,1,false,lMRIcroHdr.NiftiHdr,'log10p'+inttostr(lnTotalThreshold));
 
3787
        //next - free float buffer
 
3788
        FreeMem(lBufferUnaligned);
 
3789
        StatusLabel.Caption := 'Voxels tested: '+inttostr(lnVoxelsTested);
 
3790
        //next - subtraction
 
3791
        GetMem(lBuffer ,(lVolVoxels ));
 
3792
        lNegativeNumbers := false;
 
3793
        fillchar(lBuffer^,lVolVoxels,100);
 
3794
        for lPos := 1 to lVolVoxels do begin
 
3795
                lYes[1] := gMRIcroOverlay[1].ScrnBuffer^[lPos];
 
3796
                lNo[1] := lTotal[1]-lYes[1];
 
3797
                lYes[2] := gMRIcroOverlay[2].ScrnBuffer^[lPos];
 
3798
                lNo[2] := lTotal[2]-lYes[2];
 
3799
                if (lYes[1] < 0) or (lNo[1] < 0) or (lYes[2] < 0) or (lNo[2] < 0) then
 
3800
                        lNegativeNumbers := true
 
3801
                else if (lYes[1] >0) or (lYes[2] > 0) then begin
 
3802
                        lBuffer^[lPos] := round((100* ((lYes[1]/lTotal[1])-(lYes[2]/lTotal[2])))+100);
 
3803
                end;//> threshold
 
3804
        end; //for each voxel
 
3805
        MakeStatHdr (gMRIcroOverlay[kBGOverlayNum],lMRIcroHdr,-100, 100,1,0,0,kNIFTI_INTENT_ESTIMATE,'%'+inttostr(lTotal[1])+':'+inttostr(lTotal[2]) );
 
3806
        lMRIcroHdr.NIFTIhdr.scl_inter:= -100;
 
3807
        if lNegativeNumbers then
 
3808
                Showmessage('Serious error: some group sizes were negative. This should be impossible with a subtraction analysis.');
 
3809
        SaveAsVOIorNIFTI(lBuffer,lVolVoxels,1,1,false,lMRIcroHdr.NiftiHdr,'Sub'+inttostr(lTotal[1])+'_'+inttostr(lTotal[2]));
 
3810
        FreeMem(lBuffer);
 
3811
end; //procedure Chisquare1Click
 
3812
 
 
3813
procedure TImgForm.ROIVOI1Click(Sender: TObject);
 
3814
var
 
3815
        lNumberofFiles,lC: integer;
 
3816
        lFilename: string;
 
3817
begin
 
3818
        if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 1 then begin
 
3819
                showmessage('Please load a background image (''File''/''Open'') before adding an overlay.');
 
3820
                exit;
 
3821
        end;
 
3822
        if gBGImg.Resliced then begin
 
3823
           if not HdrForm.OpenAndDisplayHdr(gMRIcroOverlay[kBGOverlayNum].HdrFileName,gMRIcroOverlay[kBGOverlayNum]) then exit;
 
3824
           if not OpenImg(gBGImg,gMRIcroOverlay[0],true,false,false,false,false) then exit;
 
3825
        end;
 
3826
        showmessage('Warning: the currently open background image must have the dimensions (size, space between slices, etc) as the image used when creating the ROIs.');
 
3827
        if gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems > 0 then
 
3828
                CloseVOIClick(nil);
 
3829
        if not OpenDialogExecute('MRIcro ROI (.roi)|*.roi','Select MRIcro format ROIs to convert',true) then exit;
 
3830
        lNumberofFiles:= HdrForm.OpenHdrDlg.Files.Count;
 
3831
        ProgressBar1.Min := 0;
 
3832
        ProgressBar1.Max :=lNumberofFiles;
 
3833
        ProgressBar1.Position := 0;
 
3834
        for lC:= 1 to lNumberofFiles do begin
 
3835
                lFilename := HdrForm.OpenHdrDlg.Files[lC-1];
 
3836
                OpenMRIcroROI (lFileName);
 
3837
                lFilename := changefileextX(lFilename,'.voi');
 
3838
                SaveAsVOIorNIFTIcore (lFilename, gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer,gMRIcroOverlay[kVOIOverlayNum].ScrnBufferItems, 1,1,gMRIcroOverlay[kBGOverlayNum].NiftiHdr);
 
3839
                CloseVOIClick(nil);
 
3840
                ProgressBar1.Position := lC;
 
3841
        end;
 
3842
        ProgressBar1.Position := 0;
 
3843
end;
 
3844
 
 
3845
procedure TImgForm.LUTinvertBtnClick(Sender: TObject);
 
3846
begin
 
3847
end; //proc LUTdropSelect
 
3848
 
 
3849
procedure TImgForm.LutFromZeroBtnClick(Sender: TObject);
 
3850
var
 
3851
   lLayer: integer;
 
3852
begin
 
3853
         lLayer := ActiveLayer;
 
3854
         gMRIcroOverlay[lLayer].LUTfromZero := LUTfromZeroBtn.down;
 
3855
         LUTdropLoad(lLayer);
 
3856
         RescaleImagesTimer.Enabled := true;
 
3857
end;
 
3858
 
 
3859
procedure TImgForm.ShowMultisliceClick(Sender: TObject);
 
3860
begin
 
3861
(*      if gBGImg.XBarClr = TColor(gMRIcroOverlay[kBGOverlayNum].LUTinvisible) then
 
3862
                MultiSliceForm.MultiImage.canvas.font.Color := clBlack//clWhite;//gLUT[lClr].rgbRed+(gLUT[lClr].rgbGreen shl 8)+(gLUT[lClr].rgbBlue shl 16);
 
3863
         else
 
3864
                MultiSliceForm.MultiImage.canvas.font.Color := gBGImg.XBarClr;*)
 
3865
        MultiSliceForm.Show;
 
3866
 //MultiSliceForm.BringToFront;
 
3867
end;
 
3868
 
 
3869
function RawBGIntensity(lPos: integer): single;
 
3870
var
 
3871
        l16Buf : SmallIntP;
 
3872
        l32Buf : SingleP;
 
3873
begin
 
3874
  result := 0;
 
3875
  if (lPos > gMRIcroOverlay[kBGOverlayNum].ImgBufferItems) or (lPos < 1) then exit;
 
3876
  if (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP  = 4) then begin
 
3877
        l32Buf := SingleP(gMRIcroOverlay[kBGOverlayNum].ImgBuffer );
 
3878
        result := l32Buf^[lPos];
 
3879
  end else if (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP  = 2) then begin
 
3880
           l16Buf := SmallIntP(gMRIcroOverlay[kBGOverlayNum].ImgBuffer );
 
3881
        result := l16Buf^[lPos];
 
3882
  end else if gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP  = 1 then
 
3883
         result := gMRIcroOverlay[kBGOverlayNum].ImgBuffer^[lPos]
 
3884
  else begin
 
3885
        showmessage('Unknown Background Buffer Bytes Per Pixel');
 
3886
        exit;
 
3887
  end;
 
3888
end;
 
3889
 
 
3890
procedure DescribeVOIonLabels (lOverlayNum: integer);
 
3891
var
 
3892
   lShowfilename: boolean = true;
 
3893
   lLocalMax,lLocalSum : HistoDoubleRA;
 
3894
   l16Buf : SmallIntP;
 
3895
   l32Buf : SingleP;
 
3896
   l8Buf: byteP;
 
3897
   lInten: double;
 
3898
   lXmm,lYmm,lZmm: single;
 
3899
   lHisto,lRegionVol,lLocalMaxPos: HistoRA;
 
3900
   lInc,lRegion: Integer;
 
3901
   lLabelStr: string;
 
3902
   lVOI: boolean;
 
3903
   lLabelStr20 : Array[0..kHistoBins] of kstr20;
 
3904
begin
 
3905
     lInten := 0;//just to hide compiler hint...
 
3906
     if (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP = 2) and ('ratlas.nii.gz' = (extractfilename( gMRIcroOverlay[kBGOverlayNum].HdrFileName))) then begin
 
3907
        //DescribeVOIonLabelsRAT(lOverlayNum,lShowFilename);
 
3908
        Showmessage('Please use Windows version.');
 
3909
        exit;
 
3910
     end;
 
3911
     if (gMRIcroOverlay[lOverlayNum].ScrnBufferItems <> gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems) or (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP <> 1) or (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 2) then
 
3912
        exit;
 
3913
     TextForm.Memo1.Lines.add(' Custom Region Analysis');
 
3914
     TextForm.Memo1.Lines.add(' For Speculative Brodmann Map: 0=not cortical and 48=no Brodmann label');
 
3915
     lVOI := IsVOIROIExt(gMRIcroOverlay[lOverlayNum].HdrFileName);
 
3916
     if (not lVOI) and (lOverlayNum = kVOIOverlayNum) then
 
3917
        lVOI := true;
 
3918
     //next describe format
 
3919
     if lShowfilename then
 
3920
        lLabelStr := ' Filename,'
 
3921
     else
 
3922
         lLabelStr := ' ';
 
3923
     if lVOI then //intensity min/max position are not important
 
3924
        TextForm.Memo1.Lines.add(lLabelStr+'Area,N>0,%N>0')
 
3925
     else
 
3926
         TextForm.Memo1.Lines.add(lLabelStr+'Area,N>0,%N>0,Sum>0,Mean>0,Max,MaxX,MaxY,MaxZ');
 
3927
   //next initialize
 
3928
   if lShowFilename then
 
3929
      lLabelStr := gMRIcroOverlay[lOverlayNum].HdrFileName+','
 
3930
   else
 
3931
       lLabelStr := '';
 
3932
     for lInc := 0 to kHistoBins do begin
 
3933
         lHisto[lInc] := 0;
 
3934
         lLocalMax[lInc] := 0;
 
3935
         lLocalSum[lInc] := 0;
 
3936
         lRegionVol[lInc] := 0;
 
3937
         if (gMRIcroOverlay[kBGOverlayNum].UsesCustomPalette) then
 
3938
            lLabelStr20[lInc] := gBGImg.LabelStr20[lInc]
 
3939
         else
 
3940
             lLabelStr20[lInc] := inttostr(lInc);
 
3941
     end;
 
3942
     for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do
 
3943
         if gMRIcroOverlay[lOverlayNum].ScrnBuffer^[lInc] > 0 then
 
3944
            inc(lHisto[gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc]]);
 
3945
     //local max start
 
3946
     l32Buf := SingleP(gMRIcroOverlay[lOverlayNum].ImgBuffer );
 
3947
     l16Buf := SmallIntP(gMRIcroOverlay[lOverlayNum].ImgBuffer );
 
3948
     //NEXT if..else July07 - ROIs only use screen buffer, not imgbuffer...
 
3949
     if gMRIcroOverlay[lOverlayNum].ScrnBufferItems = gMRIcroOverlay[lOverlayNum].ImgBufferItems then
 
3950
        l8Buf := gMRIcroOverlay[lOverlayNum].ImgBuffer
 
3951
     else
 
3952
         l8Buf := gMRIcroOverlay[lOverlayNum].ScrnBuffer;
 
3953
     for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do begin
 
3954
         if (gMRIcroOverlay[lOverlayNum].ImgBufferBPP  = 4) then
 
3955
           lInten := l32Buf^[lInc]
 
3956
         else if (gMRIcroOverlay[lOverlayNum].ImgBufferBPP  = 2) then
 
3957
              lInten := l16Buf^[lInc]
 
3958
         else if gMRIcroOverlay[lOverlayNum].ImgBufferBPP  = 1 then
 
3959
              lInten := l8Buf^[lInc];//July07
 
3960
         lRegion := gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc];
 
3961
         if lInten > 0 then
 
3962
            lLocalSum[lRegion] := lLocalSum[lRegion]+lInten;
 
3963
         if  lInten > lLocalMax[lRegion] then begin
 
3964
             lLocalMax[lRegion] := lInten;//intensity
 
3965
             lLocalMaxPos[lRegion] := lInc;//location
 
3966
         end;
 
3967
         inc(lRegionVol[lRegion]);
 
3968
     end;
 
3969
     for lInc := 0 to kHistoBins do  begin
 
3970
         if (not lVOI) and (lLocalMax[lInc] > 0) then begin
 
3971
            lLocalMax[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalMax[lInc]);
 
3972
            lLocalSum[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[lOverlayNum],lLocalSum[lInc]);
 
3973
            ImgPosToMM(lLocalMaxPos[lInc], lXmm,lYmm,lZmm);
 
3974
            TextForm.Memo1.Lines.Add(lLabelStr+ lLabelStr20[lInc] + ', ' + inttostr(lHisto[lInc])+','+floattostr( lHisto[lInc]/lRegionVol[lInc])
 
3975
               +','+floattostr( lLocalSum[lInc])+','+floattostr( lLocalSum[lInc]/lRegionVol[lInc]) //Sum>0, mean>0
 
3976
               +', ' + floattostr(lLocalMax[lInc])+','+floattostr(lXmm)+','+floattostr(lYmm)+','+floattostr(lZmm) );
 
3977
         end else if (lHisto[lInc] > 0) {necessarily also and (lRegionVol[lInc] > 0)} then
 
3978
                        TextForm.Memo1.Lines.Add(lLabelStr+ lLabelStr20[lInc] + ', ' + inttostr(lHisto[lInc])+','+floattostr( lHisto[lInc]/lRegionVol[lInc])) ;
 
3979
     end; //for each row
 
3980
end;
 
3981
 
 
3982
(*procedure DescribeVOIonLabels (lOverlayNum: integer);
 
3983
var
 
3984
        lHisto: HistoRA;
 
3985
        lInc: Integer;
 
3986
begin
 
3987
        if (gMRIcroOverlay[lOverlayNum].ScrnBufferItems <> gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems) or (gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP <> 1) or (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < 2) then
 
3988
                exit;
 
3989
        TextForm.Memo1.Lines.Add('');
 
3990
        TextForm.Memo1.Lines.add('Custom Region Analysis');
 
3991
        TextForm.Memo1.Lines.add(' For Speculative Brodmann Map, 0=not cortical, 48=no Brodmann label');
 
3992
        for lInc := 0 to 255 do
 
3993
                lHisto[lInc] := 0;
 
3994
        for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do
 
3995
                if gMRIcroOverlay[lOverlayNum].ScrnBuffer^[lInc] > 0 then
 
3996
                        inc(lHisto[gMRIcroOverlay[kBGOverlayNum].ScrnBuffer^[lInc]]);
 
3997
        for lInc := 0 to 255 do begin
 
3998
                if lHisto[lInc] > 0 then
 
3999
                        TextForm.Memo1.Lines.Add( gBGImg.LabelStr20[lInc] + ', ' + inttostr(lHisto[lInc]) );
 
4000
 
 
4001
        end;
 
4002
end;   *)
 
4003
 
 
4004
procedure TImgForm.DescriptiveMenuItemClick(Sender: TObject);
 
4005
var
 
4006
        lROIVol: array [1..3] of integer;
 
4007
        lInc,lOverlayNum,lImgSz: integer;
 
4008
        lCenterOfMass,lROISum,lROISumSqr,lROImin,lROImax:array [1..3] of double;
 
4009
        lCC,lVal,lSD,lROImean: double;
 
4010
        lStr: string;
 
4011
procedure  AddVal( lRA: integer);
 
4012
begin
 
4013
                        inc(lROIVol[lRA]);
 
4014
                        lROISum[lRA] := lROISum[lRA]+lVal;
 
4015
                        lROISumSqr[lRA] := lROISumSqr[lRA] + sqr(lVal);
 
4016
                        if lVal > lROImax[lRA] then
 
4017
                                lROImax[lRA] := lVal;
 
4018
                        if lVal < lROImin[lRA] then
 
4019
                                lROImin[lRA] := lVal;
 
4020
end;
 
4021
begin
 
4022
        lImgSz := 0;
 
4023
        for lOverlayNum := 1 to knMaxOverlay do
 
4024
                if gMRIcroOverlay[lOverlayNum].ScrnBufferItems > lImgSz then
 
4025
                        lImgSz := gMRIcroOverlay[lOverlayNum].ScrnBufferItems;
 
4026
        if (lImgSz < 1) or (gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems < lImgSz) then begin
 
4027
                Showmessage('You need to create or load an overlay (Overlay/Open or Draw/OpenVOI) to get overlay statistics.');
 
4028
                exit;
 
4029
        end;
 
4030
 TextForm.Memo1.Lines.Clear;
 
4031
 for lOverlayNum := 1 to knMaxOverlay do begin
 
4032
   if gMRIcroOverlay[lOverlayNum].ScrnBufferItems = gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems then begin
 
4033
        for lInc := 1 to 3 do begin
 
4034
                lROIVol[lInc] := 0;
 
4035
                lROISum[lInc] := 0;
 
4036
                lROISumSqr[lInc] := 0;
 
4037
                lROImin[lInc] := maxint;
 
4038
                lROImax[lInc] := -maxint;
 
4039
 
 
4040
        end;
 
4041
        for lInc := 1 to gMRIcroOverlay[lOverlayNum].ScrnBufferItems do begin
 
4042
                if gMRIcroOverlay[lOverlayNum].ScrnBuffer^[lInc] > 0 then begin
 
4043
                        lVal := RawBGIntensity(lInc);
 
4044
                        AddVal(1);
 
4045
                        if lVal <> 0 then
 
4046
                                AddVal(2);
 
4047
                        if lVal > 0 then
 
4048
                                AddVal(3);
 
4049
                end; //if VOI voxel
 
4050
        end; //for each voxel
 
4051
        //next - compute StDev
 
4052
        //compute descriptives for each set of values
 
4053
        TextForm.Memo1.Lines.Add('Overlay '+gMRIcroOverlay[lOverlayNum].HdrFileName);
 
4054
        if  CenterOfMass (lOverlayNum, lCenterOfMass[1],lCenterOfMass[2],lCenterOfMass[3]) > 0 then
 
4055
            TextForm.Memo1.Lines.Add(' Center of mass XYZ '+RealToStr(lCenterOfMass[1],2)+'x'+RealToStr(lCenterOfMass[2],2)+'x'+RealToStr(lCenterOfMass[3],2));
 
4056
        for lInc := 1 to 3 do begin
 
4057
                if lROIVol[lInc] > 1 then begin
 
4058
                        lSD := (lROISumSqr[lInc] - ((Sqr(lROISum[lInc]))/lROIVol[lInc]));
 
4059
                        if  (lSD > 0) then
 
4060
                                lSD :=  Sqrt ( lSD/(lROIVol[lInc]-1))
 
4061
                        else
 
4062
                                lSD := 0;
 
4063
                end else
 
4064
                        lSD := 0;
 
4065
                //next compute mean
 
4066
                if lROIVol[lInc] > 0 then
 
4067
                        lROImean := lROISum[lInc]/lROIVol[lInc]
 
4068
                else
 
4069
                        lROImean := 0;
 
4070
                //next - calibrate values
 
4071
                lROImin[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[kBGOverlayNum],lROImin[lInc]);
 
4072
                lROIMean := Raw2ScaledIntensity (gMRIcroOverlay[kBGOverlayNum],lROIMean);
 
4073
                lROImax[lInc] := Raw2ScaledIntensity (gMRIcroOverlay[kBGOverlayNum],lROImax[lInc]);
 
4074
                lSD := Raw2ScaledIntensity (gMRIcroOverlay[kBGOverlayNum],lSD);
 
4075
                lcc := ((lROIVol[lInc]/1000)*gBGImg.ScrnMM[1]*gBGImg.ScrnMM[2]*gBGImg.ScrnMM[3]);
 
4076
                case lInc of
 
4077
                        3: lStr := 'VOI  >0 ';
 
4078
                        2: lStr := 'VOI <>0 ';
 
4079
                        else lStr := 'VOI     ';
 
4080
                end;
 
4081
                lStr := lStr+' n=min/mean/max=SD: '+inttostr(round(lROIVol[lInc]))+'['+RealToStr(lCC,2)+'cc]='+RealToStr(lROIMin[lInc],4)+'/'+realToStr(lROIMean,4)+'/'+realToStr(lROIMax[lInc],4)+'='+realtostr(lSD,4);
 
4082
                TextForm.Memo1.Lines.Add(lStr);
 
4083
        end;
 
4084
        if      gMRIcroOverlay[kBGOverlayNum].UsesCustomPalette then
 
4085
                DescribeVOIonLabels(lOverlayNum);
 
4086
        TextForm.Memo1.Lines.Add('');
 
4087
   end; //overlaynum loaded
 
4088
 end; //for each overlay
 
4089
        TextForm.Show;
 
4090
end;
 
4091
 
 
4092
procedure TImgForm.FormResize(Sender: TObject);
 
4093
begin
 
4094
     if not ImgForm.visible then
 
4095
        exit;
 
4096
     RefreshImagesTimer.enabled := true;
 
4097
end;
 
4098
 
 
4099
function ParamStrFilename (var lParamPos: integer): string;
 
4100
var
 
4101
        I: integer;
 
4102
        lStr: string;
 
4103
begin
 
4104
  result := '';
 
4105
  if (ParamCount < lParamPos) then exit;
 
4106
  I := lParamPos;
 
4107
  repeat
 
4108
                if I = lParamPos then
 
4109
                        lStr := ParamStr(I)
 
4110
                else
 
4111
                        lStr := lStr +' '+ ParamStr(I);
 
4112
                inc(I);
 
4113
  until (I>ParamCount) or (fileexistsex(lStr));
 
4114
  lParamPos := I;
 
4115
  if fileexistsex(lStr) then
 
4116
        result := lStr;
 
4117
end;
 
4118
 
 
4119
 
 
4120
 
 
4121
procedure TImgForm.FormShow(Sender: TObject);
 
4122
var
 
4123
   lStr: String;
 
4124
   lMaximize,lRender,lMultislice : boolean;
 
4125
   lCommandChar: Char;
 
4126
   I,lError,lOverlayNum,lInc,lLUT: integer;
 
4127
   lSingle: single;
 
4128
procedure ReadCmdVal;//nested
 
4129
begin
 
4130
                   inc(I);
 
4131
                   lStr := ParamStr(I);
 
4132
  {$IFNDEF FPC}
 
4133
                   lStr := string(StrUpper(PChar(lStr))) ;
 
4134
  {$ELSE}
 
4135
     {$IFNDEF UNIX}
 
4136
                   lStr := UpCase(lStr); //unix file names are case specific /EXAMPLE/ATTENTION.NII <> /Example/Attention
 
4137
     {$ENDIF}
 
4138
  {$ENDIF}
 
4139
end; //nested ReadCmdVal
 
4140
begin
 
4141
  //gBGIMg.SaveDefaultIni := true;
 
4142
  {$IFDEF Darwin}
 
4143
  //Darwin starts passing a strange paramstr....
 
4144
  //ImgForm.OpenTemplateMRU(nil);
 
4145
  //RefreshImagesTimer.enabled := true;
 
4146
  //with Darwin, opening a file can interfere with opening by association...
 
4147
  exit;
 
4148
  //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');
 
4149
  {$ENDIF}
 
4150
 
 
4151
 if (ParamCount  < 1) then begin
 
4152
                ImgForm.OpenTemplateMRU(nil);
 
4153
                RefreshImagesTimer.enabled := true;
 
4154
                //Graph4DForm.show;//abba
 
4155
                               exit;
 
4156
 
 
4157
        end;
 
4158
        lMaximize := false;
 
4159
        lRender := false;
 
4160
        lMultislice := false;
 
4161
        lOverlayNum := 0;
 
4162
        I := 1;
 
4163
        lStr := ParamStrFilename(I);
 
4164
        if lStr <> '' then
 
4165
                OpenAndDisplayImg(lStr,True)
 
4166
         else begin //no requested image
 
4167
                OpenTemplateMRU(nil);
 
4168
                I := 1;//exit;
 
4169
        end;
 
4170
        I := I-1;
 
4171
                //ShowMultisliceClick(nil);
 
4172
        if I >= ParamCount then exit;
 
4173
        gBGIMg.SaveDefaultIni := false; //do not store changes loaded by script
 
4174
        repeat
 
4175
         lStr := '';
 
4176
         repeat
 
4177
                inc(I);
 
4178
                if I = 1 then
 
4179
                        lStr := ParamStr(I)
 
4180
                else begin
 
4181
                        if lStr <> '' then
 
4182
                           lStr := lStr +' '+ ParamStr(I)
 
4183
                        else
 
4184
                                lStr := ParamStr(I);
 
4185
                end;
 
4186
                if (length(lStr)>1) and (lStr[1] = '-')  then begin //special command
 
4187
                   lCommandChar := UpCase(lStr[2]);
 
4188
                   case lCommandChar of
 
4189
                                'B': begin //background transparency
 
4190
                                                  ReadCmdVal;
 
4191
                                                  Val(lStr,lSingle,lError);
 
4192
                                                  if lError = 0 then
 
4193
                                                        gBGImg.BGTransPct  := round(lSingle);
 
4194
                                                                 SetSubmenuWithTag(BGTransPctMenu, gBGImg.BGTransPct);
 
4195
                                        end;
 
4196
                                'C': begin //color look up table
 
4197
                                        ReadCmdVal;
 
4198
                                        if (Length(lStr)>1) then begin
 
4199
                                          if lStr[1] = '-' then begin //LUT index number
 
4200
                                                  Val(lStr,lSingle,lError);
 
4201
                                                  if lError = 0 then
 
4202
                                                        lLUT := abs(round(lSingle))
 
4203
                                                  else
 
4204
                                                        lLUT := -1;
 
4205
                                          end else begin
 
4206
                                                lStr := ParseFileName(ExtractFileName(lStr));
 
4207
                                                {$IFDEF UNIX}
 
4208
                                                lStr := UpCase(lStr);
 
4209
                                                {$ENDIF}
 
4210
                                                lLUT := -1;
 
4211
                                                for lInc := 1 to (LUTdrop.Items.Count-1) do
 
4212
                                                  if lStr = string(StrUpper(PChar(LUTdrop.Items.Strings[lINc]))) then
 
4213
                                                        lLUT := lInc;
 
4214
                                          end; //else text LUTname
 
4215
                                          if lLUT >= 0 then begin
 
4216
                                                gMRIcroOverlay[lOverlayNum].LUTindex := lLUT;
 
4217
                                                LUTdropLoad(lOverlayNum);
 
4218
                                          end;
 
4219
                                        end; //str length > 1
 
4220
                                end;
 
4221
                                'D': gBGIMg.SaveDefaultIni := true;
 
4222
                                'F': gBGImg.ResliceOnLoad := false; //turn off reslicing... loads files flat
 
4223
    'H': begin
 
4224
                                                  ReadCmdVal;
 
4225
                                                  Val(lStr,lSingle,lError);
 
4226
                                                  if lError = 0 then
 
4227
                                                                 gMRIcroOverlay[lOverlayNum].WindowScaledMax  := (lSingle);
 
4228
                                        end;
 
4229
                                'L': begin //Low intensity scale
 
4230
                                                  ReadCmdVal;
 
4231
                                                  Val(lStr,lSingle,lError);
 
4232
                                                  if lError = 0 then
 
4233
                                                                 gMRIcroOverlay[lOverlayNum].WindowScaledMin  := (lSingle);
 
4234
                                        end;
 
4235
                                'M': begin //multislice
 
4236
                                                lMultislice := true;
 
4237
                                                ReadCmdVal;
 
4238
                                                if (lStr <> '') and (lStr <> '-')and (FileexistsEx(lStr)) and (lOverlayNum < (knMaxOverlay-1)) then
 
4239
                                                        gMultiSliceStartupFilename := (lStr);
 
4240
 
 
4241
                                         end; //if 'M'
 
4242
                                'O': begin//Overlay
 
4243
                                                   ReadCmdVal;
 
4244
                                                   //Showmessage('o'+lStr);
 
4245
                                             if (lStr <> '') and (FileexistsEx(lStr)) and (lOverlayNum < (knMaxOverlay-1)) then begin
 
4246
                                                   //Showmessage('oexists'+lStr);
 
4247
                                                        inc(lOverlayNum);
 
4248
                                                        OverlayOpenCore (lStr,lOverlayNum);
 
4249
                                                end;
 
4250
                                         end; //if 'O'
 
4251
                                'R': begin//Overlay
 
4252
                                                lRender := true;//Render
 
4253
                                                ReadCmdVal;
 
4254
                                                if (lStr <> '') and (lStr <> '-')and (FileexistsEx(lStr)) and (lOverlayNum < (knMaxOverlay-1)) then
 
4255
                                                        gRenderStartupFilename := (lStr);
 
4256
                                         end; //if 'R'
 
4257
                                'S': begin //smooth
 
4258
                                        ReadCmdVal;
 
4259
                                        Val(lStr,lSingle,lError);
 
4260
                                        if lError = 0 then begin
 
4261
                                                if odd(round(lSingle)) then begin
 
4262
                                                        gBGImg.StretchQuality := sqHigh;
 
4263
                                                        Menu2DSmooth.checked := true;
 
4264
                                                end else begin
 
4265
                                                        gBGImg.StretchQuality := sqLow;
 
4266
                                                        Menu2DSmooth.checked := false;
 
4267
                                                end;
 
4268
                                                if lSingle > 1 then
 
4269
                                                        gBGIMg.OverlaySmooth := true
 
4270
                                                else
 
4271
                                                        gBGIMg.OverlaySmooth := false;
 
4272
                                                OverlaySmoothMenu.Checked := gBGIMg.OverlaySmooth;
 
4273
                                        end;//error=0
 
4274
                                end;
 
4275
                                'T': begin //overlay transparency
 
4276
                                                  ReadCmdVal;
 
4277
                                                  Val(lStr,lSingle,lError);
 
4278
                                                  if lError = 0 then
 
4279
                                                                 gBGImg.OverlayTransPct  := round(lSingle);
 
4280
  SetSubmenuWithTag(OverlayTransPctMenu, gBGImg.OverlayTransPct);
 
4281
                                end;
 
4282
                                'V': begin //open voi
 
4283
                                                  ReadCmdVal;
 
4284
                                                if (lStr <> '') and (FileexistsEx(lStr)) then
 
4285
                                                OpenVOICore(lStr);
 
4286
                                        end;
 
4287
                                'X': lMaximize := true; //open maximized
 
4288
                                'Z': gMRIcroOverlay[lOverlayNum].LUTfromZero := true;
 
4289
                   end; //case lStr[2]
 
4290
                   lStr := '';
 
4291
                end; //special command
 
4292
         until (I=ParamCount) or (fileexists(lStr)) {or (gAbort)};
 
4293
        until I >= ParamCount;
 
4294
   LayerDropSelect(nil);
 
4295
   for lInc := 0 to lOverlayNum do
 
4296
         RescaleImgIntensity(gBGImg,gMRIcroOverlay[lInc],lINc);
 
4297
         RefreshImages;
 
4298
   if lMultiSlice then
 
4299
                ShowMultisliceClick(nil);
 
4300
   if lRender then
 
4301
                ShowRenderClick(nil);
 
4302
   if lMaximize then begin
 
4303
           ImgForm.WindowState := wsMaximized;
 
4304
          RefreshImagesTimer.enabled := true;
 
4305
   end;
 
4306
end;
 
4307
 
 
4308
 
 
4309
procedure TImgForm.FlipLRmenuClick(Sender: TObject);
 
4310
var
 
4311
        lC: integer;
 
4312
        lStr: string;
 
4313
begin
 
4314
        (sender as TMenuItem).checked := not (sender as TMenuItem).checked;
 
4315
         gBGImg.Mirror := (sender as TMenuItem).checked ;
 
4316
         gBGImg.VOImirrored := true;
 
4317
         for lC := 0 to knMaxOverlay do
 
4318
                if gMRIcroOverlay[lC].ScrnBufferItems > 0 then
 
4319
                        RescaleImgIntensity(gBGImg,gMRIcroOverlay[lC],lC);
 
4320
         RefreshImagesTimer.Enabled := true;
 
4321
        if gBGImg.Mirror then
 
4322
                lStr := 'radiological [right on left side]'
 
4323
        else
 
4324
                lStr := 'neurological [left on left side]';
 
4325
        showmessage('Warning: left-right flips can be confusing. From now on, this software will attempt to show NIfTI images in '+lStr+' orientation.');
 
4326
        if MultiSliceForm.Visible then
 
4327
           MultiSliceForm.CreateMultiSlice;
 
4328
end;
 
4329
 
 
4330
procedure TImgForm.Menu2DSmoothClick(Sender: TObject);
 
4331
begin
 
4332
        if Sender <> nil then
 
4333
                (sender as TMenuItem).checked := not (sender as TMenuItem).checked;
 
4334
         if Menu2DSmooth.checked then
 
4335
                 gBGImg.StretchQuality := sqHigh
 
4336
         else
 
4337
                  gBGImg.StretchQuality := sqLow;
 
4338
         RefreshImagesTimer.Enabled := true;
 
4339
end;
 
4340
 
 
4341
procedure TImgForm.VALclick(Sender: TObject);
 
4342
begin
 
4343
        //ComputeValFile( (sender as Tmenuitem).tag);
 
4344
end;
 
4345
 
 
4346
procedure TImgForm.VOI2NIIClick(Sender: TObject);
 
4347
var
 
4348
        lNumberofFiles,lC: integer;
 
4349
        lFilename: string;
 
4350
begin
 
4351
        CloseImagesClick(nil);
 
4352
        if not OpenDialogExecute('VOI Drawings (.VOI)|*.VOI','Select VOI format images to convert',true) then exit;
 
4353
        lNumberofFiles:= HdrForm.OpenHdrDlg.Files.Count;
 
4354
        ProgressBar1.Min := 0;
 
4355
        ProgressBar1.Max :=lNumberofFiles;
 
4356
        ProgressBar1.Position := 0;
 
4357
        for lC:= 1 to lNumberofFiles do begin
 
4358
                lFilename := HdrForm.OpenHdrDlg.Files[lC-1];
 
4359
                OpenAndDisplayImg(lFilename,True);
 
4360
                lFilename := changefileextx(lFilename,'.nii');
 
4361
                //SaveAsVOIorNIFTIcore (lFilename, lByteP, lVoxels, 1, gMRIcroOverlay[kBGOverlayNum].NiftiHdr);
 
4362
                SaveAsVOIorNIFTIcore (lFilename, gMRIcroOverlay[kBGOverlayNum].ScrnBuffer,gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems, 1,1,gMRIcroOverlay[kBGOverlayNum].NiftiHdr);
 
4363
                CloseVOIClick(nil);
 
4364
                ProgressBar1.Position := lC;
 
4365
        end;
 
4366
        ProgressBar1.Position := 0;
 
4367
end;//VOI->NII
 
4368
 
 
4369
procedure TImgForm.TtoP1Click(Sender: TObject);
 
4370
var
 
4371
        lBufferAligned,lBufferUnAligned: ByteP;
 
4372
        l32Buf,l32BufSrc : SingleP;
 
4373
        l16BufSrc : SmallIntP;
 
4374
        lSlope,lIntercept: single;
 
4375
        lMRIcroHdr: TMRIcroHdr;
 
4376
        lVolVoxels,lPos: integer;
 
4377
begin
 
4378
//alfa - currently open image
 
4379
        lVolVoxels := gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems;
 
4380
        if lVolVoxels < 1 then begin
 
4381
                showmessage('Please load a background image (''File''/''Open'') before adding an overlay.');
 
4382
                exit;
 
4383
        end;
 
4384
        GetMem(lBufferUnaligned ,(lVolVoxels *sizeof(single) )+16);
 
4385
        //lBufferAligned := ByteP($fffffff0 and (integer(lBufferUnaligned)+15));
 
4386
        lBufferAligned := system.align(lBufferUnaligned, 16);
 
4387
        l32Buf := SingleP(lBufferAligned);
 
4388
        //next load values
 
4389
        case gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP of
 
4390
                4: begin
 
4391
                   l32BufSrc := SingleP(gMRIcroOverlay[kBGOverlayNum].ImgBuffer );
 
4392
                   for lPos := 1 to lVolVoxels do
 
4393
                                l32Buf^[lPos] := l32BufSrc^[lPos];
 
4394
                end;
 
4395
                2: begin
 
4396
                   l16BufSrc := SmallIntP(gMRIcroOverlay[kBGOverlayNum].ImgBuffer );
 
4397
                   for lPos := 1 to lVolVoxels do
 
4398
                                l32Buf^[lPos] := l16BufSrc^[lPos];
 
4399
                end;
 
4400
                1: begin
 
4401
                   for lPos := 1 to lVolVoxels do
 
4402
                                l32Buf^[lPos] := gMRIcroOverlay[kBGOverlayNum].ImgBuffer^[lPos];
 
4403
                end;
 
4404
                else begin
 
4405
                        showmessage('unknown datatype');
 
4406
                end;
 
4407
        end;
 
4408
        //next calibrate values
 
4409
        lSlope := gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.scl_slope;
 
4410
        lIntercept := gMRIcroOverlay[kBGOverlayNum].NIFTIhdr.scl_inter;
 
4411
        if (lSlope=0) or ((lSlope=1) and (lIntercept=0)) then
 
4412
                //no slope
 
4413
        else begin
 
4414
        for lPos := 1 to lVolVoxels do
 
4415
                                l32Buf^[lPos] := (l32Buf^[lPos] * lSlope)+lIntercept;
 
4416
        end;
 
4417
        //next - save log10 p values...
 
4418
        MakeStatHdr (gMRIcroOverlay[kBGOverlayNum],lMRIcroHdr,0, 255,1{df},0,666,NIFTI_INTENT_LOG10PVAL,inttostr(666) );
 
4419
        for lPos := 1 to lVolVoxels do
 
4420
                if l32Buf^[lPos] > 0 then
 
4421
                         l32Buf^[lPos] := -log(abs(pTdistr(42,l32Buf^[lPos])),10)
 
4422
                else
 
4423
                        l32Buf^[lPos] :=0;
 
4424
        SaveAsVOIorNIFTI(lBufferAligned,lVolVoxels,4,1,false,lMRIcroHdr.NiftiHdr,'log10p'+inttostr(666));
 
4425
        //next - free float buffer
 
4426
        FreeMem(lBufferUnaligned);
 
4427
end;
 
4428
 
 
4429
procedure TImgForm.DesignVALClick(Sender: TObject);
 
4430
begin
 
4431
        //SpreadForm.Show;
 
4432
end;
 
4433
 
 
4434
procedure TImgForm.Up1Click(Sender: TObject);
 
4435
var lVolVox,lPos,lShift: integer;
 
4436
begin
 
4437
  if gMRIcroOverlay[kBGOverlayNum].ScrnBufferItems=0 then begin
 
4438
        showmessage('You must have open a background image in order to apply an intensity filter (use File/Open).');
 
4439
        exit;
 
4440
  end;
 
4441
  if not IsVOIOpen then begin
 
4442
         ShowMessage('You have not created or opened a region of interest.');
 
4443
         exit;
 
4444
   end;
 
4445
   CreateUndoVol;//create gBGImg.VOIUndoVol
 
4446
   Move(gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer^,gBGImg.VOIUndoVol^,gBGImg.VOIUndoVolItems);
 
4447
   lVolVox := gBGImg.ScrnDim[1]* gBGImg.ScrnDim[2]*gBGImg.ScrnDim[3];
 
4448
   case (Sender as TMenuItem).tag of
 
4449
                0: lShift := 1;
 
4450
                1: lShift := -1;
 
4451
                2: lShift :=  gBGImg.ScrnDim[1];
 
4452
                3: lShift :=  -gBGImg.ScrnDim[1];
 
4453
                4: lShift :=  gBGImg.ScrnDim[1]*gBGImg.ScrnDim[2];
 
4454
                5: lShift :=  -gBGImg.ScrnDim[1]*gBGImg.ScrnDim[2];
 
4455
   end;
 
4456
   if lShift > 0 then begin
 
4457
          for lPos := 1 to (lVolVox-lShift) do
 
4458
                 gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer[lPos] := gBGImg.VOIUndoVol[lPos+lShift];
 
4459
   end else begin
 
4460
                for lPos := (1+abs(lShift)) to lVolVox do
 
4461
                        gMRIcroOverlay[kVOIOverlayNum].ScrnBuffer[lPos] := gBGImg.VOIUndoVol[lPos+lShift];
 
4462
   end;
 
4463
   gBGImg.VOIchanged := true;
 
4464
   ImgForm.ProgressBar1.Position := 0;
 
4465
   ImgForm.RefreshImagesTimer.Enabled := true;
 
4466
end;
 
4467
 
 
4468
 
 
4469
procedure TImgForm.FormDestroy(Sender: TObject);
 
4470
begin
 
4471
{$IFDEF Darwin}
 
4472
 FormClose(nil); //OSX does not send a FormClose Event if you choose the Application/Quit option
 
4473
{$ENDIF}
 
4474
        CloseShareMem;
 
4475
end;
 
4476
 
 
4477
procedure TImgForm.YokeMenuClick(Sender: TObject);
 
4478
begin
 
4479
        (sender as TMenuItem).checked := not (sender as TMenuItem).checked;
 
4480
         gYoke := (sender as TMenuItem).checked ;
 
4481
         YokeTimer.Enabled := gYoke;
 
4482
end;
 
4483
 
 
4484
procedure TImgForm.About1Click(Sender: TObject);
 
4485
//var
 
4486
//lLoop: integer;
 
4487
begin
 
4488
     //for lLoop := 1 to 4 do
 
4489
     //    RefreshImagesTImer.enabled := true;
 
4490
      //  exit;
 
4491
        //290 347 fx(TriplePanel.Width,TriplePanel.Width);
 
4492
        AboutForm.ThreadLabel.Caption := '  '+inttostr(gnCPUThreads)+' threads';
 
4493
     AboutForm.Showmodal;
 
4494
end;
 
4495
procedure TImgForm.LayerDropChange(Sender: TObject);
 
4496
begin
 
4497
     {$IFDEF LCLgtk2}
 
4498
     LayerDropSelect(nil);
 
4499
     {$ENDIF}
 
4500
end;
 
4501
 
 
4502
procedure TImgForm.LUTdropChange(Sender: TObject);
 
4503
begin
 
4504
     {$IFDEF LCLgtk2}
 
4505
     LutDropSelect(nil);
 
4506
     {$ENDIF}
 
4507
end;
 
4508
 
 
4509
procedure TImgForm.AdjustimagessoVOIintensityiszero1Click(Sender: TObject);
 
4510
begin
 
4511
    BatchChangeInterceptSoVOIEqualsZero;
 
4512
end;
 
4513
 
 
4514
procedure TImgForm.MirrorNII1Click(Sender: TObject);
 
4515
var
 
4516
        lNumberofFiles,lC: integer;
 
4517
        lFilename: string;
 
4518
begin
 
4519
        Showmessage('WARNING: This will flip the images in the Left-Right dimension: this has serious consequences');
 
4520
        CloseImagesClick(nil);
 
4521
        if not OpenDialogExecute(kImgFilter,'Select NIfTI format images to convert',true) then exit;
 
4522
        lNumberofFiles:= HdrForm.OpenHdrDlg.Files.Count;
 
4523
        ProgressBar1.Min := 0;
 
4524
        ProgressBar1.Max :=lNumberofFiles;
 
4525
        ProgressBar1.Position := 0;
 
4526
        for lC:= 1 to lNumberofFiles do begin
 
4527
                lFilename := HdrForm.OpenHdrDlg.Files[lC-1];
 
4528
                ImgForm.OpenAndDisplayImg(lFilename,True);
 
4529
                lFilename := changefileextX(lFilename,'lr.nii.gz');
 
4530
                //zap
 
4531
                //showmessage(lFilename);
 
4532
                if MirrorImgBuffer (gMRIcroOverlay[kBGOverlayNum] ) then begin
 
4533
                   //showmessage(lFilename);
 
4534
                   SaveAsVOIorNIFTIcore (lFilename, gMRIcroOverlay[kBGOverlayNum].ImgBuffer,gMRIcroOverlay[kBGOverlayNum].ImgBufferItems,gMRIcroOverlay[kBGOverlayNum].ImgBufferBPP,1,gMRIcroOverlay[kBGOverlayNum].NiftiHdr);
 
4535
                end;
 
4536
                CloseVOIClick(nil);
 
4537
                ProgressBar1.Position := lC;
 
4538
        end;
 
4539
        ProgressBar1.Position := 0;
 
4540
 
 
4541
end;
 
4542
 
 
4543
procedure TImgForm.ZoomDropChange(Sender: TObject);
 
4544
begin
 
4545
     {$IFDEF LCLgtk2}
 
4546
     ZoomDropSelect(nil);
 
4547
     {$ENDIF}
 
4548
end;
 
4549
 
 
4550
 
 
4551
 
 
4552
procedure TImgForm.ResizeControlPanel (lRows: integer);
 
4553
begin
 
4554
  if lRows = 2 then begin
 
4555
    ControlPanel.Tag := 2;
 
4556
    LayerPanel.Top := 36;
 
4557
    LayerPanel.Left := 1;
 
4558
 
 
4559
    ControlPanel.Height := 72;
 
4560
 
 
4561
    HideROIBtn.left := 307;
 
4562
    XBarBtn.Left := 307+29;
 
4563
    ToolPanel.Left := 307+61;
 
4564
  end else begin
 
4565
    ControlPanel.Tag := 1;
 
4566
    LayerPanel.Top := 1;
 
4567
    LayerPanel.Left := 307;
 
4568
    HideROIBtn.left := 809;
 
4569
    XBarBtn.Left := 809+29;
 
4570
    ToolPanel.Left := 809+61;
 
4571
    ControlPanel.Height := 40;
 
4572
  end;
 
4573
end;
 
4574
 
 
4575
procedure TImgForm.ControlPanelDblClick(Sender: TObject);
 
4576
begin
 
4577
  if ControlPanel.Tag = 1 then
 
4578
    ResizeControlPanel(2)
 
4579
  else
 
4580
    ResizeControlPanel(1);
 
4581
  ImgForm.RefreshImagesTimer.enabled := true;
 
4582
end;
 
4583
 
 
4584
procedure TImgForm.DefaultControlPanel;
 
4585
begin
 
4586
  if gBGImg.SingleRow then begin
 
4587
      ResizeControlPanel(1);
 
4588
      ImgForm.Width := 1025;
 
4589
      ImgForm.Height :=  469;
 
4590
  end else begin
 
4591
    ResizeControlPanel(2);
 
4592
      ImgForm.Width := 524;
 
4593
      ImgForm.Height :=  640;
 
4594
   end;
 
4595
end;
 
4596
 
 
4597
  {$IFDEF FPC}
 
4598
initialization
 
4599
  {$I nifti_img_view.lrs}
 
4600
{$ENDIF}
 
4601
  for gMouseDownY := 0 to knMaxOverlay do
 
4602
    gMRIcroOverlay[gMouseDownY].index := gMouseDownY; //RGB
 
4603
 
 
4604
end.