1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * filename: m-matrix.c                                                    *
3  *                                                                         *
4  * UTIL C-source: Medical Image Conversion Utility                         *
5  *                                                                         *
6  * purpose      : CTI source for handling ECAT 6.4 files                   *
7  *                                                                         *
8  * project      : (X)MedCon by Erik Nolf                                   *
9  *                                                                         *
10  * Notes        : Source code addapted from CTI PET Systems, Inc.          *
11  *                Original code 2.6 10/19/93  Copyright 1989-1993          *
12  *                                                                         *
13  *                Changed code for swapping & the use of our data types    *
14  *                with machine independency as target                      *
15  *                                                                         *
16  *                Put "mdc" prefix on functions and structs to prevent     *
17  *                naming conflicts with other tools based on CTI code      *
18  *                                                                         *
19  *                Added functions for ECAT 7 reading support               *
20  *                                                                         *
21  * Original CTI Authors listed:                                            *
22  *   E. Phearson                                                           *
23  *   L. Davis                                                              *
24  *   Yaorong                                                               *
25  *                                                                         *
26  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27 /*
28  */
29 
30 /*
31    Copyright (C) 1997-2021 by Erik Nolf
32 
33    This program is free software; you can redistribute it and/or modify it
34    under the terms of the GNU General Public License as published by the
35    Free Software Foundation; either version 2, or (at your option) any later
36    version.
37 
38    This program is distributed in the hope that it will be useful, but
39    WITHOUT ANY WARRANTY; without even the implied warranty of
40    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
41    Public License for more details.
42 
43    You should have received a copy of the GNU General Public License along
44    with this program; if not, write to the Free Software Foundation, Inc.,
45    59 Place - Suite 330, Boston, MA 02111-1307, USA.  */
46 
47 /****************************************************************************
48                               H E A D E R S
49 ****************************************************************************/
50 
51 #include "m-depend.h"
52 
53 #include <stdio.h>
54 #ifdef HAVE_STDLIB_H
55 #include <stdlib.h>
56 #endif
57 #ifdef HAVE_STRING_H
58 #include <string.h>
59 #endif
60 #ifdef HAVE_STRINGS_H
61 #ifndef _WIN32
62 #include <strings.h>
63 #endif
64 #endif
65 
66 #include "medcon.h"
67 
68 /***************************************************************************
69                               D E F I N E S
70 ***************************************************************************/
71 
72 struct ExpMatDir {
73         int matnum;
74         int strtblk;
75         int endblk;
76         int matstat;
77         float anatloc;
78 };
79 
80 /****************************************************************************
81                             F U N C T I O N S
82 ****************************************************************************/
83 
84 
85 /*********************************************************/
mdc_mat_open(fname,fmode)86 FILE *mdc_mat_open( fname, fmode)
87   char *fname, *fmode;
88 {
89   FILE *fptr;
90 
91   fptr = fopen(fname, fmode);
92   return (fptr);
93 
94 }
95 /*********************************************************/
mdc_mat_close(fptr)96 void mdc_mat_close( fptr)
97   FILE *fptr;
98 {
99   MdcCloseFile( fptr);
100 }
101 /*********************************************************/
mdc_mat_rblk(fptr,blkno,bufr,nblks)102 Int32 mdc_mat_rblk( fptr, blkno, bufr, nblks)
103   FILE *fptr;
104   Int32 blkno, nblks;
105   Uint8 *bufr;
106 {
107   int r;
108   fseek( fptr, (blkno-1)*MdcMatBLKSIZE, 0);
109   r = fread( bufr, 1, (unsigned)(nblks*MdcMatBLKSIZE), fptr);
110   if (r != (nblks*MdcMatBLKSIZE)) return(-1);
111 
112   return (0);
113 }
114 /*********************************************************/
115 
mdc_mat_list(fptr,mlist,lmax)116 Int32 mdc_mat_list( fptr, mlist, lmax)
117   FILE *fptr;
118   struct Mdc_MatDir mlist[];
119   Int32 lmax;
120 {
121   Int32 blk, num_entry, num_stored, i;
122   Int32 nxtblk, matnum, strtblk, endblk, matstat;
123   Int32 dirbufr[MdcMatBLKSIZE/4];
124   Uint8 bytebufr[MdcMatBLKSIZE];
125 
126   blk = MdcMatFirstDirBlk;
127   num_entry = 0;
128   num_stored = 0;
129   while(1) {
130     mdc_mat_rblk( fptr, blk, bytebufr,1);
131     if ( MdcHostBig() ) {
132       MdcSWAB( (Uint8 *)bytebufr, (Uint8 *)dirbufr, MdcMatBLKSIZE);
133       MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, MdcMatBLKSIZE/2);
134     }else{
135       memcpy(dirbufr, bytebufr, MdcMatBLKSIZE);
136     }
137     /* nfree  = dirbufr[0]; */
138     nxtblk = dirbufr[1];
139     /* prvblk = dirbufr[2]; */
140     /* nused  = dirbufr[3]; */
141     for (i=4; i<MdcMatBLKSIZE/4; i+=4)
142     {  matnum  = dirbufr[i];
143       strtblk = dirbufr[i+1];
144       endblk  = dirbufr[i+2];
145       matstat = dirbufr[i+3];
146       if (matnum && num_stored < lmax)
147       {  mlist[num_stored].matnum = matnum;
148         mlist[num_stored].strtblk = strtblk;
149         mlist[num_stored].endblk = endblk;
150         mlist[num_stored].matstat = matstat;
151         num_stored++;
152       }
153       if (matnum) num_entry++;
154     }
155     blk = nxtblk;
156     if (blk == MdcMatFirstDirBlk) break;
157   }
158 
159   return (num_entry);
160 }
161 /*********************************************************/
mdc_mat_list7(fptr,mlist,lmax)162 Int32 mdc_mat_list7( fptr, mlist, lmax)
163   FILE *fptr;
164   struct Mdc_MatDir mlist[];
165   Int32 lmax;
166 {
167   Int32 blk, num_entry, num_stored, i;
168   Int32 nxtblk, matnum, strtblk, endblk, matstat;
169   Int32 dirbufr[MdcMatBLKSIZE/4];
170   Uint8 bytebufr[MdcMatBLKSIZE];
171 
172   blk = MdcMatFirstDirBlk;
173   num_entry = 0;
174   num_stored = 0;
175   while(1) {
176     mdc_mat_rblk( fptr, blk, bytebufr,1);
177     if (! MdcHostBig() ) {
178       MdcSWAB( (Uint8 *)bytebufr, (Uint8 *)dirbufr, MdcMatBLKSIZE);
179       MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, MdcMatBLKSIZE/2);
180     }else{
181       memcpy(dirbufr, bytebufr, MdcMatBLKSIZE);
182     }
183     /* nfree  = dirbufr[0]; */
184     nxtblk = dirbufr[1];
185     /* prvblk = dirbufr[2]; */
186     /* nused  = dirbufr[3]; */
187     for (i=4; i<MdcMatBLKSIZE/4; i+=4)
188     {  matnum  = dirbufr[i];
189       strtblk = dirbufr[i+1];
190       endblk  = dirbufr[i+2];
191       matstat = dirbufr[i+3];
192       if (matnum && num_stored < lmax)
193       {  mlist[num_stored].matnum = matnum;
194         mlist[num_stored].strtblk = strtblk;
195         mlist[num_stored].endblk = endblk;
196         mlist[num_stored].matstat = matstat;
197         num_stored++;
198       }
199       if (matnum) num_entry++;
200     }
201     blk = nxtblk;
202     if (blk == MdcMatFirstDirBlk) break;
203   }
204 
205   return (num_entry);
206 }
207 
208 /*********************************************************/
MdcSWAW(from,to,length)209 Int32 MdcSWAW( from, to, length)
210   Uint16 from[], to[];
211   Int32 length;
212 {
213   Uint16 temp;
214   Int32 i;
215 
216   for (i=0;i<length; i+=2)
217   {  temp = from[i+1];
218     to[i+1]=from[i];
219     to[i] = temp;
220   }
221   return 0;
222 }
223 
224 /*********************************************************/
MdcSWAB(from,to,length)225 Int32 MdcSWAB( from, to, length)
226   Uint8 from[], to[];
227   Int32 length;
228 {
229   Uint16 temp;
230   Int32 i;
231 
232   for (i=0;i<length; i+=2)
233   {
234     temp   = from[i+1];
235     to[i+1]= from[i];
236     to[i]  = temp;
237   }
238   return 0;
239 }
240 
241 
242 /********************************************************
243   old version supporting 4096 planes, 256 planes, 4 data types
244   Int32 mdc_mat_numcod( frame, plane, gate, data, bed)
245   Int32 frame, plane, gate, data, bed;
246   {
247   return ((frame&0xFFF)|((bed&0xF)<<12)|((plane&0xFF)<<16)|
248   ((gate&0x3F)<<24)|((data&0x3)<<30));
249   }
250  */
251 /********************************************************
252   old version supporting 4096 planes, 256 planes, 4 data types
253   mdc_mat_numdoc( matnum, matval)
254   Int32 matnum; struct Mdc_Matval *matval;
255   {
256   matval->frame = matnum&0xFFF;
257   matval->plane = (matnum>>16)&0xFF;
258   matval->gate  = (matnum>>24)&0x3F;
259   matval->data  = (matnum>>30)&0x3;
260   matval->bed   = (matnum>>12)&0xF;
261   return 0;
262   }
263  */
264 /********************************************************
265   new version supporting 512 planes, 1024 planes, 8 data types */
mdc_mat_numcod(frame,plane,gate,data,bed)266 Int32 mdc_mat_numcod( frame, plane, gate, data, bed)
267   Int32 frame, plane, gate, data, bed;
268 {
269   Int32 matnum8data16bed64gate1024plane512frame, loPlane, hiPlane = 0, loData, hiData = 0;
270 
271   hiPlane = (plane & 0x300);
272   loPlane = (plane & 0xFF);
273   loData = (data & 0x3);
274   hiData = (data & 0x4);
275 
276   matnum8data16bed64gate1024plane512frame = ((frame & 0x1FF) | ((bed & 0xF) << 12) |
277       ((loPlane << 16) | (hiPlane << 1)) | ((gate & 0x3F) << 24) | ((loData << 30) | (hiData << 9)));
278 
279   return (matnum8data16bed64gate1024plane512frame);
280 }
281 /********************************************************
282   new version supporting 512 planes, 1024 planes, 8 data types */
mdc_mat_numdoc(matnum,matval)283 Int32 mdc_mat_numdoc( matnum, matval)
284   Int32 matnum; struct Mdc_Matval *matval;
285 {
286   Int32 loPlane, hiPlane = 0, loData, hiData = 0;
287 
288   matval->frame = matnum & 0x1FF;
289   loPlane = (matnum >> 16) & 0xFF;
290   hiPlane = (matnum >> 1) & 0x300;
291   matval->plane = loPlane | hiPlane;
292   matval->gate = (matnum >> 24) & 0x3F;
293   loData = (matnum >> 30) & 0x3;
294   hiData = (matnum >> 9) & 0x4;
295   matval->data = loData | hiData;
296   matval->bed = (matnum >> 12) & 0xF;
297   return 0;
298 }
299 /*********************************************************/
mdc_mat_lookup(fptr,matnum,entry)300 Int32 mdc_mat_lookup( fptr, matnum, entry)
301   FILE *fptr; Int32 matnum; struct Mdc_MatDir *entry;
302 {
303 
304   Int32 blk, i;
305   Int32 nxtblk, matnbr, strtblk, endblk, matstat;
306   Int32 dirbufr[MdcMatBLKSIZE/4];
307   Uint8 bytebufr[MdcMatBLKSIZE];
308 
309   blk = MdcMatFirstDirBlk;
310   while(1) {
311     mdc_mat_rblk( fptr, blk, bytebufr,1);
312     if ( MdcHostBig() ) {
313       MdcSWAB( (Uint8 *)bytebufr, (Uint8 *)dirbufr, MdcMatBLKSIZE);
314       MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, MdcMatBLKSIZE/2);
315     }else{
316       memcpy(dirbufr, bytebufr, MdcMatBLKSIZE);
317     }
318     /* nfree  = dirbufr[0]; */
319     nxtblk = dirbufr[1];
320     /* prvblk = dirbufr[2]; */
321     /* nused  = dirbufr[3]; */
322     for (i=4; i<MdcMatBLKSIZE/4; i+=4)
323     {  matnbr  = dirbufr[i];
324       strtblk = dirbufr[i+1];
325       endblk  = dirbufr[i+2];
326       matstat = dirbufr[i+3];
327       if (matnum == matnbr) {
328         entry->matnum  = matnbr;
329         entry->strtblk = strtblk;
330         entry->endblk  = endblk;
331         entry->matstat = matstat;
332         return (1); }
333     }
334     blk = nxtblk;
335     if (blk == MdcMatFirstDirBlk) break;
336   }
337   return (0);
338 }
339 
340 /*********************************************************/
mdc_mat_lookup7(fptr,matnum,entry)341 Int32 mdc_mat_lookup7( fptr, matnum, entry)
342   FILE *fptr; Int32 matnum; struct Mdc_MatDir *entry;
343 {
344 
345   Int32 blk, i;
346   Int32 nxtblk, matnbr, strtblk, endblk, matstat;
347   Int32 dirbufr[MdcMatBLKSIZE/4];
348   Uint8 bytebufr[MdcMatBLKSIZE];
349 
350   blk = MdcMatFirstDirBlk;
351   while(1) {
352     mdc_mat_rblk( fptr, blk, bytebufr,1);
353     if ( ! MdcHostBig() ) {
354       MdcSWAB( (Uint8 *)bytebufr, (Uint8 *)dirbufr, MdcMatBLKSIZE);
355       MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, MdcMatBLKSIZE/2);
356     }else{
357       memcpy(dirbufr, bytebufr, MdcMatBLKSIZE);
358     }
359     /* nfree  = dirbufr[0]; */
360     nxtblk = dirbufr[1];
361     /* prvblk = dirbufr[2]; */
362     /* nused  = dirbufr[3]; */
363     for (i=4; i<MdcMatBLKSIZE/4; i+=4)
364     {  matnbr  = dirbufr[i];
365       strtblk = dirbufr[i+1];
366       endblk  = dirbufr[i+2];
367       matstat = dirbufr[i+3];
368       if (matnum == matnbr) {
369         entry->matnum  = matnbr;
370         entry->strtblk = strtblk;
371         entry->endblk  = endblk;
372         entry->matstat = matstat;
373         return (1); }
374     }
375     blk = nxtblk;
376     if (blk == MdcMatFirstDirBlk) break;
377   }
378   return (0);
379 }
380 
381 /*********************************************************/
mdc_mat_read_main_header(fptr,h)382 Int32 mdc_mat_read_main_header( fptr, h)
383   FILE *fptr; Mdc_Main_header *h;
384 {
385   Int16 b[256];
386   char *bb;
387   Int32 err, i;
388 
389   err = mdc_mat_rblk(fptr,1,(Uint8 *)b,1);/* read main header at block 1*/
390   if (err) return(err);
391   bb = (char *)b;
392   strncpy( h->original_file_name, bb+28, 20);
393   strncpy( h->node_id, bb+56, 10);
394   strncpy( h->isotope_code, bb+78, 8);
395   strncpy( h->radiopharmaceutical, bb+90, 32);
396   strncpy( h->study_name, bb+162, 12);
397   strncpy( h->patient_id, bb+174, 16);
398   strncpy( h->patient_name, bb+190, 32);
399   h->patient_sex = bb[222];
400   strncpy( h->patient_age, bb+223, 10);
401   strncpy( h->patient_height, bb+233, 10);
402   strncpy( h->patient_weight, bb+243, 10);
403   h->patient_dexterity = bb[253];
404   strncpy( h->physician_name, bb+254, 32);
405   strncpy( h->operator_name, bb+286, 32);
406   strncpy( h->study_description, bb+318, 32);
407   strncpy( h->facility_name, bb+356, 20);
408   strncpy( h->user_process_code, bb+462, 10);
409   if (MdcHostBig()) MdcSWAB( (Uint8 *)b, (Uint8 *)b, MdcMatBLKSIZE);
410   h->sw_version = b[24];
411   h->data_type = b[25];
412   h->system_type = b[26];
413   h->file_type = b[27];
414   h->scan_start_day = b[33];
415   h->scan_start_month = b[34];
416   h->scan_start_year = b[35];
417   h->scan_start_hour = b[36];
418   h->scan_start_minute = b[37];
419   h->scan_start_second = b[38];
420   h->isotope_halflife=mdc_get_vax_float((Uint16 *)b, 43);
421   h->gantry_tilt = mdc_get_vax_float((Uint16 *)b, 61);
422   h->gantry_rotation = mdc_get_vax_float((Uint16 *)b, 63);
423   h->bed_elevation = mdc_get_vax_float((Uint16 *)b, 65);
424   h->rot_source_speed = b[67];
425   h->wobble_speed = b[68];
426   h->transm_source_type = b[69];
427   h->axial_fov = mdc_get_vax_float((Uint16 *)b, 70);
428   h->transaxial_fov = mdc_get_vax_float((Uint16 *)b, 72);
429   h->transaxial_samp_mode = b[74];
430   h->coin_samp_mode = b[75];
431   h->axial_samp_mode = b[76];
432   h->calibration_factor=mdc_get_vax_float((Uint16 *)b, 77);
433   h->calibration_units = b[79];
434   h->compression_code = b[80];
435   h->acquisition_type = b[175];
436   h->bed_type = b[176];
437   h->septa_type = b[177];
438   h->num_planes = b[188];
439   h->num_frames = b[189];
440   h->num_gates = b[190];
441   h->num_bed_pos = b[191];
442   h->init_bed_position=mdc_get_vax_float((Uint16 *)b, 192);
443   for (i=0; i<15; i++)
444     h->bed_offset[i] = mdc_get_vax_float((Uint16 *)b, 194+2*i);
445   h->plane_separation = mdc_get_vax_float((Uint16 *)b, 224);
446   h->lwr_sctr_thres = b[226];
447   h->lwr_true_thres = b[227];
448   h->upr_true_thres = b[228];
449   h->collimator = mdc_get_vax_float((Uint16 *)b, 229);
450   h->acquisition_mode = b[236];
451   return (0);
452 }
453 /*********************************************************/
mdc_mat_read_matrix_data(fptr,blk,nblks,bufr)454 Int32 mdc_mat_read_matrix_data( fptr, blk, nblks, bufr)
455   FILE *fptr; Int32 blk, nblks; Int16 bufr[];
456 {
457   Int32 error ;
458   Mdc_Main_header h ;
459 
460   error = mdc_mat_read_main_header(fptr, &h) ;
461   if(error)   return(error) ;
462   error = mdc_mat_read_mat_data(fptr, blk, nblks,
463       (Uint8 *)bufr, h.data_type) ;
464   return (error);
465 }
466 
467 /*********************************************************/
mdc_mat_read_main_header7(fptr,h)468 Int32 mdc_mat_read_main_header7( fptr, h)
469   FILE *fptr; Mdc_Main_header7 *h;
470 {
471   Int16 b[256];
472   char *bb;
473   Int32 err, i;
474 
475   err = mdc_mat_rblk(fptr,1,(Uint8 *)b,1);/* read main header at block 1*/
476   if (err) return(err);
477   bb = (char *)b;
478 
479   memcpy( h->magic_number        ,bb    ,14);
480   memcpy( h->original_file_name  ,bb+14 ,32);
481   memcpy(&h->sw_version          ,bb+46 , 2);  MdcSWAP(h->sw_version);
482   memcpy(&h->system_type         ,bb+48 , 2);  MdcSWAP(h->system_type);
483   memcpy(&h->file_type           ,bb+50 , 2);  MdcSWAP(h->file_type);
484   memcpy( h->serial_number       ,bb+52 ,10);
485   memcpy(&h->scan_start_time     ,bb+62 , 4);  MdcSWAP(h->scan_start_time);
486   memcpy( h->isotope_name        ,bb+66 , 8);
487   memcpy(&h->isotope_halflife    ,bb+74 , 4);  MdcSWAP(h->isotope_halflife);
488   memcpy( h->radiopharmaceutical ,bb+78 ,32);
489   memcpy(&h->gantry_tilt         ,bb+110, 4);  MdcSWAP(h->gantry_tilt);
490   memcpy(&h->gantry_rotation     ,bb+114, 4);  MdcSWAP(h->gantry_rotation);
491   memcpy(&h->bed_elevation       ,bb+118, 4);  MdcSWAP(h->bed_elevation);
492   memcpy(&h->intrinsic_tilt      ,bb+122, 4);  MdcSWAP(h->intrinsic_tilt);
493   memcpy(&h->wobble_speed        ,bb+126, 2);  MdcSWAP(h->wobble_speed);
494   memcpy(&h->transm_source_type  ,bb+128, 2);  MdcSWAP(h->transm_source_type);
495   memcpy(&h->distance_scanned    ,bb+130, 4);  MdcSWAP(h->distance_scanned);
496   memcpy(&h->transaxial_fov      ,bb+134, 4);  MdcSWAP(h->transaxial_fov);
497   memcpy(&h->angular_compression ,bb+138, 2);  MdcSWAP(h->angular_compression);
498   memcpy(&h->coin_samp_mode      ,bb+140, 2);  MdcSWAP(h->coin_samp_mode);
499   memcpy(&h->axial_samp_mode     ,bb+142, 2);  MdcSWAP(h->axial_samp_mode);
500   memcpy(&h->ecat_calibration_factor,bb+144,4);
501   MdcSWAP(h->ecat_calibration_factor);
502   memcpy(&h->calibration_units   ,bb+148, 2);  MdcSWAP(h->calibration_units);
503   memcpy(&h->calibration_units_label,bb+150,2);
504   MdcSWAP(h->calibration_units_label);
505   memcpy(&h->compression_code    ,bb+152, 2);  MdcSWAP(h->compression_code);
506   memcpy( h->study_type          ,bb+154,12);
507   memcpy( h->patient_id          ,bb+166,16);
508   memcpy( h->patient_name        ,bb+182,32);
509   memcpy( h->patient_sex         ,bb+214, 1);
510   memcpy( h->patient_dexterity   ,bb+215, 1);
511   memcpy(&h->patient_age         ,bb+216, 4);  MdcSWAP(h->patient_age);
512   memcpy(&h->patient_height      ,bb+220, 4);  MdcSWAP(h->patient_height);
513   memcpy(&h->patient_weight      ,bb+224, 4);  MdcSWAP(h->patient_weight);
514   memcpy(&h->patient_birth_date  ,bb+228, 4);  MdcSWAP(h->patient_birth_date);
515   memcpy( h->physician_name      ,bb+232,32);
516   memcpy( h->operator_name       ,bb+264,32);
517   memcpy( h->study_description   ,bb+296,32);
518   memcpy(&h->acquisition_type    ,bb+328, 2);  MdcSWAP(h->acquisition_type);
519   memcpy(&h->patient_orientation ,bb+330, 2);  MdcSWAP(h->patient_orientation);
520   memcpy( h->facility_name       ,bb+332,20);
521   memcpy(&h->num_planes          ,bb+352, 2);  MdcSWAP(h->num_planes);
522   memcpy(&h->num_frames          ,bb+354, 2);  MdcSWAP(h->num_frames);
523   memcpy(&h->num_gates           ,bb+356, 2);  MdcSWAP(h->num_gates);
524   memcpy(&h->num_bed_pos         ,bb+358, 2);  MdcSWAP(h->num_bed_pos);
525   memcpy(&h->init_bed_position   ,bb+360, 4);  MdcSWAP(h->init_bed_position);
526   memcpy( h->bed_position        ,bb+364,60);
527   for (i=0; i<15; i++) MdcSWAP(h->bed_position[i]);
528   memcpy(&h->plane_separation    ,bb+424, 4);  MdcSWAP(h->plane_separation);
529   memcpy(&h->lwr_sctr_thres      ,bb+428, 2);  MdcSWAP(h->lwr_sctr_thres);
530   memcpy(&h->lwr_true_thres      ,bb+430, 2);  MdcSWAP(h->lwr_true_thres);
531   memcpy(&h->upr_true_thres      ,bb+432, 2);  MdcSWAP(h->upr_true_thres);
532   memcpy( h->user_process_code   ,bb+434,10);
533   memcpy(&h->acquisition_mode    ,bb+444, 2);  MdcSWAP(h->acquisition_mode);
534   memcpy(&h->bin_size            ,bb+446, 4);  MdcSWAP(h->bin_size);
535   memcpy(&h->branching_fraction  ,bb+450, 4);  MdcSWAP(h->branching_fraction);
536   memcpy(&h->dose_start_time     ,bb+454, 4);  MdcSWAP(h->dose_start_time);
537   memcpy(&h->dosage              ,bb+458, 4);  MdcSWAP(h->dosage);
538   memcpy(&h->well_counter_corr_factor,bb+462,4);
539   MdcSWAP(h->well_counter_corr_factor);
540   memcpy( h->data_units          ,bb+466,32);
541   memcpy(&h->septa_state         ,bb+498, 2);  MdcSWAP(h->septa_state);
542   memcpy( h->fill_cti            ,bb+500,12);
543 
544   return (0);
545 }
546 
547 /*******************************************************************/
548 /*  May 90, PLuk - Now reads VAX or Sun matrix files.              */
549 
mdc_mat_read_mat_data(fptr,strtblk,nblks,dptr,dtype)550 Int32 mdc_mat_read_mat_data( fptr, strtblk, nblks, dptr, dtype)
551   FILE *fptr;
552   Int32 strtblk, nblks, dtype;
553   Uint8 *dptr;
554 {
555   Int32 i, error;
556 
557   error = mdc_mat_rblk( fptr, strtblk, dptr, nblks);
558   if (error) return(error);
559 
560   switch( dtype)
561   {
562     case 1: /* byte format...no translation necessary */
563       break;
564     case 2: /* Vax I*2 */
565       if (MdcHostBig())
566         MdcSWAB((Uint8 *)dptr, (Uint8 *)dptr, 512*nblks);
567       break;
568     case 3: /* Vax I*4 */
569       if (MdcHostBig()) {
570         MdcSWAB( (Uint8 *)dptr, (Uint8 *)dptr, 512*nblks);
571         MdcSWAW( (Uint16 *)dptr, (Uint16 *)dptr, 256*nblks);
572       }
573       break;
574     case 4: /* Vax R*4 */
575       if (MdcHostBig())
576         MdcSWAB( (Uint8 *)dptr, (Uint8 *)dptr, 512*nblks);
577       for (i=0; i<nblks*128; i++)
578         ((float *)dptr)[i] = mdc_get_vax_float((Uint16 *)dptr, i*2);
579       break;
580     case 5: /* IEEE R*4 */
581       break;
582     case 6: /* 68K I*2 */
583       break;
584     case 7: /* 68K I*4 */
585       break;
586     default:  /* something else...treat as Vax I*2 */
587       if (MdcHostBig())
588         MdcSWAB( (Uint8 *)dptr, (Uint8 *)dptr, 512*nblks);
589       break;
590   }
591   return 0;
592 }
593 
594 /*********************************************************/
mdc_mat_read_mat_data7(fptr,strtblk,nblks,dptr,dtype)595 Int32 mdc_mat_read_mat_data7( fptr, strtblk, nblks, dptr, dtype)
596   FILE *fptr;
597   Int32 strtblk, nblks, dtype;
598   Uint8 *dptr;
599 {
600   Int32 i, error;
601 
602   error = mdc_mat_rblk( fptr, strtblk, dptr, nblks);
603   if (error) return(error);
604 
605   switch( dtype)
606   {
607     case 1: /* byte format...no translation necessary */
608       break;
609     case 2: /* Vax I*2 */
610       if (! MdcHostBig())
611         MdcSWAB((Uint8 *)dptr, (Uint8 *)dptr, 512*nblks);
612       break;
613     case 3: /* Vax I*4 */
614       if (! MdcHostBig()) {
615         MdcSWAB( (Uint8 *)dptr, (Uint8 *)dptr, 512*nblks);
616         MdcSWAW( (Uint16 *)dptr, (Uint16 *)dptr, 256*nblks);
617       }
618       break;
619     case 4: /* Vax R*4 */
620       if (! MdcHostBig())
621         MdcSWAB( (Uint8 *)dptr, (Uint8 *)dptr, 512*nblks);
622       for (i=0; i<nblks*128; i++)
623         ((float *)dptr)[i] = mdc_get_vax_float( (Uint16 *)dptr, i/2);
624       break;
625     case 5: /* IEEE R*4 */
626       break;
627     case 6: /* 68K I*2 */
628       break;
629     case 7: /* 68K I*4 */
630       break;
631     default:  /* something else...treat as Vax I*2 */
632       if (! MdcHostBig())
633         MdcSWAB( (Uint8 *)dptr, (Uint8 *)dptr, 512*nblks);
634       break;
635   }
636   return 0;
637 }
638 
639 /*********************************************************/
mdc_mat_read_scan_subheader(fptr,blknum,h)640 Int32 mdc_mat_read_scan_subheader( fptr, blknum, h)
641   FILE *fptr; Int32 blknum; Mdc_Scan_subheader *h;
642 {
643   Int16 b[256];
644   Int32 i, err;
645 
646   err = mdc_mat_rblk( fptr, blknum, (Uint8 *)b, 1);
647   if (err) return(err);
648   if (MdcHostBig())
649     MdcSWAB( (Uint8 *)b, (Uint8 *)b, MdcMatBLKSIZE);
650   h->data_type = b[63];
651   h->dimension_1 = b[66];
652   h->dimension_2 = b[67];
653   h->smoothing = b[68];
654   h->processing_code = b[69];
655   h->sample_distance = mdc_get_vax_float((Uint16 *)b, 73);
656   h->isotope_halflife = mdc_get_vax_float((Uint16 *)b, 83);
657   h->frame_duration_sec = b[85];
658   h->gate_duration = mdc_get_vax_long((Uint16 *)b, 86);
659   h->r_wave_offset = mdc_get_vax_long((Uint16 *)b, 88);
660   h->scale_factor = mdc_get_vax_float((Uint16 *)b, 91);
661   h->scan_min = b[96];
662   h->scan_max = b[97];
663   h->prompts = mdc_get_vax_long((Uint16 *)b, 98);
664   h->delayed = mdc_get_vax_long((Uint16 *)b, 100);
665   h->multiples = mdc_get_vax_long((Uint16 *)b, 102);
666   h->net_trues = mdc_get_vax_long((Uint16 *)b, 104);
667   for (i=0; i<16; i++)
668   { h->cor_singles[i] = mdc_get_vax_float((Uint16 *)b, 158+2*i);
669     h->uncor_singles[i] = mdc_get_vax_float((Uint16 *)b, 190+2*i);}
670   h->tot_avg_cor = mdc_get_vax_float((Uint16 *)b, 222);
671   h->tot_avg_uncor = mdc_get_vax_float((Uint16 *)b, 224);
672   h->total_coin_rate = mdc_get_vax_long((Uint16 *)b, 226);
673   h->frame_start_time = mdc_get_vax_long((Uint16 *)b, 228);
674   h->frame_duration = mdc_get_vax_long((Uint16 *)b, 230);
675   h->loss_correction_fctr = mdc_get_vax_float((Uint16 *)b, 232);
676   for (i=0; i<8; i++)
677     h->phy_planes[i] = mdc_get_vax_long((Uint16 *)b, 234+(2*i));
678   return (0);
679 }
680 /*********************************************************/
mdc_mat_read_scan_subheader7(fptr,blknum,h)681 Int32 mdc_mat_read_scan_subheader7( fptr, blknum, h)
682   FILE *fptr; Int32 blknum; Mdc_Scan_subheader7 *h;
683 {
684   Int16 b[256];
685   Int32 err;
686   char *bb;
687 
688   err = mdc_mat_rblk( fptr, blknum, (Uint8 *)b, 1);
689   if (err) return(err);
690   bb = (char *)b;
691 
692   memcpy(&h->data_type             ,bb    , 2); MdcSWAP(h->data_type);
693   memcpy(&h->num_dimensions        ,bb+  2, 2); MdcSWAP(h->num_dimensions);
694   memcpy(&h->num_r_elements        ,bb+  4, 2); MdcSWAP(h->num_r_elements);
695   memcpy(&h->num_angles            ,bb+  6, 2); MdcSWAP(h->num_angles);
696   memcpy(&h->corrections_applied   ,bb+  8, 2); MdcSWAP(h->corrections_applied);
697   memcpy(&h->num_z_elements        ,bb+ 10, 2); MdcSWAP(h->num_z_elements);
698   memcpy(&h->ring_difference       ,bb+ 12, 2); MdcSWAP(h->ring_difference);
699   memcpy(&h->x_resolution          ,bb+ 14, 4); MdcSWAP(h->x_resolution);
700   memcpy(&h->y_resolution          ,bb+ 18, 4); MdcSWAP(h->y_resolution);
701   memcpy(&h->z_resolution          ,bb+ 22, 4); MdcSWAP(h->z_resolution);
702   memcpy(&h->w_resolution          ,bb+ 26, 4); MdcSWAP(h->w_resolution);
703 
704   return (0);
705 }
706 /*********************************************************/
mdc_mat_read_image_subheader(fptr,blknum,h)707 Int32 mdc_mat_read_image_subheader( fptr, blknum, h)
708   FILE *fptr; Int32 blknum; Mdc_Image_subheader *h;
709 {
710   Int16 b[256];
711   Int32 i, err;
712   char *bb;
713 
714   err = mdc_mat_rblk( fptr, blknum, (Uint8 *)b, 1);
715   if (err) return(err);
716   bb = (char *)b;
717   strncpy( h->annotation, bb+420, 40);
718   if (MdcHostBig())
719     MdcSWAB( (Uint8 *)b, (Uint8 *)b, MdcMatBLKSIZE);
720   h->data_type = b[63];
721   h->num_dimensions = b[64];
722   h->dimension_1 = b[66];
723   h->dimension_2 = b[67];
724   h->x_origin = mdc_get_vax_float((Uint16 *)b, 80);
725   h->y_origin = mdc_get_vax_float((Uint16 *)b, 82);
726   h->recon_scale = mdc_get_vax_float((Uint16 *)b, 84);
727   h->quant_scale = mdc_get_vax_float((Uint16 *)b, 86);
728   h->image_min = b[88];
729   h->image_max = b[89];
730   h->pixel_size = mdc_get_vax_float((Uint16 *)b, 92);
731   h->slice_width = mdc_get_vax_float((Uint16 *)b, 94);
732   h->frame_duration = mdc_get_vax_long((Uint16 *)b, 96);
733   h->frame_start_time = mdc_get_vax_long((Uint16 *)b, 98);
734   h->slice_location = b[100];
735   h->recon_start_hour = b[101];
736   h->recon_start_minute = b[102];
737   h->recon_start_sec = b[103];
738   h->gate_duration = mdc_get_vax_long((Uint16 *)b, 104);
739   h->filter_code = b[118];
740   h->scan_matrix_num = mdc_get_vax_long((Uint16 *)b, 119);
741   h->norm_matrix_num = mdc_get_vax_long((Uint16 *)b, 121);
742   h->atten_cor_matrix_num = mdc_get_vax_long((Uint16 *)b, 123);
743   h->image_rotation = mdc_get_vax_float((Uint16 *)b, 148);
744   h->plane_eff_corr_fctr = mdc_get_vax_float((Uint16 *)b, 150);
745   h->decay_corr_fctr = mdc_get_vax_float((Uint16 *)b, 152);
746   h->loss_corr_fctr = mdc_get_vax_float((Uint16 *)b, 154);
747   h->intrinsic_tilt = mdc_get_vax_float((Uint16 *)b, 156);
748   h->processing_code = b[188];
749   h->quant_units = b[190];
750   h->recon_start_day = b[191];
751   h->recon_start_month = b[192];
752   h->recon_start_year = b[193];
753   h->ecat_calibration_fctr = mdc_get_vax_float((Uint16 *)b, 194);
754   h->well_counter_cal_fctr = mdc_get_vax_float((Uint16 *)b, 196);
755   for (i=0; i<6; i++)
756     h->filter_params[i] = mdc_get_vax_float((Uint16 *)b, 198+2*i);
757   return (0);
758 }
759 /*********************************************************/
mdc_mat_read_image_subheader7(fptr,blknum,h)760 Int32 mdc_mat_read_image_subheader7( fptr, blknum, h)
761   FILE *fptr; Int32 blknum; Mdc_Image_subheader7 *h;
762 {
763   Int16 b[256];
764   Int32 i, err;
765   char *bb;
766 
767   err = mdc_mat_rblk( fptr, blknum, (Uint8 *)b, 1);
768   if (err) return(err);
769   bb = (char *)b;
770 
771   memcpy(&h->data_type              ,bb    , 2); MdcSWAP(h->data_type);
772   memcpy(&h->num_dimensions         ,bb+  2, 2); MdcSWAP(h->num_dimensions);
773   memcpy(&h->x_dimension            ,bb+  4, 2); MdcSWAP(h->x_dimension);
774   memcpy(&h->y_dimension            ,bb+  6, 2); MdcSWAP(h->y_dimension);
775   memcpy(&h->z_dimension            ,bb+  8, 2); MdcSWAP(h->z_dimension);
776   memcpy(&h->x_offset               ,bb+ 10, 4); MdcSWAP(h->x_offset);
777   memcpy(&h->y_offset               ,bb+ 14, 4); MdcSWAP(h->y_offset);
778   memcpy(&h->z_offset               ,bb+ 18, 4); MdcSWAP(h->z_offset);
779   memcpy(&h->recon_zoom             ,bb+ 22, 4); MdcSWAP(h->recon_zoom);
780   memcpy(&h->scale_factor           ,bb+ 26, 4); MdcSWAP(h->scale_factor);
781   memcpy(&h->image_min              ,bb+ 30, 2); MdcSWAP(h->image_min);
782   memcpy(&h->image_max              ,bb+ 32, 2); MdcSWAP(h->image_max);
783   memcpy(&h->x_pixel_size           ,bb+ 34, 4); MdcSWAP(h->x_pixel_size);
784   memcpy(&h->y_pixel_size           ,bb+ 38, 4); MdcSWAP(h->y_pixel_size);
785   memcpy(&h->z_pixel_size           ,bb+ 42, 4); MdcSWAP(h->z_pixel_size);
786   memcpy(&h->frame_duration         ,bb+ 46, 4); MdcSWAP(h->frame_duration);
787   memcpy(&h->frame_start_time       ,bb+ 50, 4); MdcSWAP(h->frame_start_time);
788   memcpy(&h->filter_code            ,bb+ 54, 2); MdcSWAP(h->filter_code);
789   memcpy(&h->x_resolution           ,bb+ 56, 4); MdcSWAP(h->x_resolution);
790   memcpy(&h->y_resolution           ,bb+ 60, 4); MdcSWAP(h->y_resolution);
791   memcpy(&h->z_resolution           ,bb+ 64, 4); MdcSWAP(h->z_resolution);
792   memcpy(&h->num_r_elements         ,bb+ 68, 4); MdcSWAP(h->num_r_elements);
793   memcpy(&h->num_angles             ,bb+ 72, 4); MdcSWAP(h->num_angles);
794   memcpy(&h->z_rotation_angle       ,bb+ 76, 4); MdcSWAP(h->z_rotation_angle);
795   memcpy(&h->decay_corr_fctr        ,bb+ 80, 4); MdcSWAP(h->decay_corr_fctr);
796   memcpy(&h->processing_code        ,bb+ 84, 4); MdcSWAP(h->processing_code);
797   memcpy(&h->gate_duration          ,bb+ 88, 4); MdcSWAP(h->gate_duration);
798   memcpy(&h->r_wave_offset          ,bb+ 92, 4); MdcSWAP(h->r_wave_offset);
799   memcpy(&h->num_accepted_beats     ,bb+ 96, 4); MdcSWAP(h->num_accepted_beats);
800   memcpy(&h->filter_cutoff_frequency,bb+100, 4);
801   MdcSWAP(h->filter_cutoff_frequency);
802   memcpy(&h->filter_resolution      ,bb+104, 4); MdcSWAP(h->filter_resolution);
803   memcpy(&h->filter_ramp_slope      ,bb+108, 4); MdcSWAP(h->filter_ramp_slope);
804   memcpy(&h->filter_order           ,bb+112, 2); MdcSWAP(h->filter_order);
805   memcpy(&h->filter_scatter_fraction,bb+114, 4);
806   MdcSWAP(h->filter_scatter_fraction);
807   memcpy(&h->filter_scatter_slope   ,bb+118, 4);
808   MdcSWAP(h->filter_scatter_slope);
809   memcpy( h->annotation             ,bb+122,40);
810   memcpy(&h->mt_1_1                 ,bb+162, 4); MdcSWAP(h->mt_1_1);
811   memcpy(&h->mt_1_2                 ,bb+166, 4); MdcSWAP(h->mt_1_2);
812   memcpy(&h->mt_1_3                 ,bb+170, 4); MdcSWAP(h->mt_1_3);
813   memcpy(&h->mt_2_1                 ,bb+174, 4); MdcSWAP(h->mt_2_1);
814   memcpy(&h->mt_2_2                 ,bb+178, 4); MdcSWAP(h->mt_2_2);
815   memcpy(&h->mt_2_3                 ,bb+182, 4); MdcSWAP(h->mt_2_3);
816   memcpy(&h->mt_3_1                 ,bb+186, 4); MdcSWAP(h->mt_3_1);
817   memcpy(&h->mt_3_2                 ,bb+190, 4); MdcSWAP(h->mt_3_2);
818   memcpy(&h->mt_3_3                 ,bb+194, 4); MdcSWAP(h->mt_3_3);
819   memcpy(&h->rfilter_cutoff         ,bb+198, 4); MdcSWAP(h->rfilter_cutoff);
820   memcpy(&h->rfilter_resolution     ,bb+202, 4); MdcSWAP(h->rfilter_resolution);
821   memcpy(&h->rfilter_code           ,bb+206, 2); MdcSWAP(h->rfilter_code);
822   memcpy(&h->rfilter_order          ,bb+208, 2); MdcSWAP(h->rfilter_order);
823   memcpy(&h->zfilter_cutoff         ,bb+210, 4); MdcSWAP(h->zfilter_cutoff);
824   memcpy(&h->zfilter_resolution     ,bb+214, 4); MdcSWAP(h->zfilter_resolution);
825   memcpy(&h->zfilter_code           ,bb+218, 2); MdcSWAP(h->zfilter_code);
826   memcpy(&h->zfilter_order          ,bb+220, 2); MdcSWAP(h->zfilter_order);
827   memcpy(&h->mt_1_4                 ,bb+222, 4); MdcSWAP(h->mt_1_4);
828   memcpy(&h->mt_2_4                 ,bb+226, 4); MdcSWAP(h->mt_2_4);
829   memcpy(&h->mt_3_4                 ,bb+230, 4); MdcSWAP(h->mt_3_4);
830   memcpy(&h->scatter_type           ,bb+234, 2); MdcSWAP(h->scatter_type);
831   memcpy(&h->recon_type             ,bb+236, 2); MdcSWAP(h->recon_type);
832   memcpy(&h->recon_views            ,bb+238, 2); MdcSWAP(h->recon_views);
833   memcpy( h->fill_cti               ,bb+240,174);
834   for (i=0; i<87; i++) MdcSWAP(h->fill_cti[i]);
835   memcpy( h->fill_user              ,bb+414,96);
836   for (i=0; i<48; i++) MdcSWAP(h->fill_user[i]);
837 
838   return (0);
839 }
840 
841 
842 /*********************************************************/
mdc_get_vax_float(bufr,off)843 float mdc_get_vax_float( bufr, off)
844   Uint16 bufr[]; Int32 off;
845 {
846   Uint16 t1, t2;
847   union {Uint32 t3; float t4;} test;
848 
849   if (bufr[off]==0 && bufr[off+1]==0) return(0.0);
850   t1 = bufr[off] & 0x80ff;
851   t2=(((bufr[off])&0x7f00)+0xff00)&0x7f00;
852   test.t3 = (t1+t2)<<16;
853   test.t3 =test.t3+bufr[off+1];
854   return(test.t4);
855 }
856 
857 /*********************************************************/
mdc_get_vax_long(bufr,off)858 Int32 mdc_get_vax_long( bufr, off)
859   Uint16 bufr[]; Int32 off;
860 {
861   return ((bufr[off+1]<<16)+bufr[off]);
862 }
863 
mdc_mat_read_dir(fptr,selector)864 Mdc_Mat_dir mdc_mat_read_dir( fptr, selector)
865   FILE *fptr;
866   Uint8 *selector;
867 { Int32 i, n, blk, nxtblk, ndblks, bufr[128];
868   Mdc_Mat_dir dir;
869 
870   blk = MdcMatFirstDirBlk;
871   nxtblk = 0;
872   for (ndblks=0; nxtblk != MdcMatFirstDirBlk; ndblks++)
873   {
874     mdc_mat_rblk( fptr, blk, (Uint8 *)bufr, 1);
875     if (MdcHostBig()) {
876       MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, 8);
877       MdcSWAW( (Uint16 *)bufr, (Uint16 *)bufr, 4);
878     }
879     nxtblk = bufr[1];
880     blk = nxtblk;
881   }
882   dir = (Mdc_Mat_dir) malloc( sizeof(struct mdc_matdir));
883   dir->nmats = 0;
884   dir->nmax = 31 * ndblks;
885   dir->entry = (struct Mdc_MatDir *) malloc( 31*ndblks*sizeof( struct Mdc_MatDir));
886   for (n=0, nxtblk=0, blk=MdcMatFirstDirBlk; nxtblk != MdcMatFirstDirBlk; blk = nxtblk)
887   {
888     mdc_mat_rblk( fptr, blk, (Uint8 *)bufr, 1);
889     if (MdcHostBig()) {
890       MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, 512);
891       MdcSWAW( (Uint16 *)bufr, (Uint16 *)bufr, 256);
892     }
893     nxtblk = bufr[1];
894     for (i=4; i<MdcMatBLKSIZE/4; n++)
895     { dir->entry[n].matnum = bufr[i++];
896       dir->entry[n].strtblk = bufr[i++];
897       dir->entry[n].endblk = bufr[i++];
898       dir->entry[n].matstat = bufr[i++];
899       if (dir->entry[n].matnum != 0) dir->nmats++;
900     }
901   }
902   return dir;
903 }
904 
905 /*********************************************************/
906 
mdc_mat_wblk(fptr,blkno,bufr,nblks)907 Int32 mdc_mat_wblk( fptr, blkno, bufr, nblks)
908   FILE *fptr;
909   Int32 blkno, nblks;
910   Uint8 *bufr;
911 {
912   Int32 err;
913   /* seek to position in file */
914   err=fseek( fptr, (blkno-1)*MdcMatBLKSIZE, 0);
915   if (err) return(-1);
916 
917   /* write matrix data */
918   err=fwrite( bufr, 1, (unsigned)nblks*MdcMatBLKSIZE, fptr);
919   if (err != nblks*MdcMatBLKSIZE) return(-1);
920   if (ferror(fptr)) return (-1);
921   return (0);
922 }
923 
mdc_mat_create(fname,mhead)924 FILE *mdc_mat_create( fname, mhead)
925   char *fname;
926   Mdc_Main_header *mhead;
927 {
928   FILE *fptr;
929   Int32 i, *bufr;
930   fptr = mdc_mat_open( fname, "wb+");
931   if (!fptr) return fptr;
932   mdc_mat_write_main_header( fptr, mhead);
933   bufr = (Int32 *) malloc( MdcMatBLKSIZE);
934   for (i=0; i<128; i++)
935     bufr[i] = 0;
936   bufr[0] = 31;
937   bufr[1] = 2;
938   if (MdcHostBig()) {
939     MdcSWAW( (Uint16 *)bufr, (Uint16 *)bufr, 256);
940     MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, 512);
941   }
942   mdc_mat_wblk( fptr, MdcMatFirstDirBlk, (Uint8 *)bufr, 1);
943   free( bufr);
944   return (fptr);
945 }
946 
mdc_mat_enter(fptr,matnum,nblks)947 Int32 mdc_mat_enter( fptr, matnum, nblks)
948   FILE *fptr; Int32 matnum, nblks;
949 {
950 
951   Int32 dirblk, dirbufr[128+4], i, nxtblk, busy, oldsize;
952 
953   dirblk = MdcMatFirstDirBlk;
954   mdc_mat_rblk( fptr, dirblk, (Uint8 *)dirbufr, 1);
955   if (MdcHostBig()) {
956     MdcSWAB( (Uint8 *)dirbufr, (Uint8 *)dirbufr, 512);
957     MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, 256);
958   }
959   busy = 1;
960   while (busy) {
961     nxtblk = dirblk+1;
962     for (i=4; i<128; i+=4)
963     {
964       if (dirbufr[i] == 0)
965       { busy = 0;
966         break;
967       }
968       else if (dirbufr[i] == matnum)
969       { oldsize = dirbufr[i+2]-dirbufr[i+1]+1;
970         if (oldsize < nblks)
971         { dirbufr[i] = 0xFFFFFFFF;
972           if (MdcHostBig()) {
973             MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, 256);
974             MdcSWAB( (Uint8 *)dirbufr, (Uint8 *)dirbufr, 512);
975           }
976           mdc_mat_wblk( fptr, dirblk, (Uint8 *)dirbufr, 1);
977           if (MdcHostBig()) {
978             MdcSWAB( (Uint8 *)dirbufr, (Uint8 *)dirbufr, 512);
979             MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, 256);
980           }
981           nxtblk = dirbufr[i+2]+1;
982         }
983         else
984         { nxtblk = dirbufr[i+1];
985           dirbufr[0]++;
986           dirbufr[3]--;
987           busy = 0;
988           break;
989         }
990       }
991       else nxtblk = dirbufr[i+2]+1;
992     }
993     if (!busy) break;
994     if (dirbufr[1] != MdcMatFirstDirBlk)
995     { dirblk = dirbufr[1];
996       mdc_mat_rblk( fptr, dirblk, (Uint8 *)dirbufr, 1);
997       if (MdcHostBig()) {
998         MdcSWAB( (Uint8 *)dirbufr, (Uint8 *)dirbufr, 512);
999         MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, 256);
1000       }
1001     } else
1002     { dirbufr[1] = nxtblk;
1003       if (MdcHostBig()) {
1004         MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, 256);
1005         MdcSWAB( (Uint8 *)dirbufr, (Uint8 *)dirbufr, 512);
1006       }
1007       mdc_mat_wblk( fptr, dirblk, (Uint8 *)dirbufr, 1);
1008       dirbufr[0] = 31;
1009       dirbufr[1] = MdcMatFirstDirBlk;
1010       dirbufr[2] = dirblk;
1011       dirbufr[3] = 0;
1012       dirblk = nxtblk;
1013       for (i=4; i<128; i++) dirbufr[i] = 0;
1014     }
1015   }
1016 
1017   dirbufr[i] = matnum;
1018   dirbufr[i+1] = nxtblk;
1019   dirbufr[i+2] = nxtblk + nblks;
1020   dirbufr[i+3] = 1;
1021   dirbufr[0]--;
1022   dirbufr[3]++;
1023   if (MdcHostBig()) {
1024     MdcSWAW( (Uint16 *)dirbufr, (Uint16 *)dirbufr, 256);
1025     MdcSWAB( (Uint8 *)dirbufr, (Uint8 *)dirbufr, 512);
1026   }
1027   mdc_mat_wblk( fptr, dirblk, (Uint8 *)dirbufr, 1);
1028   return (nxtblk);
1029 }
1030 
mdc_mat_write_image(fptr,matnum,header,data,data_size)1031 Int32 mdc_mat_write_image( fptr, matnum, header, data, data_size)
1032   FILE *fptr;
1033   Int32 matnum;
1034   Mdc_Image_subheader *header;
1035   Uint16 *data;
1036   Int32 data_size;
1037 {
1038   Int32 nxtblk, size, error ;
1039 
1040   size = (data_size+511)/512;
1041   nxtblk = mdc_mat_enter( fptr, matnum, size);
1042   mdc_mat_write_image_subheader( fptr, nxtblk, header);
1043   error = mdc_write_matrix_data(fptr, nxtblk+1, size,
1044       (Uint8 *)data,
1045       header->data_type) ;
1046   return(error) ;
1047 }
1048 
mdc_mat_write_scan(fptr,matnum,header,data,data_size)1049 Int32 mdc_mat_write_scan( fptr, matnum, header, data, data_size)
1050   FILE *fptr;
1051   Int32 matnum;
1052   Mdc_Scan_subheader *header;
1053   Uint16 *data;
1054   Int32 data_size;
1055 {
1056   Int32 nxtblk, size, error ;
1057 
1058   size = (data_size+511)/512;
1059   nxtblk = mdc_mat_enter( fptr, matnum, size);
1060   mdc_mat_write_scan_subheader( fptr, nxtblk, header);
1061   error = mdc_write_matrix_data(fptr, nxtblk+1, size,
1062       (Uint8 *)data,
1063       header->data_type) ;
1064   return(error) ;
1065 }
1066 
mdc_mat_write_attn(fptr,matnum,header,data,data_size)1067 Int32 mdc_mat_write_attn( fptr, matnum, header, data, data_size)
1068   FILE *fptr;
1069   Int32 matnum;
1070   Mdc_Attn_subheader *header;
1071   float *data;
1072   Int32 data_size;
1073 {
1074   Int32 nxtblk, size, error ;
1075 
1076   size = (data_size+511)/512;
1077   nxtblk = mdc_mat_enter( fptr, matnum, size);
1078   mdc_mat_write_attn_subheader( fptr, nxtblk, header);
1079   error = mdc_write_matrix_data (fptr, nxtblk+1, size,
1080       (Uint8 *)data,
1081       header->data_type) ;
1082   return(error) ;
1083 }
1084 
mdc_mat_write_norm(fptr,matnum,header,data,data_size)1085 Int32 mdc_mat_write_norm( fptr, matnum, header, data, data_size)
1086   FILE *fptr;
1087   Int32 matnum;
1088   Mdc_Norm_subheader *header;
1089   float *data;
1090   Int32 data_size;
1091 {
1092   Int32 nxtblk, size, error ;
1093 
1094   size = (data_size+511)/512;
1095   nxtblk = mdc_mat_enter( fptr, matnum, size);
1096   mdc_mat_write_norm_subheader( fptr, nxtblk, header);
1097   error = mdc_write_matrix_data(fptr, nxtblk+1, size,
1098       (Uint8 *)data,
1099       header->data_type) ;
1100   return(error) ;
1101 }
1102 
mdc_mat_write_idata(fptr,blk,data,size)1103 Int32 mdc_mat_write_idata( fptr, blk, data, size)
1104   FILE *fptr;
1105   Int32 blk, size;
1106   Uint8 *data;
1107 {
1108   Uint8 bufr[512];
1109   Int32 i, nbytes, nblks;
1110 
1111   nblks = (size+511)/512;
1112   for (i=0; i<nblks; i++)
1113   {
1114     nbytes = (size < 512) ? size: 512;
1115     memcpy( (Uint8 *)bufr, (Uint8 *)data, (unsigned)nbytes);
1116     if (MdcHostBig())
1117       MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, 512);
1118     mdc_mat_wblk( fptr, blk+i, (Uint8 *)bufr, 1);
1119     data += nbytes;
1120     size -= nbytes;
1121   }
1122   return 0;
1123 }
1124 
mdc_mat_write_fdata(fptr,blk,data,size)1125 Int32 mdc_mat_write_fdata( fptr, blk, data, size)
1126   FILE *fptr;
1127   Int32 blk, size;
1128   float *data;
1129 {
1130   float bufr[128];
1131   Int32 i, j, nvals, nblks;
1132 
1133   nblks = (size+511)/512;
1134   for (i=0; i<nblks; i++)
1135   {
1136     nvals = (size < 512) ? size/4: 512/4;
1137     for (j=0; j<nvals; j++)
1138       mdc_hostftovaxf( *data++, (Uint16 *)&bufr[j]);
1139     if (MdcHostBig())
1140       MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, 512);
1141     mdc_mat_wblk( fptr, blk+i, (Uint8 *)bufr, 1);
1142     size -= 4*nvals;
1143   }
1144   return 0;
1145 }
1146 
mdc_matrix_selector(matnum,ranges)1147 Int32 mdc_matrix_selector( matnum, ranges)
1148   Int32 matnum, ranges[2][5];
1149 {
1150   struct Mdc_Matval m;
1151 
1152   mdc_mat_numdoc( matnum, &m);
1153   if (ranges[0][0] != -1)
1154     if (m.frame < ranges[0][0] || m.frame > ranges[1][0]) return (0);
1155   if (ranges[0][1] != -1)
1156     if (m.plane < ranges[0][1] || m.plane > ranges[1][1]) return (0);
1157   if (ranges[0][2] != -1)
1158     if (m.gate  < ranges[0][2] || m.gate  > ranges[1][2]) return (0);
1159   if (ranges[0][3] != -1)
1160     if (m.data  < ranges[0][3] || m.data  > ranges[1][3]) return (0);
1161   if (ranges[0][4] != -1)
1162     if (m.bed   < ranges[0][4] || m.bed   > ranges[1][4]) return (0);
1163   return (matnum);
1164 }
1165 
mdc_decode_selector(s1,ranges)1166 Int32 mdc_decode_selector( s1, ranges)
1167   char *s1; Int32 ranges[2][5];
1168 { char xword[16];
1169   Int32 i;
1170 
1171   mdc_fix_selector( s1, s1);
1172   for (i=0;i<5;i++) /* set all ranges to all (-1) */
1173   { ranges[0][i]=ranges[1][i]=-1;
1174     s1 = mdc_nex_word( s1, xword);
1175     if (xword[0] == '*') continue;
1176     else if (strchr(xword,':'))
1177       sscanf(xword,"%d:%d",&ranges[0][i],&ranges[1][i]);
1178     else
1179     { sscanf(xword,"%d",&ranges[0][i]);
1180       ranges[1][i]=ranges[0][i];
1181     };
1182   }
1183   return 0;
1184 }
1185 
mdc_str_find(s1,s2)1186 Int32 mdc_str_find( s1, s2)
1187   char *s1, *s2;
1188 {
1189   Int32 i, j, k;
1190 
1191   for (i=0;s1[i];i++) {
1192     for (j=i,k=0; s2[k]!='\0' && s1[j]==s2[k]; j++, k++) ;
1193     if (s2[k]=='\0') return (i);
1194   } return (-1);
1195 }
1196 
mdc_str_replace(s1,s2,s3,s4)1197 Int32 mdc_str_replace( s1, s2, s3, s4)
1198   char *s1, *s2, *s3, *s4;
1199 {
1200   Int32 nf=0, n;
1201 
1202   *s1 = '\0';
1203   while (1)
1204   { if ((n=mdc_str_find(s2, s3))==-1)
1205     { strcat(s1, s2);
1206       return (nf);
1207     } else
1208     { strncat(s1, s2, (unsigned)n);
1209       strcat(s1, s4);
1210       s2+= n+strlen(s3);
1211       nf++;
1212     }
1213   }
1214 }
1215 
mdc_string_replace(s1,s2,s3,s4)1216 Int32 mdc_string_replace( s1, s2, s3, s4)
1217   char *s1, *s2, *s3, *s4;
1218 {
1219   char temp[256];
1220 
1221   strcpy(temp, s2);
1222   while (mdc_str_replace(s1, temp, s3, s4) > 0)
1223     strcpy(temp, s1);
1224   return 0;
1225 }
1226 
mdc_fix_selector(s1,s2)1227 Int32 mdc_fix_selector( s1, s2)
1228   char *s1, *s2;
1229 {
1230   char temp[256];
1231   mdc_string_replace(temp, s2, "," , " ");
1232   mdc_string_replace(s1, temp, "..", ":");
1233   mdc_string_replace(temp, s1, ".", ":");
1234   mdc_string_replace(s1, temp, "-", ":");
1235   mdc_string_replace(temp, s1, "**", "*");
1236   mdc_string_replace(s1, temp, "  ", " ");
1237   mdc_string_replace(temp, s1, " :", ":");
1238   mdc_string_replace(s1, temp, ": ", ":");
1239   return 0;
1240 }
1241 
mdc_nex_word(s,w)1242 char* mdc_nex_word(s, w)
1243   char *s, *w;
1244 {
1245   while (*s && *s!=' ') *w++=*s++;
1246   *w='\0';
1247   if (*s) s++;
1248   return (s);
1249 }
1250 
1251 /********************************************************/
1252 /*  HOSTFTOVAXF                                         */
1253 /********************************************************/
1254 
mdc_hostftovaxf(float f_orig,Uint16 number[])1255 Int32 mdc_hostftovaxf(float f_orig, Uint16 number[])
1256 {
1257 
1258   /* convert from host float to vax float */
1259 
1260   union {
1261     Uint16 t[2];
1262     float t4;
1263   } test ;
1264   Uint16 exp;
1265 
1266   number[0] = 0;
1267   number[1] = 0;
1268 
1269   test.t4 = f_orig;
1270   if (test.t4 == 0.0)
1271     return 0;
1272 
1273   if (!MdcHostBig()) MdcSWAW((Uint16 *)test.t, (Uint16 *)test.t,2);
1274 
1275   number[1] = test.t[1];
1276 
1277   exp = ((test.t[0] & 0x7f00) + 0x0100) & 0x7f00;
1278   test.t[0] = (test.t[0] & 0x80ff) + exp;
1279 
1280   number[0] = test.t[0];
1281   return 0;
1282 
1283 }
1284 
1285 /*********************************************************/
mdc_mat_write_main_header(fptr,header)1286 Int32 mdc_mat_write_main_header( fptr, header)
1287   FILE *fptr; Mdc_Main_header *header;
1288 {
1289   Uint8 *bbufr;
1290   Int16 bufr[256];
1291   Int32 err,i;
1292 
1293   for (i=0; i<256; i++)
1294     bufr[i] = 0;
1295   bbufr = (Uint8 *) bufr;
1296 
1297   bufr[24] = header->sw_version;
1298   bufr[25] = header->data_type;
1299   bufr[26] = header->system_type;
1300   bufr[27] = header->file_type;
1301   bufr[33] = header->scan_start_day;
1302   bufr[34] = header->scan_start_month;
1303   bufr[35] = header->scan_start_year;
1304   bufr[36] = header->scan_start_hour;
1305   bufr[37] = header->scan_start_minute;
1306   bufr[38] = header->scan_start_second;
1307   mdc_hostftovaxf (header->isotope_halflife, (Uint16 *)&bufr[43]);
1308   mdc_hostftovaxf (header->gantry_tilt, (Uint16 *)&bufr[61]);
1309   mdc_hostftovaxf (header->gantry_rotation, (Uint16 *)&bufr[63]);
1310   mdc_hostftovaxf (header->bed_elevation, (Uint16 *)&bufr[65]);
1311   bufr[67] = header->rot_source_speed;
1312   bufr[68] = header->wobble_speed;
1313   bufr[69] = header->transm_source_type;
1314   mdc_hostftovaxf (header->axial_fov, (Uint16 *)&bufr[70]);
1315   mdc_hostftovaxf (header->transaxial_fov, (Uint16 *)&bufr[72]);
1316   bufr[74] = header->transaxial_samp_mode;
1317   bufr[75] = header->coin_samp_mode;
1318   bufr[76] = header->axial_samp_mode;
1319   mdc_hostftovaxf (header->calibration_factor,(Uint16 *)&bufr[77]);
1320   bufr[79] = header->calibration_units;
1321   bufr[80] = header->compression_code;
1322   bufr[175] = header->acquisition_type;
1323   bufr[176] = header->bed_type;
1324   bufr[177] = header->septa_type;
1325   bufr[188] = header->num_planes;
1326   bufr[189] = header->num_frames;
1327   bufr[190] = header->num_gates;
1328   bufr[191] = header->num_bed_pos;
1329   mdc_hostftovaxf (header->init_bed_position,(Uint16 *)&bufr[192]);
1330   for (i=0; i<15; i++)
1331   {
1332     mdc_hostftovaxf (header->bed_offset[i],(Uint16 *)&bufr[194+2*i]);
1333   }
1334   mdc_hostftovaxf (header->plane_separation,(Uint16 *)&bufr[224]);
1335   bufr[226] = header->lwr_sctr_thres;
1336   bufr[227] = header->lwr_true_thres;
1337   bufr[228] = header->upr_true_thres;
1338   mdc_hostftovaxf (header->collimator,(Uint16 *)&bufr[229]);
1339   bufr[236] = header->acquisition_mode;
1340 
1341   if (MdcHostBig())
1342     MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, MdcMatBLKSIZE);
1343 
1344   memcpy( bbufr+28, header->original_file_name, 20);
1345   /* write the node_id - character string */
1346   memcpy( bbufr+56, header->node_id, 10);
1347   /* write the isotope code - char string */
1348   memcpy( bbufr+78, header->isotope_code, 8);
1349   /* write the radiopharmaceutical  - char string */
1350   memcpy( bbufr+90, header->radiopharmaceutical, 32);
1351   /* study_name - char string */
1352   memcpy( bbufr+162, header->study_name, 12);
1353   /* patient_id - char string */
1354   memcpy( bbufr+174, header->patient_id, 16);
1355   /* patient_name - char string */
1356   memcpy( bbufr+190, header->patient_name, 32);
1357   /* patient_sex - char */
1358   bbufr[222] = header->patient_sex;
1359   /* patient_age - char string */
1360   memcpy( bbufr+223, header->patient_age, 10);
1361   /* patient_height  - char string */
1362   memcpy( bbufr+233, header->patient_height, 10);
1363   /* patient_weight - char string */
1364   memcpy( bbufr+243, header->patient_weight, 10);
1365   /* patient_dexterity - char */
1366   bbufr[253] = header->patient_dexterity;
1367   /* physician_name - char string */
1368   memcpy( bbufr+254, header->physician_name, 32);
1369   /* operator_name - char string */
1370   memcpy( bbufr+286, header->operator_name, 32);
1371   /* study_description - char string */
1372   memcpy( bbufr+318, header->study_description, 32);
1373   /* facility_name */
1374   memcpy( bbufr+356, header->facility_name, 20);
1375   /* user_process_code  - char string */
1376   memcpy( bbufr+462, header->user_process_code, 10);
1377 
1378   err = mdc_mat_wblk( fptr, 1, (Uint8 *)bufr, 1); /* write main header at block 1 */
1379   if (err) return(err);
1380 
1381   return (0);
1382 }
1383 
1384 /*********************************************************/
1385 
mdc_mat_write_image_subheader(fptr,blknum,header)1386 Int32 mdc_mat_write_image_subheader( fptr, blknum, header)
1387   FILE *fptr; Int32 blknum; Mdc_Image_subheader *header;
1388 {
1389   Uint8 *bbufr;
1390   Int16 bufr[256];
1391   Int32 i, err;
1392 
1393   for (i=0; i<256; i++)
1394     bufr[i] = 0;
1395   bbufr = (Uint8 *) bufr;
1396   /* transfer subheader information */
1397   bufr[63] = header->data_type;
1398   bufr[64] = header->num_dimensions;
1399   bufr[66] = header->dimension_1;
1400   bufr[67] = header->dimension_2;
1401   mdc_hostftovaxf(header->x_origin,(Uint16 *)&bufr[80]);
1402   mdc_hostftovaxf(header->y_origin,(Uint16 *)&bufr[82]);
1403   mdc_hostftovaxf(header->recon_scale,(Uint16 *)&bufr[84]);
1404   mdc_hostftovaxf(header->quant_scale,(Uint16 *)&bufr[86]);
1405   bufr[88] = header->image_min;
1406   bufr[89] = header->image_max;
1407   mdc_hostftovaxf(header->pixel_size,(Uint16 *)&bufr[92]);
1408   mdc_hostftovaxf(header->slice_width,(Uint16 *)&bufr[94]);
1409   mdc_hostltovaxl(header->frame_duration,(Uint16 *)&bufr[96]);
1410   mdc_hostltovaxl(header->frame_start_time,(Uint16 *)&bufr[98]);
1411   bufr[100] = header->slice_location;
1412   bufr[101] = header->recon_start_hour;
1413   bufr[102] = header->recon_start_minute;
1414   bufr[103] = header->recon_start_sec;
1415   mdc_hostltovaxl(header->gate_duration,(Uint16 *)&bufr[104]);
1416   bufr[118] = header->filter_code;
1417   mdc_hostltovaxl(header->scan_matrix_num,(Uint16 *)&bufr[119]);
1418   mdc_hostltovaxl(header->norm_matrix_num,(Uint16 *)&bufr[121]);
1419   mdc_hostltovaxl(header->atten_cor_matrix_num,(Uint16 *)&bufr[123]);
1420   mdc_hostftovaxf(header->image_rotation,(Uint16 *)&bufr[148]);
1421   mdc_hostftovaxf(header->plane_eff_corr_fctr,(Uint16 *)&bufr[150]);
1422   mdc_hostftovaxf(header->decay_corr_fctr,(Uint16 *)&bufr[152]);
1423   mdc_hostftovaxf(header->loss_corr_fctr,(Uint16 *)&bufr[154]);
1424   mdc_hostftovaxf(header->intrinsic_tilt,(Uint16 *)&bufr[156]);
1425   bufr[188] = header->processing_code;
1426   bufr[190] = header->quant_units;
1427   bufr[191] = header->recon_start_day;
1428   bufr[192] = header->recon_start_month;
1429   bufr[193] = header->recon_start_year;
1430   mdc_hostftovaxf(header->ecat_calibration_fctr,(Uint16 *)&bufr[194]);
1431   mdc_hostftovaxf(header->well_counter_cal_fctr,(Uint16 *)&bufr[196]);
1432 
1433   for (i=0; i<6; i++)
1434     mdc_hostftovaxf(header->filter_params[i],(Uint16 *)&bufr[198+2*i]);
1435 
1436   /* swap the bytes */
1437   if (MdcHostBig())
1438     MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, MdcMatBLKSIZE);
1439 
1440   strcpy ((char *)(bbufr+420), header->annotation);
1441 
1442   /* write to matrix file */
1443   err = mdc_mat_wblk( fptr, blknum, bbufr, 1);
1444   if (err) return(err);
1445 
1446   return(0);
1447 }
1448 
1449 /*********************************************************/
mdc_hostltovaxl(in,out)1450 Int32 mdc_hostltovaxl( in, out)
1451   Int32 in;
1452   Uint16 out[2];
1453 {
1454 
1455   out[0]=(in&0x0000FFFF);
1456   out[1]=(in&0xFFFF0000)>>16;
1457 
1458   return 0;
1459 }
1460 
1461 /*********************************************************/
mdc_mat_write_scan_subheader(fptr,blknum,header)1462 Int32 mdc_mat_write_scan_subheader( fptr, blknum, header)
1463   FILE *fptr;
1464   Int32 blknum;
1465   Mdc_Scan_subheader *header;
1466 {
1467   Int16 bufr[256];
1468   Int32 i, err;
1469 
1470   for (i=0; i<256; bufr[i++]=0);
1471   bufr[0] = 256;
1472   bufr[1] = 1;
1473   bufr[2] = 22;
1474   bufr[3] = -1;
1475   bufr[4] = 25;
1476   bufr[5] = 62;
1477   bufr[6] = 79;
1478   bufr[7] = 106;
1479   bufr[24] = 37;
1480   bufr[25] = -1;
1481   bufr[61] = 17;
1482   bufr[62] = -1;
1483   bufr[78] = 27;
1484   bufr[79] = -1;
1485   bufr[105] = 52;
1486   bufr[106] = -1;
1487   bufr[63] = header->data_type;
1488   bufr[66] = header->dimension_1;   /* x dimension */
1489   bufr[67] = header->dimension_2;   /* y_dimension */
1490   bufr[68] = header->smoothing;
1491   bufr[69] = header->processing_code;
1492   mdc_hostftovaxf(header->sample_distance,(Uint16 *)&bufr[73]);
1493   mdc_hostftovaxf(header->isotope_halflife,(Uint16 *)&bufr[83]);
1494   bufr[85] = header->frame_duration_sec;
1495   mdc_hostltovaxl(header->gate_duration,(Uint16 *)&bufr[86]);
1496   mdc_hostltovaxl(header->r_wave_offset,(Uint16 *)&bufr[88]);
1497   mdc_hostftovaxf(header->scale_factor,(Uint16 *)&bufr[91]);
1498   bufr[96] = header->scan_min;
1499   bufr[97] = header->scan_max;
1500   mdc_hostltovaxl(header->prompts,(Uint16 *)&bufr[98]);
1501   mdc_hostltovaxl(header->delayed,(Uint16 *)&bufr[100]);
1502   mdc_hostltovaxl(header->multiples,(Uint16 *)&bufr[102]);
1503   mdc_hostltovaxl(header->net_trues,(Uint16 *)&bufr[104]);
1504   for (i=0; i<16; i++)
1505   {
1506     mdc_hostftovaxf(header->cor_singles[i],(Uint16 *)&bufr[158+2*i]);
1507     mdc_hostftovaxf(header->uncor_singles[i],(Uint16 *)&bufr[190+2*i]);
1508   };
1509   mdc_hostftovaxf(header->tot_avg_cor,(Uint16 *)&bufr[222]);
1510   mdc_hostftovaxf(header->tot_avg_uncor,(Uint16 *)&bufr[224]);
1511   mdc_hostltovaxl(header->total_coin_rate,(Uint16 *)&bufr[226]);
1512   /* total coin rate */
1513   mdc_hostltovaxl(header->frame_start_time,(Uint16 *)&bufr[228]);
1514   mdc_hostltovaxl(header->frame_duration,(Uint16 *)&bufr[230]);
1515   mdc_hostftovaxf(header->loss_correction_fctr,(Uint16 *)&bufr[232]);
1516   for (i=0; i<8; i++)
1517     mdc_hostltovaxl(header->phy_planes[i],(Uint16 *)&bufr[234+2*i]);
1518 
1519 
1520   if (MdcHostBig())
1521     MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, MdcMatBLKSIZE);
1522 
1523   err = mdc_mat_wblk( fptr, blknum, (Uint8 *)bufr, 1);
1524   return (err);
1525 }
1526 
mdc_mat_write_attn_subheader(fptr,blknum,header)1527 Int32 mdc_mat_write_attn_subheader( fptr, blknum, header)
1528   FILE *fptr;
1529   Int32 blknum;
1530   Mdc_Attn_subheader *header;
1531 {
1532   Int16 bufr[256];
1533   Int32 i,err;
1534 
1535   for (i=0; i<256; bufr[i++]=0);
1536   bufr[0] = 256;
1537   bufr[1] = 1;
1538   bufr[2] = 22;
1539   bufr[3] = -1;
1540   bufr[4] = 25;
1541   bufr[5] = 62;
1542   bufr[6] = 79;
1543   bufr[7] = 106;
1544   bufr[24] = 37;
1545   bufr[25] = -1;
1546   bufr[61] = 17;
1547   bufr[62] = -1;
1548   bufr[78] = 27;
1549   bufr[79] = -1;
1550   bufr[105] = 52;
1551   bufr[106] = -1;
1552   bufr[63] = header->data_type;
1553   bufr[64] = header->attenuation_type;
1554   bufr[66] = header->dimension_1;
1555   bufr[67] = header->dimension_2;
1556   mdc_hostftovaxf( header->scale_factor,(Uint16 *)&bufr[91]);
1557   mdc_hostftovaxf( header->x_origin,(Uint16 *)&bufr[93]);
1558   mdc_hostftovaxf( header->y_origin,(Uint16 *)&bufr[95]);
1559   mdc_hostftovaxf( header->x_radius,(Uint16 *)&bufr[97]);
1560   mdc_hostftovaxf( header->y_radius,(Uint16 *)&bufr[99]);
1561   mdc_hostftovaxf( header->tilt_angle,(Uint16 *)&bufr[101]);
1562   mdc_hostftovaxf( header->attenuation_coeff,(Uint16 *)&bufr[103]);
1563   mdc_hostftovaxf( header->sample_distance,(Uint16 *)&bufr[105]);
1564   if (MdcHostBig())
1565     MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, 512);
1566   err = mdc_mat_wblk( fptr, blknum, (Uint8 *)bufr, 1);
1567   return (err);
1568 }
1569 
mdc_mat_write_norm_subheader(fptr,blknum,header)1570 Int32 mdc_mat_write_norm_subheader( fptr, blknum, header)
1571   FILE *fptr;
1572   Int32 blknum;
1573   Mdc_Norm_subheader *header;
1574 {
1575   Int16 bufr[256];
1576   Int32 i,err;
1577 
1578   for (i=0; i<256; bufr[i++]=0);
1579   bufr[0] = 256;
1580   bufr[1] = 1;
1581   bufr[2] = 22;
1582   bufr[3] = -1;
1583   bufr[4] = 25;
1584   bufr[5] = 62;
1585   bufr[6] = 79;
1586   bufr[7] = 106;
1587   bufr[24] = 37;
1588   bufr[25] = -1;
1589   bufr[61] = 17;
1590   bufr[62] = -1;
1591   bufr[78] = 27;
1592   bufr[79] = -1;
1593   bufr[105] = 52;
1594   bufr[106] = -1;
1595   bufr[63] = header->data_type;
1596   bufr[66] = header->dimension_1;
1597   bufr[67] = header->dimension_2;
1598   mdc_hostftovaxf( header->scale_factor,(Uint16 *)&bufr[91]);
1599   bufr[93] = header->norm_hour;
1600   bufr[94] = header->norm_minute;
1601   bufr[95] = header->norm_second;
1602   bufr[96] = header->norm_day;
1603   bufr[97] = header->norm_month;
1604   bufr[98] = header->norm_year;
1605   mdc_hostftovaxf( header->fov_source_width,(Uint16 *)&bufr[99]);
1606   mdc_hostftovaxf( header->ecat_calib_factor,(Uint16 *)&bufr[101]);
1607   if (MdcHostBig())
1608     MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, 512);
1609   err = mdc_mat_wblk( fptr, blknum, (Uint8 *)bufr, 1);
1610   return (err);
1611 }
1612 
mdc_mat_read_attn_subheader(fptr,blknum,header)1613 Int32 mdc_mat_read_attn_subheader( fptr, blknum, header)
1614   FILE *fptr;
1615   Int32 blknum;
1616   Mdc_Attn_subheader *header;
1617 {
1618   Int16 bufr[256];
1619   Int32 err;
1620 
1621   err = mdc_mat_rblk( fptr, blknum, (Uint8 *)bufr, 1);
1622   if (err) return(err);
1623   if (MdcHostBig())
1624     MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, MdcMatBLKSIZE);
1625 
1626   header->data_type = bufr[63];
1627   header->attenuation_type = bufr[64];
1628   header->dimension_1 = bufr[66];
1629   header->dimension_2 = bufr[67];
1630   header->scale_factor = mdc_get_vax_float((Uint16 *)bufr, 91);
1631   header->x_origin = mdc_get_vax_float((Uint16 *)bufr, 93);
1632   header->y_origin = mdc_get_vax_float((Uint16 *)bufr, 95);
1633   header->x_radius = mdc_get_vax_float((Uint16 *)bufr, 97);
1634   header->y_radius = mdc_get_vax_float((Uint16 *)bufr, 99);
1635   header->tilt_angle = mdc_get_vax_float((Uint16 *)bufr, 101);
1636   header->attenuation_coeff = mdc_get_vax_float((Uint16 *)bufr, 103);
1637   header->sample_distance = mdc_get_vax_float((Uint16 *)bufr, 105);
1638   return (0);
1639 }
1640 
mdc_mat_read_attn_subheader7(fptr,blknum,h)1641 Int32 mdc_mat_read_attn_subheader7( fptr, blknum, h)
1642   FILE *fptr;
1643   Int32 blknum;
1644   Mdc_Attn_subheader7 *h;
1645 {
1646   Int16 b[256];
1647   Int32 err, i;
1648   char *bb;
1649 
1650   err = mdc_mat_rblk( fptr, blknum, (Uint8 *)b, 1);
1651   if (err) return(err);
1652   bb = (char *)b;
1653 
1654   memcpy(&h->data_type             ,bb    ,  2); MdcSWAP(h->data_type);
1655   memcpy(&h->num_dimensions        ,bb+  2,  2); MdcSWAP(h->num_dimensions);
1656   memcpy(&h->attenuation_type      ,bb+  4,  2); MdcSWAP(h->attenuation_type);
1657   memcpy(&h->num_r_elements        ,bb+  6,  2); MdcSWAP(h->num_r_elements);
1658   memcpy(&h->num_angles            ,bb+  8,  2); MdcSWAP(h->num_angles);
1659   memcpy(&h->num_z_elements        ,bb+ 10,  2); MdcSWAP(h->num_z_elements);
1660   memcpy(&h->ring_difference       ,bb+ 12,  2); MdcSWAP(h->ring_difference);
1661   memcpy(&h->x_resolution          ,bb+ 14,  4); MdcSWAP(h->x_resolution);
1662   memcpy(&h->y_resolution          ,bb+ 18,  4); MdcSWAP(h->y_resolution);
1663   memcpy(&h->z_resolution          ,bb+ 22,  4); MdcSWAP(h->z_resolution);
1664   memcpy(&h->w_resolution          ,bb+ 26,  4); MdcSWAP(h->w_resolution);
1665   memcpy(&h->scale_factor          ,bb+ 30,  4); MdcSWAP(h->scale_factor);
1666   memcpy(&h->x_offset              ,bb+ 34,  4); MdcSWAP(h->x_offset);
1667   memcpy(&h->y_offset              ,bb+ 38,  4); MdcSWAP(h->y_offset);
1668   memcpy(&h->x_radius              ,bb+ 42,  4); MdcSWAP(h->x_radius);
1669   memcpy(&h->y_radius              ,bb+ 46,  4); MdcSWAP(h->y_radius);
1670   memcpy(&h->tilt_angle            ,bb+ 50,  4); MdcSWAP(h->tilt_angle);
1671   memcpy(&h->attenuation_coeff     ,bb+ 54,  4); MdcSWAP(h->attenuation_coeff);
1672   memcpy(&h->attenuation_min       ,bb+ 58,  4); MdcSWAP(h->attenuation_min);
1673   memcpy(&h->attenuation_max       ,bb+ 62,  4); MdcSWAP(h->attenuation_max);
1674   memcpy(&h->skull_thickness       ,bb+ 66,  4); MdcSWAP(h->skull_thickness);
1675   memcpy(&h->num_xtra_atten_coeff  ,bb+ 70,  2);
1676   MdcSWAP(h->num_xtra_atten_coeff);
1677   memcpy(&h->xtra_atten_coeff      ,bb+ 72, 32);
1678   for (i=0; i<8;  i++) MdcSWAP(h->xtra_atten_coeff[i]);
1679   memcpy(&h->edge_finding_threshold,bb+104,  4);
1680   MdcSWAP(h->edge_finding_threshold);
1681   memcpy(&h->storage_order         ,bb+108,  2); MdcSWAP(h->storage_order);
1682   memcpy(&h->span                  ,bb+110,  2); MdcSWAP(h->span);
1683   memcpy(&h->z_elements            ,bb+112,128);
1684   for (i=0; i<64; i++) MdcSWAP(h->z_elements[i]);
1685   memcpy(&h->fill_unused           ,bb+240,172);
1686   for (i=0; i<86; i++) MdcSWAP(h->fill_unused[i]);
1687   memcpy(&h->fill_user             ,bb+412,100);
1688   for (i=0; i<50; i++) MdcSWAP(h->fill_user[i]);
1689 
1690   return (0);
1691 }
1692 
mdc_mat_read_norm_subheader(fptr,blknum,header)1693 Int32 mdc_mat_read_norm_subheader( fptr, blknum, header)
1694   FILE *fptr; Int32 blknum; Mdc_Norm_subheader *header;
1695 {
1696   Int16 bufr[256];
1697   Int32 err;
1698 
1699   err = mdc_mat_rblk( fptr, blknum, (Uint8 *)bufr, 1);
1700   if (err) return(err);
1701   if (MdcHostBig())
1702     MdcSWAB( (Uint8 *)bufr, (Uint8 *)bufr, MdcMatBLKSIZE);
1703 
1704   header->data_type = bufr[63];
1705   header->dimension_1 = bufr[66];
1706   header->dimension_2 = bufr[67];
1707   header->scale_factor = mdc_get_vax_float((Uint16 *)bufr, 91);
1708   header->norm_hour = bufr[93];
1709   header->norm_minute = bufr[94];
1710   header->norm_second = bufr[95];
1711   header->norm_day = bufr[96];
1712   header->norm_month = bufr[97];
1713   header->norm_year = bufr[98];
1714   header->fov_source_width = mdc_get_vax_float((Uint16 *)bufr, 99);
1715   header->ecat_calib_factor = mdc_get_vax_float((Uint16 *)bufr, 101);
1716   return (0);
1717 }
1718 
1719 /* Following function was copied from CTI-source file 'matrix_extra.c' */
1720 /* and slightly modified ...                                           */
1721 
mdc_write_matrix_data(fptr,strtblk,nblks,dptr,dtype)1722 Int32 mdc_write_matrix_data(fptr, strtblk, nblks, dptr, dtype)
1723   FILE *fptr;
1724   Int32 strtblk,
1725   nblks,
1726   dtype;
1727 Uint8 *dptr;
1728 {
1729   Int32 err;
1730 
1731   switch (dtype)
1732   {
1733     case 1: /* byte format...no
1734                  * translation necessary */
1735       err = mdc_mat_wblk(fptr, strtblk, dptr, nblks);
1736       break;
1737     case 2: /* Vax I*2 */
1738       err = mdc_mat_write_idata(fptr, strtblk, (Uint8 *)dptr, 512 * nblks);
1739       break;
1740     case 4: /* Vax R*4 */
1741       err = mdc_mat_write_fdata(fptr, strtblk, (float *)dptr, 512 * nblks);
1742       break;
1743     case 5: /* IEEE R*4 */
1744       err = mdc_mat_wblk(fptr, strtblk, dptr, nblks);
1745       break;
1746     case 6: /* 68K I*2 */
1747       err = mdc_mat_wblk(fptr, strtblk, dptr, nblks);
1748       break;
1749     case 7: /* 68K I*4 */
1750       err = mdc_mat_wblk(fptr, strtblk, dptr, nblks);
1751       break;
1752     default:  /* something
1753                  * else...treat as Vax
1754                  * I*2 */
1755       err = mdc_mat_write_idata(fptr, strtblk, (Uint8 *)dptr, 512 * nblks);
1756       break;
1757   }
1758 
1759   return (err);
1760 }
1761 
1762 /* code from mat_get_spec.c */
mdc_mat_get_spec(char * file,Int32 * num_frames,Int32 * num_planes,Int32 * num_gates,Int32 * num_bed)1763 Int32 mdc_mat_get_spec (char *file, Int32 *num_frames, Int32 *num_planes, Int32 *num_gates, Int32 *num_bed)
1764 {
1765   struct Mdc_MatDir matrixlist[5000];
1766   FILE *fptr;
1767   Int32 status, num_matrices, i;
1768   struct Mdc_Matval matnum;
1769 
1770   /* initialization */
1771   status = 0;
1772   *num_frames = 0;
1773   *num_planes = 0;
1774   *num_gates = 0;
1775   *num_bed = 0;
1776 
1777   /* open the specified file */
1778   fptr = mdc_mat_open (file, "r");
1779   if (fptr != NULL)
1780   {
1781     /* get the matrix entries */
1782     num_matrices = mdc_mat_list( fptr, matrixlist, 5000);
1783 
1784     for (i=0; i<num_matrices; i++)
1785     {
1786       mdc_mat_numdoc (matrixlist[i].matnum, &matnum);
1787 
1788       if (matnum.frame > *num_frames)
1789         (*num_frames)++;
1790 
1791       if (matnum.plane > *num_planes)
1792         (*num_planes)++;
1793 
1794       if (matnum.gate > *num_gates)
1795         (*num_gates)++;
1796 
1797       if (matnum.bed > *num_bed)
1798         (*num_bed)++;
1799     }
1800 
1801     /* bed is zero based in the matrix number, but all numbers returned */
1802     /* from this function will be one based                             */
1803     (*num_bed)++;
1804     mdc_mat_close (fptr);
1805   }
1806   else
1807     status = 1;
1808 
1809   return(status);
1810 }
1811 
1812 /* code from sort_order.c */
1813 
mdc_compare_anatloc(const void * vi,const void * vj)1814 static int mdc_compare_anatloc(const void *vi, const void *vj)
1815 {
1816   struct ExpMatDir *i, *j;
1817 
1818   i = (struct ExpMatDir *)vi;
1819   j = (struct ExpMatDir *)vj;
1820 
1821   if (i->anatloc < j->anatloc) return (-1);
1822   if (i->anatloc > j->anatloc) return (1);
1823   return (0);
1824 }
1825 
1826 /* matrix list by anatomical position */
mdc_anatomical_sort(struct Mdc_MatDir matrix_list[],Int32 num_matrices,Mdc_Main_header * mhead,Int32 num_bed_pos)1827 void mdc_anatomical_sort (struct Mdc_MatDir matrix_list[], Int32 num_matrices, Mdc_Main_header *mhead, Int32 num_bed_pos)
1828 {
1829   struct Mdc_Matval matval;
1830   Int32 i, plane, bed;
1831   float bed_pos[16], plane_separation;
1832   struct ExpMatDir exp_matlist[5000];
1833 
1834   bed_pos[0] = 0.0;
1835   for (i=1; i < num_bed_pos; i++)
1836     bed_pos[i] = mhead->bed_offset[i-1];
1837 
1838   plane_separation = mhead->plane_separation;
1839 
1840   /* if plane separation not filled in main header, use plane number to sort */
1841   if (plane_separation == 0.0) plane_separation = 1.0;
1842 
1843   for (i=0; i < num_matrices; i++)
1844   {
1845     mdc_mat_numdoc (matrix_list[i].matnum, &matval);
1846     plane = matval.plane;
1847     bed = matval.bed;
1848     exp_matlist[i].matnum = matrix_list[i].matnum;
1849     exp_matlist[i].strtblk = matrix_list[i].strtblk;
1850     exp_matlist[i].endblk = matrix_list[i].endblk;
1851     exp_matlist[i].matstat = matrix_list[i].matstat;
1852     exp_matlist[i].anatloc = bed_pos[bed]+(plane-1)*plane_separation;
1853   }
1854 
1855   qsort(exp_matlist,(unsigned)num_matrices
1856       ,sizeof(struct ExpMatDir)
1857       ,mdc_compare_anatloc);
1858 
1859   for (i=0; i < num_matrices; i++)
1860   {
1861     matrix_list[i].matnum = exp_matlist[i].matnum;
1862     matrix_list[i].strtblk = exp_matlist[i].strtblk;
1863     matrix_list[i].endblk = exp_matlist[i].endblk;
1864     matrix_list[i].matstat = exp_matlist[i].matstat;
1865   }
1866 }
1867 
mdc_compmatdir(const void * vi,const void * vj)1868 static int mdc_compmatdir(const void *vi, const void *vj)
1869 {
1870   struct Mdc_MatDir *i, *j;
1871 
1872   i = (struct Mdc_MatDir *)vi;
1873   j = (struct Mdc_MatDir *)vj;
1874 
1875   return((i->matnum - j->matnum));
1876 }
1877 
1878 
mdc_matnum_sort(struct Mdc_MatDir mlist[],Int32 num_entry)1879 void mdc_matnum_sort(struct Mdc_MatDir mlist[], Int32 num_entry)
1880 {
1881   qsort(mlist,(unsigned)num_entry, sizeof(struct Mdc_MatDir), mdc_compmatdir);
1882 }
1883 
1884 /* sort by planes varying first */
mdc_plane_sort(struct Mdc_MatDir matrix_list[],Int32 num_matrices)1885 void mdc_plane_sort (struct Mdc_MatDir matrix_list[], Int32 num_matrices)
1886 {
1887   struct Mdc_Matval matval;
1888   Int32 i, frame, plane, bed;
1889   struct ExpMatDir exp_matlist[5000];
1890 
1891   for (i=0; i < num_matrices; i++)
1892   {
1893     mdc_mat_numdoc (matrix_list[i].matnum, &matval);
1894     plane = matval.plane;
1895     frame = matval.frame;
1896     bed = matval.bed;
1897     exp_matlist[i].matnum = matrix_list[i].matnum;
1898     exp_matlist[i].strtblk = matrix_list[i].strtblk;
1899     exp_matlist[i].endblk = matrix_list[i].endblk;
1900     exp_matlist[i].matstat = matrix_list[i].matstat;
1901     exp_matlist[i].anatloc = (float)(frame*1000 + plane*10 + bed);
1902   }
1903 
1904   qsort (exp_matlist,(unsigned)num_matrices
1905       ,sizeof(struct ExpMatDir)
1906       ,mdc_compare_anatloc);
1907 
1908   for (i=0; i < num_matrices; i++)
1909   {
1910     matrix_list[i].matnum = exp_matlist[i].matnum;
1911     matrix_list[i].strtblk = exp_matlist[i].strtblk;
1912     matrix_list[i].endblk = exp_matlist[i].endblk;
1913     matrix_list[i].matstat = exp_matlist[i].matstat;
1914   }
1915 
1916 }
1917