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