Attachment 'mriio.c'
Download 1 /*
2 * FILE NAME: mriio.c
3 *
4 * DESCRIPTION: utilities for reading/writing MRI data structure
5 *
6 * AUTHOR: Bruce Fischl
7 * DATE: 4/12/97
8 *
9 */
10
11 /*-----------------------------------------------------
12 INCLUDE FILES
13 -------------------------------------------------------*/
14 #define USE_ELECTRIC_FENCE 1
15 #define _MRIIO_SRC
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <unistd.h>
24 #include <memory.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <ctype.h>
28 #include <dirent.h>
29 #include <time.h>
30 #include <errno.h>
31 #include <fcntl.h>
32
33 #include "utils.h"
34 #include "error.h"
35 #include "proto.h"
36 #include "mri.h"
37 #include "macros.h"
38 #include "diag.h"
39 #include "volume_io.h"
40 #include "region.h"
41 #include "machine.h"
42 #include "analyze.h"
43 #include "fio.h"
44 #include "mri_identify.h"
45 #include "signa.h"
46 #include "fio.h"
47 #include "matfile.h"
48 #include "math.h"
49 #include "matrix.h"
50 #include "diag.h"
51 #include "chklc.h"
52 #include "mriColorLookupTable.h"
53 #include "DICOMRead.h"
54 #include "imautils.h"
55 #include "cma.h"
56 #include "Bruker.h"
57 #include "bfileio.h"
58 #include "AFNI.h"
59 #include "mghendian.h"
60 #include "tags.h"
61 #ifdef Darwin
62 // /usr/include/zconf.h should typedef Byte, but doesnt on the Mac:
63 typedef unsigned char Byte; /* 8 bits */
64 #endif
65 #include "nifti1.h"
66 #include "znzlib.h"
67
68 // unix director separator
69 #define DIR_SEPARATOR '/'
70 #define CURDIR "./"
71
72 #define MM_PER_METER 1000.0f
73 #define INFO_FNAME "COR-.info"
74
75 #ifdef Linux
76 extern void swab(const void *from, void *to, size_t n);
77 #endif
78
79 #if 0
80 static int NormalizeVector(float *v, int n);
81 static MRI *mincRead2(char *fname, int read_volume);
82 static int mincWrite2(MRI *mri, char *fname);
83 static int GetMINCInfo(MRI *mri,
84 char *dim_names[4],
85 int dim_sizes[4],
86 Real separations[4],
87 Real dircos[3][3],
88 Real VolCenterVox[3],
89 Real VolCenterWorld[3]);
90 #endif
91
92 static MRI *mri_read
93 (char *fname, int type, int volume_flag, int start_frame, int end_frame);
94 static MRI *corRead(char *fname, int read_volume);
95 static int corWrite(MRI *mri, char *fname);
96 static MRI *siemensRead(char *fname, int read_volume);
97 static MRI *readGCA(char *fname) ;
98
99 static MRI *mincRead(char *fname, int read_volume);
100 static int mincWrite(MRI *mri, char *fname);
101 static int bvolumeWrite(MRI *vol, char *fname_passed, int type);
102 //static int bshortWrite(MRI *mri, char *fname_passed);
103 //static int bfloatWrite(MRI *mri, char *stem);
104 static int write_bhdr(MRI *mri, FILE *fp);
105 static int read_bhdr(MRI *mri, FILE *fp);
106
107 static MRI *bvolumeRead(char *fname_passed, int read_volume, int type);
108 //static MRI *bshortRead(char *fname_passed, int read_volume);
109 //static MRI *bfloatRead(char *fname_passed, int read_volume);
110 static MRI *genesisRead(char *stem, int read_volume);
111 static MRI *gelxRead(char *stem, int read_volume);
112
113 static int CountAnalyzeFiles(char *analyzefname, int nzpad, char **ppstem);
114 static MRI *analyzeRead(char *fname, int read_volume);
115 static dsr *ReadAnalyzeHeader(char *hdrfile, int *swap,
116 int *mritype, int *bytes_per_voxel);
117 static int DumpAnalyzeHeader(FILE *fp, dsr *hdr);
118
119
120 static int analyzeWrite(MRI *mri, char *fname);
121 static int analyzeWriteFrame(MRI *mri, char *fname, int frame);
122 static int analyzeWriteSeries(MRI *mri, char *fname);
123 static int analyzeWrite4D(MRI *mri, char *fname);
124
125 static void swap_analyze_header(dsr *hdr);
126
127 #if 0
128 static int orient_with_register(MRI *mri);
129 #endif
130 static int nan_inf_check(MRI *mri);
131 #ifdef VC_TO_CV
132 static int voxel_center_to_center_voxel
133 (MRI *mri, float *x, float *y, float *z);
134 #endif
135 static MRI *gdfRead(char *fname, int read_volume);
136 static int gdfWrite(MRI *mri, char *fname);
137
138 static MRI *ximgRead(char *fname, int read_volume);
139
140 static MRI *nifti1Read(char *fname, int read_volume);
141 static int nifti1Write(MRI *mri, char *fname);
142 static MRI *niiRead(char *fname, int read_volume);
143 static int niiWrite(MRI *mri, char *fname);
144 static int niftiQformToMri(MRI *mri, struct nifti_1_header *hdr);
145 static int mriToNiftiQform(MRI *mri, struct nifti_1_header *hdr);
146 static int niftiSformToMri(MRI *mri, struct nifti_1_header *hdr);
147 static void swap_nifti_1_header(struct nifti_1_header *hdr);
148 static MRI *MRISreadCurvAsMRI(char *curvfile, int read_volume);
149
150 /********************************************/
151
152 static void short_local_buffer_to_image
153 (short *buf, MRI *mri, int slice, int frame) ;
154
155 static void int_local_buffer_to_image
156 (int *buf, MRI *mri, int slice, int frame) ;
157
158 static void long32_local_buffer_to_image
159 (long32 *buf, MRI *mri, int slice, int frame) ;
160
161 static void float_local_buffer_to_image
162 (float *buf, MRI *mri, int slice, int frame) ;
163
164 static void local_buffer_to_image
165 (BUFTYPE *buf, MRI *mri, int slice, int frame) ;
166
167 static MRI *sdtRead(char *fname, int read_volume);
168 static MRI *mghRead(char *fname, int read_volume, int frame) ;
169 static int mghWrite(MRI *mri, char *fname, int frame) ;
170 static int mghAppend(MRI *mri, char *fname, int frame) ;
171
172 /********************************************/
173
174 extern int errno;
175
176 extern char *Progname;
177 /*char *Progname;*/
178
179 static char *command_line;
180 static char *subject_name;
181
182 #define MAX_UNKNOWN_LABELS 100
183
184 static short cma_field[512][512];
185 static char unknown_labels[MAX_UNKNOWN_LABELS][STRLEN];
186 static int n_unknown_labels;
187
188 //////////////////////////////////////////////////////////////////////
189 // this is a one way of setting direction cosine
190 // when the direction cosine is not provided in the volume.
191 // may not agree with the volume. what can we do? Let them set by themselves.
192 int setDirectionCosine(MRI *mri, int orientation)
193 {
194 switch(orientation)
195 {
196 case MRI_CORONAL: // x is from right to left.
197 // y is from top to neck, z is from back to front
198 mri->x_r = -1; mri->y_r = 0; mri->z_r = 0; mri->c_r = 0;
199 mri->x_a = 0; mri->y_a = 0; mri->z_a = 1; mri->c_a = 0;
200 mri->x_s = 0; mri->y_s = -1; mri->z_s = 0; mri->c_s = 0;
201 break;
202 case MRI_SAGITTAL: // x is frp, back to front,
203 // y is from top to neck, z is from left to right
204 mri->x_r = 0; mri->y_r = 0; mri->z_r = 1; mri->c_r = 0;
205 mri->x_a = 1; mri->y_a = 0; mri->z_a = 0; mri->c_a = 0;
206 mri->x_s = 0; mri->y_s = -1; mri->z_s = 0; mri->c_s = 0;
207 break;
208 case MRI_HORIZONTAL: // x is from right to left,
209 // y is from front to back, z is from neck to top
210 mri->x_r = -1; mri->y_r = 0; mri->z_r = 0; mri->c_r = 0;
211 mri->x_a = 0; mri->y_a = -1; mri->z_a = 0; mri->c_a = 0;
212 mri->x_s = 0; mri->y_s = 0; mri->z_s = 1; mri->c_s = 0;
213 break;
214 default:
215 ErrorReturn
216 (ERROR_BADPARM,
217 (ERROR_BADPARM, "setDirectionCosine():unknown slice direction"));
218 break; // should not reach here (handled at the conversion)
219 }
220 return (NO_ERROR);
221 }
222
223 #define isOne(a) (fabs(fabs(a)-1)<0.00001)
224
225 // here I take the narrow view of slice_direction
226 int getSliceDirection(MRI *mri)
227 {
228 int direction = MRI_UNDEFINED;
229
230 if (isOne(mri->x_r) && isOne(mri->y_s) && isOne(mri->z_a))
231 direction = MRI_CORONAL;
232 else if (isOne(mri->x_a) && isOne(mri->y_s) && isOne(mri->z_r))
233 direction = MRI_SAGITTAL;
234 else if (isOne(mri->x_r) && isOne(mri->y_a) && isOne( mri->z_s))
235 direction = MRI_HORIZONTAL;
236 return direction;
237 }
238
239 // For surface, we currently cannot handle volumes with general slice direction
240 // nor we cannot handle non-conformed volumes
241 int mriOKforSurface(MRI *mri)
242 {
243 // first check slice direction
244 if (getSliceDirection(mri) != MRI_CORONAL)
245 return 0;
246 // remove slice size limitation
247 // else if (mri->width != 256 || mri->height != 256 || mri->depth != 256)
248 // return 0;
249 // remove check for 1 mm size
250 // else if (mri->xsize != 1 || mri->ysize != 1 || mri->zsize != 1)
251 // return 0;
252 else
253 return 1;
254 }
255
256 int mriConformed(MRI *mri)
257 {
258 // first check slice direction
259 if (getSliceDirection(mri) != MRI_CORONAL)
260 return 0;
261 else if (mri->width != 256 || mri->height != 256 || mri->depth != 256)
262 return 0;
263 else if (mri->xsize != 1 || mri->ysize != 1 || mri->zsize != 1)
264 return 0;
265 else
266 return 1;
267 }
268
269 void setMRIforSurface(MRI *mri)
270 {
271 if (!mriOKforSurface(mri))
272 ErrorExit(ERROR_BADPARM,
273 "%s: the volume is not conformed, that is, "
274 "the volume must be in CORONAL direction.\n", Progname) ;
275 #if 0
276 else
277 {
278 // we checked conformed in mriOKforSurface().
279 // The only thing missing is c_(r,a,s) = 0
280 // for surface creation assume that the
281 // volume is conformed and c_(r,a,s) = 0
282 mri->c_r=mri->c_a=mri->c_s = 0;
283 if (mri->i_to_r__)
284 MatrixFree(&mri->i_to_r__) ;
285 if (mri->r_to_i__)
286 MatrixFree(&mri->r_to_i__) ;
287 mri->i_to_r__ = extract_i_to_r(mri);
288 mri->r_to_i__ = extract_r_to_i(mri);
289 }
290 #endif
291 }
292
293 int mriio_command_line(int argc, char *argv[])
294 {
295
296 int i;
297 int length;
298 char *c;
299
300 length = 0;
301 for(i = 0;i < argc;i++)
302 length += strlen(argv[i]);
303
304 /* --- space for spaces and \0 --- */
305 length += argc;
306
307 command_line = (char *)malloc(length);
308
309 c = command_line;
310 for(i = 0;i < argc;i++)
311 {
312 strcpy(c, argv[i]);
313 c += strlen(argv[i]);
314 *c = (i == argc-1 ? '\0' : ' ');
315 c++;
316 }
317
318 return(NO_ERROR);
319
320 } /* end mriio_command_line() */
321
322 int mriio_set_subject_name(char *name)
323 {
324
325 if(subject_name == NULL)
326 subject_name = (char *)malloc(STRLEN);
327
328 if(subject_name == NULL)
329 {
330 errno = 0;
331 ErrorReturn(ERROR_NO_MEMORY, (ERROR_NO_MEMORY,
332 "mriio_set_subject_name(): "
333 "could't allocate %d bytes...!", STRLEN));
334 }
335
336 if(name == NULL)
337 strcpy(subject_name, name);
338 else
339 {
340 free(subject_name);
341 subject_name = NULL;
342 }
343
344 return(NO_ERROR);
345
346 } /* end mriio_set_subject_name() */
347
348 int MRIgetVolumeName(char *string, char *name_only)
349 {
350
351 char *at, *pound;
352
353 strcpy(name_only, string);
354
355 if((at = strrchr(name_only, '@')) != NULL)
356 *at = '\0';
357
358 if((pound = strrchr(name_only, '#')) != NULL)
359 *pound = '\0';
360
361 return(NO_ERROR);
362
363 } /* end MRIgetVolumeName() */
364
365 static MRI *mri_read
366 (char *fname, int type, int volume_flag, int start_frame, int end_frame)
367 {
368 MRI *mri, *mri2;
369 IMAGE *I;
370 char fname_copy[STRLEN];
371 char *ptmpstr;
372 char *at, *pound, *colon;
373 char *ep;
374 int i, j, k, t;
375 int volume_frames;
376
377 // sanity-checks
378 if(fname == NULL)
379 {
380 errno = 0;
381 ErrorReturn(NULL, (ERROR_BADPARM, "mri_read(): null fname!\n"));
382 }
383 if(fname[0] == 0)
384 {
385 errno = 0;
386 ErrorReturn(NULL, (ERROR_BADPARM, "mri_read(): empty fname!\n"));
387 }
388
389 // if filename does not contain any directory separator, then add cwd
390 if (!strchr(fname,DIR_SEPARATOR))
391 {
392 char *cwd = getcwd(NULL, 0); // posix 1 extension
393 // (allocate as much space needed)
394 if (cwd)
395 {
396 strcpy(fname_copy, cwd);
397 strcat(fname_copy, "/");
398 strcat(fname_copy, fname);
399 free(cwd);
400 }
401 else // why fail?
402 strcpy(fname_copy, fname);
403 }
404 else
405 strcpy(fname_copy, fname);
406
407 at = strrchr(fname_copy, '@');
408 pound = strrchr(fname_copy, '#');
409
410 if(at != NULL)
411 {
412 *at = '\0';
413 at++;
414 }
415
416 if(pound != NULL)
417 {
418 *pound = '\0';
419 pound++;
420 }
421
422 if(at != NULL)
423 {
424 type = string_to_type(at);
425 if(type == MRI_VOLUME_TYPE_UNKNOWN)
426 {
427 errno = 0;
428 ErrorReturn
429 (NULL, (ERROR_BADPARM, "mri_read(): unknown type '%s'\n", at));
430 }
431 }
432 else if(type == MRI_VOLUME_TYPE_UNKNOWN)
433 {
434 type = mri_identify(fname_copy);
435 if(type == MRI_VOLUME_TYPE_UNKNOWN)
436 {
437 errno = 0;
438 ErrorReturn
439 (NULL,
440 (ERROR_BADPARM,
441 "mri_read(): couldn't determine type of file %s", fname_copy));
442 }
443 }
444
445 if(pound != NULL)
446 {
447 colon = strchr(pound, ':');
448 if(colon != NULL)
449 {
450 *colon = '\0';
451 colon++;
452 if(*colon == '\0')
453 {
454 errno = 0;
455 ErrorReturn
456 (NULL,
457 (ERROR_BADPARM,
458 "mri_read(): bad frame specification ('%s:')\n", pound));
459 }
460
461 start_frame = strtol(pound, &ep, 10);
462 if(*ep != '\0')
463 {
464 errno = 0;
465 ErrorReturn
466 (NULL,
467 (ERROR_BADPARM,
468 "mri_read(): bad start frame ('%s')\n", pound));
469 }
470
471 end_frame = strtol(colon, &ep, 10);
472 if(*ep != '\0')
473 {
474 errno = 0;
475 ErrorReturn
476 (NULL,
477 (ERROR_BADPARM,
478 "mri_read(): bad end frame ('%s')\n", colon));
479 }
480
481 }
482 else
483 {
484 start_frame = end_frame = strtol(pound, &ep, 10);
485 if(*ep != '\0')
486 {
487 errno = 0;
488 ErrorReturn
489 (NULL,
490 (ERROR_BADPARM,
491 "mri_read(): bad frame ('%s')\n", pound));
492 }
493 }
494
495 if(start_frame < 0)
496 {
497 errno = 0;
498 ErrorReturn
499 (NULL,
500 (ERROR_BADPARM,
501 "mri_read(): frame (%d) is less than zero\n", start_frame));
502 }
503
504 if(end_frame < 0)
505 {
506 errno = 0;
507 ErrorReturn
508 (NULL,
509 (ERROR_BADPARM,
510 "mri_read(): frame (%d) is less than zero\n", end_frame));
511 }
512
513 if(start_frame > end_frame)
514 {
515 errno = 0;
516 ErrorReturn(NULL, (ERROR_BADPARM,
517 "mri_read(): the start frame (%d) is "
518 "greater than the end frame (%d)\n",
519 start_frame, end_frame));
520 }
521
522 }
523
524 if(type == MRI_CORONAL_SLICE_DIRECTORY)
525 {
526 mri = corRead(fname_copy, volume_flag);
527 }
528 else if(type == SIEMENS_FILE)
529 {
530 mri = siemensRead(fname_copy, volume_flag);
531 }
532 else if (type == MRI_GCA_FILE)
533 {
534 mri = readGCA(fname_copy) ;
535 }
536 else if(type == BHDR)
537 {
538 ptmpstr = bhdr_firstslicefname(fname_copy);
539 t = bhdr_precision(fname_copy);
540 mri = bvolumeRead(ptmpstr, volume_flag, t);
541 free(ptmpstr);
542 }
543 else if(type == BSHORT_FILE)
544 {
545 //mri = bshortRead(fname_copy, volume_flag);
546 mri = bvolumeRead(fname_copy, volume_flag, MRI_SHORT);
547 }
548 else if(type == BFLOAT_FILE)
549 {
550 //mri = bfloatRead(fname_copy, volume_flag);
551 mri = bvolumeRead(fname_copy, volume_flag, MRI_FLOAT);
552 }
553 else if(type == GENESIS_FILE)
554 {
555 mri = genesisRead(fname_copy, volume_flag);
556 }
557 else if(type == SIGNA_FILE)
558 {
559 mri = signaRead(fname_copy, volume_flag);
560 }
561 else if(type == GE_LX_FILE)
562 {
563 mri = gelxRead(fname_copy, volume_flag);
564 }
565 else if(type == MRI_ANALYZE_FILE || type == MRI_ANALYZE4D_FILE)
566 {
567 mri = analyzeRead(fname_copy, volume_flag);
568 }
569 else if(type == BRIK_FILE)
570 {
571 mri = afniRead(fname_copy, volume_flag);
572 }
573 else if(type == MRI_MINC_FILE)
574 {
575 //mri = mincRead2(fname_copy, volume_flag);
576 mri = mincRead(fname_copy, volume_flag);
577 }
578 else if(type == SDT_FILE)
579 {
580 mri = sdtRead(fname_copy, volume_flag);
581 }
582 else if(type == MRI_MGH_FILE)
583 {
584 mri = mghRead(fname_copy, volume_flag, -1);
585 }
586 else if(type == GDF_FILE)
587 {
588 mri = gdfRead(fname_copy, volume_flag);
589 }
590 else if(type == DICOM_FILE)
591 {
592 DICOMRead(fname_copy, &mri, volume_flag);
593 }
594 else if(type == SIEMENS_DICOM_FILE)
595 {
596 // mri_convert -nth option sets start_frame = nth. otherwise -1
597 mri = sdcmLoadVolume(fname_copy, volume_flag, start_frame);
598 start_frame = -1;
599 // in order to avoid the later processing on start_frame and end_frame
600 // read the comment later on
601 end_frame = 0;
602 }
603 else if (type == BRUKER_FILE)
604 {
605 mri = brukerRead(fname_copy, volume_flag);
606 }
607 else if(type == XIMG_FILE)
608 {
609 mri = ximgRead(fname_copy, volume_flag);
610 }
611 else if(type == NIFTI1_FILE)
612 {
613 mri = nifti1Read(fname_copy, volume_flag);
614 }
615 else if(type == NII_FILE)
616 mri = niiRead(fname_copy, volume_flag);
617 else if(type == MRI_CURV_FILE)
618 mri = MRISreadCurvAsMRI(fname_copy, volume_flag);
619 else if (type == IMAGE_FILE) {
620 I = ImageRead(fname_copy);
621 mri = ImageToMRI(I);
622 ImageFree(&I);
623 }
624 else
625 {
626 fprintf(stderr,"mri_read(): type = %d\n",type);
627 errno = 0;
628 ErrorReturn(NULL, (ERROR_BADPARM, "mri_read(): code inconsistency "
629 "(file type recognized but not caught)"));
630 }
631
632 if (mri == NULL) return(NULL) ;
633
634 // update/cache the transform
635 if (mri->i_to_r__)
636 MatrixFree(&(mri->i_to_r__));
637 mri->i_to_r__ = extract_i_to_r(mri);
638
639 if (mri->r_to_i__)
640 MatrixFree(&(mri->r_to_i__));
641 mri->r_to_i__ = extract_r_to_i(mri);
642
643 /* Compute the FOV from the vox2ras matrix (don't rely on what
644 may or may not be in the file).*/
645
646 if(start_frame == -1) return(mri);
647
648 /* --- select frames --- */
649
650 if(start_frame >= mri->nframes)
651 {
652 volume_frames = mri->nframes;
653 MRIfree(&mri);
654 errno = 0;
655 ErrorReturn
656 (NULL,
657 (ERROR_BADPARM,
658 "mri_read(): start frame (%d) is "
659 "out of range (%d frames in volume)",
660 start_frame, volume_frames));
661 }
662
663 if(end_frame >= mri->nframes)
664 {
665 volume_frames = mri->nframes;
666 MRIfree(&mri);
667 errno = 0;
668 ErrorReturn
669 (NULL,
670 (ERROR_BADPARM,
671 "mri_read(): end frame (%d) is out of range (%d frames in volume)",
672 end_frame, volume_frames));
673 }
674
675 if(!volume_flag)
676 {
677
678 if(nan_inf_check(mri) != NO_ERROR)
679 {
680 MRIfree(&mri);
681 return(NULL);
682 }
683 mri2 = MRIcopy(mri, NULL);
684 MRIfree(&mri);
685 mri2->nframes = (end_frame - start_frame + 1);
686 return(mri2);
687
688 }
689
690 if(start_frame == 0 && end_frame == mri->nframes-1)
691 {
692 if(nan_inf_check(mri) != NO_ERROR)
693 {
694 MRIfree(&mri);
695 return(NULL);
696 }
697 return(mri);
698 }
699
700 /* reading the whole volume and then copying only
701 some frames is a bit inelegant,
702 but it's easier for now
703 to do this than to insert the appropriate
704 code into the read function for each format... */
705 /////////////////////////////////////////////////////////////////
706 // This method does not work, because
707 // 1. each frame has different acq parameters
708 // 2. when making frames, it takes the info only from the first frame
709 // Thus taking a frame out must be done at each frame extraction
710 ////////////////////////////////////////////////////////////////////
711 mri2 = MRIallocSequence(mri->width,
712 mri->height,
713 mri->depth,
714 mri->type,
715 (end_frame - start_frame + 1));
716 MRIcopyHeader(mri, mri2);
717 mri2->nframes = (end_frame - start_frame + 1);
718 mri2->imnr0 = 1;
719 mri2->imnr0 = mri2->nframes;
720
721 if(mri2->type == MRI_UCHAR)
722 for(t = 0;t < mri2->nframes;t++)
723 for(i = 0;i < mri2->width;i++)
724 for(j = 0;j < mri2->height;j++)
725 for(k = 0;k < mri2->depth;k++)
726 MRIseq_vox(mri2, i, j, k, t) =
727 MRIseq_vox(mri, i, j, k, t + start_frame);
728
729 if(mri2->type == MRI_SHORT)
730 for(t = 0;t < mri2->nframes;t++)
731 for(i = 0;i < mri2->width;i++)
732 for(j = 0;j < mri2->height;j++)
733 for(k = 0;k < mri2->depth;k++)
734 MRISseq_vox(mri2, i, j, k, t) =
735 MRISseq_vox(mri, i, j, k, t + start_frame);
736
737 if(mri2->type == MRI_INT)
738 for(t = 0;t < mri2->nframes;t++)
739 for(i = 0;i < mri2->width;i++)
740 for(j = 0;j < mri2->height;j++)
741 for(k = 0;k < mri2->depth;k++)
742 MRIIseq_vox(mri2, i, j, k, t) =
743 MRIIseq_vox(mri, i, j, k, t + start_frame);
744
745 if(mri2->type == MRI_LONG)
746 for(t = 0;t < mri2->nframes;t++)
747 for(i = 0;i < mri2->width;i++)
748 for(j = 0;j < mri2->height;j++)
749 for(k = 0;k < mri2->depth;k++)
750 MRILseq_vox(mri2, i, j, k, t) =
751 MRILseq_vox(mri, i, j, k, t + start_frame);
752
753 if(mri2->type == MRI_FLOAT)
754 for(t = 0;t < mri2->nframes;t++)
755 for(i = 0;i < mri2->width;i++)
756 for(j = 0;j < mri2->height;j++)
757 for(k = 0;k < mri2->depth;k++)
758 MRIFseq_vox(mri2, i, j, k, t) =
759 MRIFseq_vox(mri, i, j, k, t + start_frame);
760
761 if(nan_inf_check(mri) != NO_ERROR)
762 {
763 MRIfree(&mri);
764 return(NULL);
765 }
766
767 MRIfree(&mri);
768
769 return(mri2);
770
771 } /* end mri_read() */
772
773 static int nan_inf_check(MRI *mri)
774 {
775
776 int i, j, k, t;
777
778 if(mri->type != MRI_FLOAT)
779 return(NO_ERROR);
780
781 for(i = 0;i < mri->width;i++)
782 for(j = 0;j < mri->height;j++)
783 for(k = 0;k < mri->depth;k++)
784 for(t = 0;t < mri->nframes;t++)
785 if(!devFinite((MRIFseq_vox(mri, i, j, k, t))))
786 {
787 if(devIsinf((MRIFseq_vox(mri, i, j, k, t))) != 0)
788 {
789 errno = 0;
790 ErrorReturn
791 (ERROR_BADPARM,
792 (ERROR_BADPARM,
793 "nan_inf_check(): Inf at voxel %d, %d, %d, %d",
794 i, j, k, t));
795 }
796 else if(devIsnan((MRIFseq_vox(mri, i, j, k, t))))
797 {
798 errno = 0;
799 ErrorReturn
800 (ERROR_BADPARM,
801 (ERROR_BADPARM,
802 "nan_inf_check(): NaN at voxel %d, %d, %d, %d",
803 i, j, k, t));
804 }
805 else
806 {
807 errno = 0;
808 ErrorReturn
809 (ERROR_BADPARM,
810 (ERROR_BADPARM,
811 "nan_inf_check(): bizarre value (not Inf, "
812 "not NaN, but not finite) at %d, %d, %d, %d",
813 i, j, k, t));
814 }
815 }
816
817 return(NO_ERROR);
818
819 } /* end nan_inf_check() */
820
821 MRI *MRIreadType(char *fname, int type)
822 {
823
824 MRI *mri;
825
826 chklc();
827
828 mri = mri_read(fname, type, TRUE, -1, -1);
829
830 return(mri);
831
832 } /* end MRIreadType() */
833
834 MRI *MRIread(char *fname)
835 {
836 char buf[STRLEN] ;
837 MRI *mri = NULL;
838
839 chklc() ;
840
841 FileNameFromWildcard(fname, buf) ; fname = buf ;
842 mri = mri_read(fname, MRI_VOLUME_TYPE_UNKNOWN, TRUE, -1, -1);
843
844 /* some volume format needs to read many
845 different files for slices (GE DICOM or COR).
846 we make sure that mri_read() read the slices, not just one */
847 if (mri==NULL)
848 return NULL;
849
850 MRIremoveNaNs(mri, mri) ;
851 return(mri);
852
853 } /* end MRIread() */
854
855 // allow picking one frame out of many frame
856 // currently implemented only for Siemens dicom file
857 MRI *MRIreadEx(char *fname, int nthframe)
858 {
859 char buf[STRLEN] ;
860 MRI *mri = NULL;
861
862 chklc() ;
863
864 FileNameFromWildcard(fname, buf) ; fname = buf ;
865 mri = mri_read(fname, MRI_VOLUME_TYPE_UNKNOWN, TRUE, nthframe, nthframe);
866
867 /* some volume format needs to read many
868 different files for slices (GE DICOM or COR).
869 we make sure that mri_read() read the slices, not just one */
870 if (mri==NULL)
871 return NULL;
872
873 MRIremoveNaNs(mri, mri) ;
874 return(mri);
875
876 } /* end MRIread() */
877
878 MRI *MRIreadInfo(char *fname)
879 {
880
881 MRI *mri = NULL;
882
883 mri = mri_read(fname, MRI_VOLUME_TYPE_UNKNOWN, FALSE, -1, -1);
884
885 return(mri);
886
887 } /* end MRIreadInfo() */
888
889 /*---------------------------------------------------------------
890 MRIreadHeader() - reads the MRI header of the given file name.
891 If type is MRI_VOLUME_TYPE_UNKNOWN, then the type will be
892 inferred from the file name.
893 ---------------------------------------------------------------*/
894 MRI *MRIreadHeader(char *fname, int type)
895 {
896 int usetype;
897 MRI *mri = NULL;
898 char modFname[STRLEN];
899 struct stat stat_buf;
900
901 usetype = type;
902
903 if (!strchr(fname,DIR_SEPARATOR))
904 {
905 char *cwd = getcwd(NULL, 0); // posix 1 extension
906 // (allocate as much space needed)
907 if (cwd)
908 {
909 strcpy(modFname, cwd);
910 strcat(modFname, "/");
911 strcat(modFname, fname);
912 free(cwd);
913 }
914 else // why fail?
915 strcpy(modFname, fname);
916 }
917 else
918 strcpy(modFname, fname);
919
920 if(usetype == MRI_VOLUME_TYPE_UNKNOWN){
921 usetype = mri_identify(modFname);
922 if(usetype == MRI_VOLUME_TYPE_UNKNOWN)
923 {
924 // just check again
925 if (stat(fname, &stat_buf) < 0)
926 printf("ERROR: cound not find volume %s. Does it exist?\n", fname);
927 else
928 printf("ERROR: could not determine type of %s\n",fname);
929 return(NULL);
930 }
931 }
932 mri = mri_read(modFname, usetype, FALSE, -1, -1);
933
934 return(mri);
935
936 } /* end MRIreadInfo() */
937
938 int MRIwriteType(MRI *mri, char *fname, int type)
939 {
940 struct stat stat_buf;
941 int error=0;
942 char *fstem;
943 char tmpstr[STRLEN];
944
945 if(type == MRI_CORONAL_SLICE_DIRECTORY)
946 {
947 error = corWrite(mri, fname);
948 }
949 else
950 {
951 /* ----- all remaining types should write to
952 a filename, not to within a directory,
953 so check that it isn't an existing directory name we've been passed.
954 failure to check will result in a segfault
955 when attempting to write file data
956 to a 'file' that is actually an existing directory ----- */
957 if(stat(fname, &stat_buf) == 0){ // if can stat, then fname exists
958 if(S_ISDIR(stat_buf.st_mode)){ // if is directory...
959 errno = 0;
960 ErrorReturn
961 (ERROR_BADFILE,
962 (ERROR_BADFILE,
963 "MRIwriteType(): %s is an existing directory. (type=%d)\n"
964 " A filename should be specified instead.",
965 fname, type));
966 }
967 }
968 }
969
970 /* ----- continue file writing... ----- */
971
972 if(type == MRI_MINC_FILE)
973 {
974 error = mincWrite(mri, fname);
975 }
976 else if(type == BHDR)
977 {
978 fstem = bhdr_stem(fname);
979 if(mri->type == MRI_SHORT){
980 sprintf(tmpstr,"%s_000.bshort",fstem);
981 error = bvolumeWrite(mri, tmpstr, MRI_SHORT);
982 }
983 else{
984 sprintf(tmpstr,"%s_000.bfloat",fstem);
985 error = bvolumeWrite(mri, tmpstr, MRI_FLOAT);
986 }
987 free(fstem);
988 }
989 else if(type == BSHORT_FILE)
990 {
991 error = bvolumeWrite(mri, fname, MRI_SHORT);
992 }
993 else if(type == BFLOAT_FILE)
994 {
995 error = bvolumeWrite(mri, fname, MRI_FLOAT);
996 }
997 else if(type == MRI_ANALYZE_FILE)
998 {
999 error = analyzeWrite(mri, fname);
1000 }
1001 else if(type == MRI_ANALYZE4D_FILE)
1002 {
1003 error = analyzeWrite4D(mri, fname);
1004 }
1005 else if(type == BRIK_FILE)
1006 {
1007 error = afniWrite(mri, fname);
1008 }
1009 else if(type == MRI_MGH_FILE)
1010 {
1011 error = mghWrite(mri, fname, -1);
1012 }
1013 else if(type == GDF_FILE)
1014 {
1015 error = gdfWrite(mri, fname);
1016 }
1017 else if(type == NIFTI1_FILE)
1018 {
1019 error = nifti1Write(mri, fname);
1020 }
1021 else if(type == NII_FILE) error = niiWrite(mri, fname);
1022 else if(type == GENESIS_FILE)
1023 {
1024 errno = 0;
1025 ErrorReturn
1026 (ERROR_BADPARM,
1027 (ERROR_BADPARM,
1028 "MRIwriteType(): writing of GENESIS file type not supported"));
1029 }
1030 else if(type == GE_LX_FILE)
1031 {
1032 errno = 0;
1033 ErrorReturn
1034 (ERROR_BADPARM,
1035 (ERROR_BADPARM,
1036 "MRIwriteType(): writing of GE LX file type not supported"));
1037 }
1038 else if(type == SIEMENS_FILE)
1039 {
1040 errno = 0;
1041 ErrorReturn
1042 (ERROR_BADPARM,
1043 (ERROR_BADPARM,
1044 "MRIwriteType(): writing of SIEMENS file type not supported"));
1045 }
1046 else if(type == SDT_FILE)
1047 {
1048 errno = 0;
1049 ErrorReturn
1050 (ERROR_BADPARM,
1051 (ERROR_BADPARM,
1052 "MRIwriteType(): writing of SDT file type not supported"));
1053 }
1054 else if(type == OTL_FILE)
1055 {
1056 errno = 0;
1057 ErrorReturn
1058 (ERROR_BADPARM,
1059 (ERROR_BADPARM,
1060 "MRIwriteType(): writing of OTL file type not supported"));
1061 }
1062 else if(type == RAW_FILE)
1063 {
1064 errno = 0;
1065 ErrorReturn
1066 (ERROR_BADPARM,
1067 (ERROR_BADPARM,
1068 "MRIwriteType(): writing of RAW file type not supported"));
1069 }
1070 else if(type == SIGNA_FILE)
1071 {
1072 errno = 0;
1073 ErrorReturn
1074 (ERROR_BADPARM,
1075 (ERROR_BADPARM,
1076 "MRIwriteType(): writing of SIGNA file type not supported"));
1077 }
1078 else if(type == DICOM_FILE)
1079 {
1080 errno = 0;
1081 ErrorReturn
1082 (ERROR_BADPARM,
1083 (ERROR_BADPARM,
1084 "MRIwriteType(): writing of DICOM file type not supported"));
1085 }
1086 else if(type == SIEMENS_DICOM_FILE)
1087 {
1088 errno = 0;
1089 ErrorReturn
1090 (ERROR_BADPARM,
1091 (ERROR_BADPARM,
1092 "MRIwriteType(): writing of SIEMENS DICOM file type not supported"));
1093 }
1094 else if(type == BRUKER_FILE)
1095 {
1096 errno = 0;
1097 ErrorReturn
1098 (ERROR_BADPARM,
1099 (ERROR_BADPARM,
1100 "MRIwriteType(): writing of BRUKER file type not supported"));
1101 }
1102 else if(type == XIMG_FILE)
1103 {
1104 errno = 0;
1105 ErrorReturn
1106 (ERROR_BADPARM,
1107 (ERROR_BADPARM,
1108 "MRIwriteType(): writing of XIMG file type not supported"));
1109 }
1110 else if(type == MRI_CORONAL_SLICE_DIRECTORY)
1111 {
1112 // already processed above
1113 }
1114 else
1115 {
1116 errno = 0;
1117 ErrorReturn(ERROR_BADPARM,
1118 (ERROR_BADPARM,
1119 "MRIwriteType(): code inconsistency "
1120 "(file type recognized but not caught)"));
1121 }
1122
1123 return(error);
1124
1125 } /* end MRIwriteType() */
1126
1127 int
1128 MRIwriteFrame(MRI *mri, char *fname, int frame)
1129 {
1130 MRI *mri_tmp ;
1131
1132 mri_tmp = MRIcopyFrame(mri, NULL, frame, 0) ;
1133 MRIwrite(mri_tmp, fname) ;
1134 MRIfree(&mri_tmp) ;
1135 return(NO_ERROR) ;
1136 }
1137
1138 int MRIwrite(MRI *mri, char *fname)
1139 {
1140
1141 int int_type = -1;
1142 int error;
1143
1144 chklc() ;
1145 if((int_type = mri_identify(fname)) < 0)
1146 {
1147 errno = 0;
1148 ErrorReturn
1149 (ERROR_BADPARM,
1150 (ERROR_BADPARM, "unknown file type for file (%s)", fname));
1151 }
1152
1153 error = MRIwriteType(mri, fname, int_type);
1154
1155 return(error);
1156
1157 } /* end MRIwrite() */
1158
1159
1160 /* ----- required header fields ----- */
1161
1162 #define COR_ALL_REQUIRED 0x00001fff
1163
1164 #define IMNR0_FLAG 0x00000001
1165 #define IMNR1_FLAG 0x00000002
1166 #define PTYPE_FLAG 0x00000004
1167 #define X_FLAG 0x00000008
1168 #define Y_FLAG 0x00000010
1169 #define THICK_FLAG 0x00000020
1170 #define PSIZ_FLAG 0x00000040
1171 #define STRTX_FLAG 0x00000080
1172 #define ENDX_FLAG 0x00000100
1173 #define STRTY_FLAG 0x00000200
1174 #define ENDY_FLAG 0x00000400
1175 #define STRTZ_FLAG 0x00000800
1176 #define ENDZ_FLAG 0x00001000
1177
1178 /* trivially time course clean */
1179 static MRI *corRead(char *fname, int read_volume)
1180 {
1181
1182 MRI *mri;
1183 struct stat stat_buf;
1184 char fname_use[STRLEN];
1185 char *fbase;
1186 FILE *fp;
1187 int i, j;
1188 char line[STRLEN];
1189 int imnr0, imnr1, x, y, ptype;
1190 double fov, thick, psiz, locatn; /* using floats to read creates problems
1191 when checking values
1192 (e.g. thick = 0.00100000005) */
1193 float strtx, endx, strty, endy, strtz, endz;
1194 float tr, te, ti, flip_angle ;
1195 int ras_good_flag;
1196 float x_r, x_a, x_s;
1197 float y_r, y_a, y_s;
1198 float z_r, z_a, z_s;
1199 float c_r, c_a, c_s;
1200 char xform[STRLEN];
1201 long gotten;
1202 char xform_use[STRLEN];
1203 char *cur_char;
1204 char *last_slash;
1205
1206 /* ----- check that it is a directory we've been passed ----- */
1207 strcpy(fname_use, fname);
1208 if(stat(fname_use, &stat_buf) < 0)
1209 {
1210 errno = 0;
1211 ErrorReturn(NULL,
1212 (ERROR_BADFILE, "corRead(): can't stat %s", fname_use));
1213 }
1214
1215 if(!S_ISDIR(stat_buf.st_mode))
1216 {
1217 /* remove the last bit and try again */
1218 cur_char = fname_use;
1219 last_slash = cur_char;
1220 while( *(cur_char+1) != '\0' )
1221 {
1222 if(*cur_char == '/')
1223 last_slash = cur_char;
1224 cur_char++;
1225 }
1226 *last_slash = '\0';
1227 if(stat(fname_use, &stat_buf) < 0)
1228 {
1229 errno = 0;
1230 ErrorReturn
1231 (NULL,
1232 (ERROR_BADFILE, "corRead(): can't stat %s", fname_use));
1233 }
1234 if(!S_ISDIR(stat_buf.st_mode))
1235 {
1236 errno = 0;
1237 ErrorReturn
1238 (NULL,
1239 (ERROR_BADFILE, "corRead(): %s isn't a directory", fname_use));
1240 }
1241 }
1242
1243 /* ----- copy the directory name and remove any trailing '/' ----- */
1244 fbase = &fname_use[strlen(fname_use)];
1245 if(*(fbase-1) != '/')
1246 {
1247 *fbase = '/';
1248 fbase++;
1249 }
1250
1251 /* ----- read the header file ----- */
1252 sprintf(fbase, "COR-.info");
1253 if((fp = fopen(fname_use, "r")) == NULL)
1254 {
1255 errno = 0;
1256 ErrorReturn
1257 (NULL, (ERROR_BADFILE, "corRead(): can't open file %s", fname_use));
1258 }
1259
1260 /* ----- defaults (a good idea for non-required values...) ----- */
1261 xform[0] = '\0';
1262 ras_good_flag = 0;
1263 x_r = x_a = x_s = 0.0;
1264 y_r = y_a = y_s = 0.0;
1265 z_r = z_a = z_s = 0.0;
1266 c_r = c_a = c_s = 0.0;
1267 flip_angle = tr = te = ti = 0.0;
1268 fov = 0.0;
1269 locatn = 0.0;
1270
1271 gotten = 0x00;
1272
1273 while(fgets(line, STRLEN, fp) != NULL)
1274 {
1275 if(strncmp(line, "imnr0 ", 6) == 0)
1276 {
1277 sscanf(line, "%*s %d", &imnr0);
1278 gotten = gotten | IMNR0_FLAG;
1279 }
1280 else if(strncmp(line, "imnr1 ", 6) == 0)
1281 {
1282 sscanf(line, "%*s %d", &imnr1);
1283 gotten = gotten | IMNR1_FLAG;
1284 }
1285 else if(strncmp(line, "ptype ", 6) == 0)
1286 {
1287 sscanf(line, "%*s %d", &ptype);
1288 gotten = gotten | PTYPE_FLAG;
1289 }
1290 else if(strncmp(line, "x ", 2) == 0)
1291 {
1292 sscanf(line, "%*s %d", &x);
1293 gotten = gotten | X_FLAG;
1294 }
1295 else if(strncmp(line, "y ", 2) == 0)
1296 {
1297 sscanf(line, "%*s %d", &y);
1298 gotten = gotten | Y_FLAG;
1299 }
1300 else if(strncmp(line, "fov ", 4) == 0)
1301 {
1302 sscanf(line, "%*s %lf", &fov);
1303 }
1304 else if(strncmp(line, "thick ", 6) == 0)
1305 {
1306 sscanf(line, "%*s %lf", &thick);
1307 gotten = gotten | THICK_FLAG;
1308 }
1309 else if(strncmp(line, "flip ", 5) == 0)
1310 {
1311 sscanf(line+11, "%f", &flip_angle);
1312 flip_angle = RADIANS(flip_angle) ;
1313 }
1314 else if(strncmp(line, "psiz ", 5) == 0)
1315 {
1316 sscanf(line, "%*s %lf", &psiz);
1317 gotten = gotten | PSIZ_FLAG;
1318 }
1319 else if(strncmp(line, "locatn ", 7) == 0)
1320 {
1321 sscanf(line, "%*s %lf", &locatn);
1322 }
1323 else if(strncmp(line, "strtx ", 6) == 0)
1324 {
1325 sscanf(line, "%*s %f", &strtx);
1326 gotten = gotten | STRTX_FLAG;
1327 }
1328 else if(strncmp(line, "endx ", 5) == 0)
1329 {
1330 sscanf(line, "%*s %f", &endx);
1331 gotten = gotten | ENDX_FLAG;
1332 }
1333 else if(strncmp(line, "strty ", 6) == 0)
1334 {
1335 sscanf(line, "%*s %f", &strty);
1336 gotten = gotten | STRTY_FLAG;
1337 }
1338 else if(strncmp(line, "endy ", 5) == 0)
1339 {
1340 sscanf(line, "%*s %f", &endy);
1341 gotten = gotten | ENDY_FLAG;
1342 }
1343 else if(strncmp(line, "strtz ", 6) == 0)
1344 {
1345 sscanf(line, "%*s %f", &strtz);
1346 gotten = gotten | STRTZ_FLAG;
1347 }
1348 else if(strncmp(line, "endz ", 5) == 0)
1349 {
1350 sscanf(line, "%*s %f", &endz);
1351 gotten = gotten | ENDZ_FLAG;
1352 }
1353 else if(strncmp(line, "tr ", 3) == 0)
1354 {
1355 sscanf(line, "%*s %f", &tr);
1356 }
1357 else if(strncmp(line, "te ", 3) == 0)
1358 {
1359 sscanf(line, "%*s %f", &te);
1360 }
1361 else if(strncmp(line, "ti ", 3) == 0)
1362 {
1363 sscanf(line, "%*s %f", &ti);
1364 }
1365 else if(strncmp(line, "ras_good_flag ", 14) == 0)
1366 {
1367 sscanf(line, "%*s %d", &ras_good_flag);
1368 }
1369 else if(strncmp(line, "x_ras ", 6) == 0)
1370 {
1371 sscanf(line, "%*s %f %f %f", &x_r, &x_a, &x_s);
1372 }
1373 else if(strncmp(line, "y_ras ", 6) == 0)
1374 {
1375 sscanf(line, "%*s %f %f %f", &y_r, &y_a, &y_s);
1376 }
1377 else if(strncmp(line, "z_ras ", 6) == 0)
1378 {
1379 sscanf(line, "%*s %f %f %f", &z_r, &z_a, &z_s);
1380 }
1381 else if(strncmp(line, "c_ras ", 6) == 0)
1382 {
1383 sscanf(line, "%*s %f %f %f", &c_r, &c_a, &c_s);
1384 }
1385 else if(strncmp(line, "xform", 5) == 0 ||
1386 strncmp(line, "transform", 9) == 0)
1387 {
1388 sscanf(line, "%*s %s", xform);
1389 }
1390 }
1391
1392 fclose(fp);
1393
1394 /* ----- check for required fields ----- */
1395 if((gotten & COR_ALL_REQUIRED) != COR_ALL_REQUIRED)
1396 {
1397 errno = 0;
1398 ErrorPrintf(ERROR_BADFILE, "missing fields in file %s:", fname_use);
1399 if(!(gotten & IMNR0_FLAG))
1400 ErrorPrintf(ERROR_BADFILE, " imnr0 field missing");
1401 if(!(gotten & IMNR1_FLAG))
1402 ErrorPrintf(ERROR_BADFILE, " imnr1 field missing");
1403 if(!(gotten & PTYPE_FLAG))
1404 ErrorPrintf(ERROR_BADFILE, " ptype field missing");
1405 if(!(gotten & X_FLAG))
1406 ErrorPrintf(ERROR_BADFILE, " x field missing");
1407 if(!(gotten & Y_FLAG))
1408 ErrorPrintf(ERROR_BADFILE, " y field missing");
1409 if(!(gotten & THICK_FLAG))
1410 ErrorPrintf(ERROR_BADFILE, " thick field missing");
1411 if(!(gotten & PSIZ_FLAG))
1412 ErrorPrintf(ERROR_BADFILE, " psiz field missing");
1413 if(!(gotten & STRTX_FLAG))
1414 ErrorPrintf(ERROR_BADFILE, " strtx field missing");
1415 if(!(gotten & ENDX_FLAG))
1416 ErrorPrintf(ERROR_BADFILE, " endx field missing");
1417 if(!(gotten & STRTY_FLAG))
1418 ErrorPrintf(ERROR_BADFILE, " strty field missing");
1419 if(!(gotten & ENDY_FLAG))
1420 ErrorPrintf(ERROR_BADFILE, " endy field missing");
1421 if(!(gotten & STRTZ_FLAG))
1422 ErrorPrintf(ERROR_BADFILE, " strtz field missing");
1423 if(!(gotten & ENDZ_FLAG))
1424 ErrorPrintf(ERROR_BADFILE, " endz field missing");
1425 return(NULL);
1426 }
1427
1428 /* ----- check for required but forced (constant) values ----- */
1429
1430 if(imnr0 != 1)
1431 {
1432 printf
1433 ("warning: non-standard value for imnr0 "
1434 "(%d, usually 1) in file %s\n",
1435 imnr0, fname_use);
1436 }
1437
1438 if(imnr1 != 256)
1439 {
1440 printf
1441 ("warning: non-standard value for imnr1 "
1442 "(%d, usually 256) in file %s\n",
1443 imnr1, fname_use);
1444 }
1445
1446 if(ptype != 2)
1447 {
1448 printf("warning: non-standard value for ptype "
1449 "(%d, usually 2) in file %s\n",
1450 ptype, fname_use);
1451 }
1452
1453 if(x != 256)
1454 {
1455 printf("warning: non-standard value for x "
1456 "(%d, usually 256) in file %s\n",
1457 x, fname_use);
1458 }
1459
1460 if(y != 256)
1461 {
1462 printf("warning: non-standard value for y "
1463 "(%d, usually 256) in file %s\n",
1464 y, fname_use);
1465 }
1466
1467 if(thick != 0.001)
1468 {
1469 printf("warning: non-standard value for thick "
1470 "(%g, usually 0.001) in file %s\n",
1471 thick, fname_use);
1472 }
1473
1474 if(psiz != 0.001)
1475 {
1476 printf("warning: non-standard value for psiz "
1477 "(%g, usually 0.001) in file %s\n",
1478 psiz, fname_use);
1479 }
1480
1481 /* ----- copy header information to an mri structure ----- */
1482
1483 if(read_volume)
1484 mri = MRIalloc(x, y, imnr1 - imnr0 + 1, MRI_UCHAR);
1485 else
1486 mri = MRIallocHeader(x, y, imnr1 - imnr0 + 1, MRI_UCHAR);
1487
1488 /* hack */
1489 /*
1490 printf("%g, %g, %g\n", x_r, x_a, x_s);
1491 printf("%g, %g, %g\n", y_r, y_a, y_s);
1492 printf("%g, %g, %g\n", z_r, z_a, z_s);
1493 */
1494 if(x_r == 0.0 && x_a == 0.0 && x_s == 0.0 && y_r == 0.0 \
1495 && y_a == 0.0 && y_s == 0.0 && z_r == 0.0 && z_a == 0.0 && z_s == 0.0)
1496 {
1497 fprintf(stderr,
1498 "----------------------------------------------------\n"
1499 "Could not find the direction cosine information.\n"
1500 "Will use the CORONAL orientation.\n"
1501 "If not suitable, please provide the information "
1502 "in COR-.info file\n"
1503 "----------------------------------------------------\n"
1504 );
1505 x_r = -1.0;
1506 y_s = -1.0;
1507 z_a = 1.0;
1508 ras_good_flag = 0;
1509 }
1510
1511 mri->imnr0 = imnr0;
1512 mri->imnr1 = imnr1;
1513 mri->fov = (float)(fov * 1000);
1514 mri->thick = (float)(thick * 1000);
1515 mri->ps = (float)(psiz * 1000);
1516 mri->xsize = mri->ps;
1517 mri->ysize = mri->ps;
1518 mri->zsize = (float)(mri->thick);
1519 mri->xstart = strtx * 1000;
1520 mri->xend = endx * 1000;
1521 mri->ystart = strty * 1000;
1522 mri->yend = endy * 1000;
1523 mri->zstart = strtz * 1000;
1524 mri->zend = endz * 1000;
1525 strcpy(mri->fname, fname);
1526 mri->tr = tr;
1527 mri->te = te;
1528 mri->ti = ti;
1529 mri->flip_angle = flip_angle ;
1530 mri->ras_good_flag = ras_good_flag;
1531 mri->x_r = x_r; mri->x_a = x_a; mri->x_s = x_s;
1532 mri->y_r = y_r; mri->y_a = y_a; mri->y_s = y_s;
1533 mri->z_r = z_r; mri->z_a = z_a; mri->z_s = z_s;
1534 mri->c_r = c_r; mri->c_a = c_a; mri->c_s = c_s;
1535
1536 if(strlen(xform) > 0)
1537 {
1538
1539 if(xform[0] == '/')
1540 strcpy(mri->transform_fname, xform);
1541 else
1542 sprintf(mri->transform_fname, "%s/%s", fname, xform);
1543
1544 strcpy(xform_use, mri->transform_fname);
1545
1546 if(!FileExists(xform_use))
1547 {
1548
1549 sprintf(xform_use, "%s/../transforms/talairach.xfm", fname);
1550
1551 if(!FileExists(xform_use))
1552 printf("can't find talairach file '%s'\n", xform_use);
1553
1554 }
1555
1556 if(FileExists(xform_use))
1557 {
1558 if(input_transform_file(xform_use, &(mri->transform)) == NO_ERROR)
1559 {
1560 mri->linear_transform =
1561 get_linear_transform_ptr(&mri->transform);
1562 mri->inverse_linear_transform =
1563 get_inverse_linear_transform_ptr(&mri->transform);
1564 mri->free_transform = 1;
1565 strcpy(mri->transform_fname, xform_use);
1566 if (DIAG_VERBOSE_ON)
1567 fprintf
1568 (stderr,
1569 "INFO: loaded talairach xform : %s\n",
1570 mri->transform_fname);
1571 }
1572 else
1573 {
1574 errno = 0;
1575 ErrorPrintf
1576 (ERROR_BAD_FILE, "error loading transform from %s", xform_use);
1577 mri->linear_transform = NULL;
1578 mri->inverse_linear_transform = NULL;
1579 mri->free_transform = 1;
1580 (mri->transform_fname)[0] = '\0';
1581 }
1582 }
1583
1584 }
1585
1586 if(!read_volume)
1587 return(mri);
1588
1589 /* ----- read the data files ----- */
1590 for(i = mri->imnr0;i <= imnr1;i++)
1591 {
1592 sprintf(fbase, "COR-%03d", i);
1593 if((fp = fopen(fname_use, "r")) == NULL)
1594 {
1595 MRIfree(&mri);
1596 errno = 0;
1597 ErrorReturn
1598 (NULL,
1599 (ERROR_BADFILE, "corRead(): can't open file %s", fname_use));
1600 }
1601 for(j = 0;j < mri->height;j++)
1602 {
1603 if(fread(mri->slices[i-mri->imnr0][j], 1, mri->width, fp) <
1604 mri->width)
1605 {
1606 MRIfree(&mri);
1607 errno = 0;
1608 ErrorReturn
1609 (NULL,
1610 (ERROR_BADFILE,
1611 "corRead(): error reading from file %s", fname_use));
1612 }
1613 }
1614 fclose(fp);
1615 }
1616
1617 return(mri);
1618
1619 } /* end corRead() */
1620
1621 static int corWrite(MRI *mri, char *fname)
1622 {
1623
1624 struct stat stat_buf;
1625 char fname_use[STRLEN];
1626 char *fbase;
1627 FILE *fp;
1628 int i, j;
1629 int rv;
1630
1631 /* ----- check the mri structure for COR file compliance ----- */
1632
1633 if(mri->slices == NULL)
1634 {
1635 errno = 0;
1636 ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM,
1637 "corWrite(): mri structure to be "
1638 "written contains no voxel data"));
1639 }
1640
1641 if(mri->imnr0 != 1)
1642 {
1643 printf
1644 ("non-standard value for imnr0 (%d, usually 1) in volume structure\n",
1645 mri->imnr0);
1646 }
1647
1648 if(mri->imnr1 != 256)
1649 {
1650 printf
1651 ("non-standard value for imnr1 (%d, "
1652 "usually 256) in volume structure\n",
1653 mri->imnr1);
1654 }
1655
1656 if(mri->type != MRI_UCHAR)
1657 {
1658 printf("non-standard value for type "
1659 "(%d, usually %d) in volume structure\n",
1660 mri->type, MRI_UCHAR);
1661 }
1662
1663 if(mri->width != 256)
1664 {
1665 printf("non-standard value for width "
1666 "(%d, usually 256) in volume structure\n",
1667 mri->width);
1668 }
1669
1670 if(mri->height != 256)
1671 {
1672 printf("non-standard value for height "
1673 "(%d, usually 256) in volume structure\n",
1674 mri->height);
1675 }
1676
1677 if(mri->thick != 1)
1678 {
1679 printf("non-standard value for thick "
1680 "(%g, usually 1) in volume structure\n",
1681 mri->thick);
1682 }
1683
1684 if(mri->ps != 1){
1685 printf("non-standard value for ps "
1686 "(%g, usually 1) in volume structure\n",
1687 mri->ps);
1688 }
1689
1690 /* ----- copy the directory name and remove any trailing '/' ----- */
1691 strcpy(fname_use, fname);
1692 fbase = &fname_use[strlen(fname_use)];
1693 if(*(fbase-1) != '/')
1694 {
1695 *fbase = '/';
1696 fbase++;
1697 *fbase = '\0';
1698 }
1699
1700 /* Create the directory */
1701 rv = mkdir(fname_use,(mode_t)-1);
1702 if(rv != 0 && errno != EEXIST){
1703 printf("ERROR: creating directory %s\n",fname_use);
1704 perror(NULL);
1705 return(1);
1706 }
1707
1708 /* ----- check that it is a directory we've been passed ----- */
1709 if(stat(fname, &stat_buf) < 0){
1710 errno = 0;
1711 ErrorReturn
1712 (ERROR_BADFILE, (ERROR_BADFILE, "corWrite(): can't stat %s", fname));
1713 }
1714
1715 if(!S_ISDIR(stat_buf.st_mode)){
1716 errno = 0;
1717 ErrorReturn
1718 (ERROR_BADFILE,
1719 (ERROR_BADFILE, "corWrite(): %s isn't a directory", fname));
1720 }
1721
1722 sprintf(fbase, "COR-.info");
1723 if((fp = fopen(fname_use, "w")) == NULL)
1724 {
1725 errno = 0;
1726 ErrorReturn
1727 (ERROR_BADFILE,
1728 (ERROR_BADFILE,
1729 "corWrite(): can't open file %s for writing", fname_use));
1730 }
1731
1732 fprintf(fp, "imnr0 %d\n", mri->imnr0);
1733 fprintf(fp, "imnr1 %d\n", mri->imnr1);
1734 fprintf(fp, "ptype %d\n", 2);
1735 fprintf(fp, "x %d\n", mri->width);
1736 fprintf(fp, "y %d\n", mri->height);
1737 fprintf(fp, "fov %g\n", mri->fov / 1000.0);
1738 fprintf(fp, "thick %g\n", mri->zsize / 1000.0); /* was xsize 11/1/01 */
1739 fprintf(fp, "psiz %g\n", mri->xsize / 1000.0); /* was zsize 11/1/01 */
1740 fprintf(fp, "locatn %g\n", 0.0);
1741 fprintf(fp, "strtx %g\n", mri->xstart / 1000.0);
1742 fprintf(fp, "endx %g\n", mri->xend / 1000.0);
1743 fprintf(fp, "strty %g\n", mri->ystart / 1000.0);
1744 fprintf(fp, "endy %g\n", mri->yend / 1000.0);
1745 fprintf(fp, "strtz %g\n", mri->zstart / 1000.0);
1746 fprintf(fp, "endz %g\n", mri->zend / 1000.0);
1747 fprintf(fp, "tr %f\n", mri->tr);
1748 fprintf(fp, "te %f\n", mri->te);
1749 fprintf(fp, "ti %f\n", mri->ti);
1750 fprintf(fp, "flip angle %f\n", DEGREES(mri->flip_angle));
1751 fprintf(fp, "ras_good_flag %d\n", mri->ras_good_flag);
1752 fprintf(fp, "x_ras %f %f %f\n", mri->x_r, mri->x_a, mri->x_s);
1753 fprintf(fp, "y_ras %f %f %f\n", mri->y_r, mri->y_a, mri->y_s);
1754 fprintf(fp, "z_ras %f %f %f\n", mri->z_r, mri->z_a, mri->z_s);
1755 fprintf(fp, "c_ras %f %f %f\n", mri->c_r, mri->c_a, mri->c_s);
1756 if(strlen(mri->transform_fname) > 0)
1757 fprintf(fp, "xform %s\n", mri->transform_fname);
1758
1759 fclose(fp);
1760
1761 for(i = mri->imnr0;i <= mri->imnr1;i++)
1762 {
1763 sprintf(fbase, "COR-%03d", i);
1764 if((fp = fopen(fname_use, "w")) == NULL)
1765 {
1766 errno = 0;
1767 ErrorReturn
1768 (ERROR_BADFILE,
1769 (ERROR_BADFILE,
1770 "corWrite(): can't open file %s for writing", fname_use));
1771 }
1772 for(j = 0;j < mri->height;j++)
1773 {
1774 if(fwrite(mri->slices[i-mri->imnr0][j], 1, mri->width, fp) <
1775 mri->width)
1776 {
1777 fclose(fp);
1778 errno = 0;
1779 ErrorReturn
1780 (ERROR_BADFILE,
1781 (ERROR_BADFILE,
1782 "corWrite(): error writing to file %s ", fname_use));
1783 }
1784 }
1785 fclose(fp);
1786 }
1787
1788 return(NO_ERROR);
1789
1790 } /* end corWrite() */
1791
1792 static MRI *siemensRead(char *fname, int read_volume_flag)
1793 {
1794
1795 int file_n, n_low, n_high;
1796 char fname_use[STRLEN];
1797 MRI *mri;
1798 FILE *fp;
1799 char *c, *c2;
1800 short rows, cols;
1801 int n_slices;
1802 double d, d2;
1803 double im_c_r, im_c_a, im_c_s;
1804 int i, j;
1805 int n_files, base_raw_matrix_size, number_of_averages;
1806 int mosaic_size;
1807 int mosaic;
1808 int mos_r, mos_c;
1809 char pulse_sequence_name[STRLEN], ps2[STRLEN];
1810 int n_t;
1811 int n_dangling_images, n_full_mosaics, mosaics_per_volume;
1812 int br, bc;
1813 MRI *mri_raw;
1814 int t, s;
1815 int slice_in_mosaic;
1816 int file;
1817 char ima[4];
1818 IMAFILEINFO *ifi;
1819
1820 /* ----- stop compiler complaints ----- */
1821 mri = NULL;
1822 mosaic_size = 0;
1823
1824
1825 ifi = imaLoadFileInfo(fname);
1826 if(ifi == NULL){
1827 printf("ERROR: siemensRead(): %s\n",fname);
1828 return(NULL);
1829 }
1830
1831 strcpy(fname_use, fname);
1832
1833 /* ----- point to ".ima" ----- */
1834 c = fname_use + (strlen(fname_use) - 4);
1835
1836 if(c < fname_use)
1837 {
1838 errno = 0;
1839 ErrorReturn
1840 (NULL,
1841 (ERROR_BADPARM,
1842 "siemensRead(): bad file name %s (must end in '.ima' or '.IMA')",
1843 fname_use));
1844 }
1845 if(strcmp(".ima", c) == 0)
1846 sprintf(ima, "ima");
1847 else if(strcmp(".IMA", c) == 0)
1848 sprintf(ima, "IMA");
1849 else
1850 {
1851 errno = 0;
1852 ErrorReturn
1853 (NULL,
1854 (ERROR_BADPARM,
1855 "siemensRead(): bad file name %s (must end in '.ima' or '.IMA')",
1856 fname_use));
1857 }
1858
1859 c2 = c;
1860 for(c--;isdigit((int)(*c));c--);
1861 c++;
1862
1863 /* ----- c now points to the first digit in the last number set
1864 (e.g. to the "5" in 123-4-567.ima) ----- */
1865
1866 /* ----- count down and up from this file --
1867 max and min image number within the series ----- */
1868 *c2 = '\0';
1869 file_n = atol(c);
1870 *c2 = '.';
1871
1872 if(!FileExists(fname_use))
1873 {
1874 errno = 0;
1875 ErrorReturn
1876 (NULL,
1877 (ERROR_BADFILE, "siemensRead(): file %s doesn't exist", fname_use));
1878 }
1879
1880 /* --- get the low image number --- */
1881 n_low = file_n - 1;
1882 sprintf(c, "%d.%s", n_low, ima);
1883 while(FileExists(fname_use))
1884 {
1885 n_low--;
1886 sprintf(c, "%d.%s", n_low, ima);
1887 }
1888 n_low++;
1889
1890 /* --- get the high image number --- */
1891 n_high = file_n + 1;
1892 sprintf(c, "%d.%s", n_high, ima);
1893 while(FileExists(fname_use))
1894 {
1895 n_high++;
1896 sprintf(c, "%d.%s", n_high, ima);
1897 }
1898 n_high--;
1899
1900 n_files = n_high - n_low + 1;
1901
1902 sprintf(c, "%d.%s", n_low, ima);
1903 if((fp = fopen(fname_use, "r")) == NULL)
1904 {
1905 errno = 0;
1906 ErrorReturn
1907 (NULL,
1908 (ERROR_BADFILE,
1909 "siemensRead(): can't open file %s (low = %d, this = %d, high = %d)",
1910 fname_use, n_low, file_n, n_high));
1911 }
1912
1913 fseek(fp, 4994, SEEK_SET);
1914 fread(&rows, 2, 1, fp);
1915 rows = orderShortBytes(rows);
1916 fseek(fp, 4996, SEEK_SET);
1917 fread(&cols, 2, 1, fp);
1918 cols = orderShortBytes(cols);
1919 fseek(fp, 4004, SEEK_SET);
1920 fread(&n_slices, 4, 1, fp);
1921 n_slices = orderIntBytes(n_slices);
1922 if (n_slices==0)
1923 {
1924 errno = 0;
1925 ErrorReturn
1926 (NULL,
1927 (ERROR_BADFILE,
1928 "\n\nPlease try with the option '-it siemens_dicom'.\n "
1929 "The handling failed assuming the old siemens format.\n"))
1930 }
1931 fseek(fp, 2864, SEEK_SET);
1932 fread(&base_raw_matrix_size, 4, 1, fp);
1933 base_raw_matrix_size = orderIntBytes(base_raw_matrix_size);
1934 fseek(fp, 1584, SEEK_SET);
1935 fread(&number_of_averages, 4, 1, fp);
1936 number_of_averages = orderIntBytes(number_of_averages);
1937 memset(pulse_sequence_name, 0x00, STRLEN);
1938 fseek(fp, 3009, SEEK_SET);
1939 fread(&pulse_sequence_name, 1, 65, fp);
1940
1941 /* --- scout --- */
1942 strcpy(ps2, pulse_sequence_name);
1943 StrLower(ps2);
1944 if(strstr(ps2, "scout") != NULL)
1945 {
1946 errno = 0;
1947 ErrorReturn
1948 (NULL,
1949 (ERROR_BADPARM,
1950 "siemensRead(): series appears to be a scout "
1951 "(sequence file name is %s)", pulse_sequence_name));
1952 }
1953
1954 /* --- structural --- */
1955 if(n_slices == 1 && ! ifi->IsMosaic)
1956 {
1957 n_slices = n_files;
1958 n_t = 1;
1959 if(base_raw_matrix_size != rows || base_raw_matrix_size != cols)
1960 {
1961 errno = 0;
1962 ErrorReturn
1963 (NULL,
1964 (ERROR_BADPARM, "siemensRead(): bad file/base matrix sizes"));
1965 }
1966 mos_r = mos_c = 1;
1967 mosaic_size = 1;
1968 }
1969 else
1970 {
1971
1972 if(rows % base_raw_matrix_size != 0)
1973 {
1974 errno = 0;
1975 ErrorReturn
1976 (NULL,
1977 (ERROR_BADPARM, "siemensRead(): file rows (%hd) not"
1978 " divisible by image rows (%d)", rows, base_raw_matrix_size));
1979 }
1980 if(cols % base_raw_matrix_size != 0)
1981 {
1982 errno = 0;
1983 ErrorReturn
1984 (NULL,
1985 (ERROR_BADPARM,
1986 "siemensRead(): file cols (%hd)"
1987 " not divisible by image cols (%d)",
1988 cols, base_raw_matrix_size));
1989 }
1990
1991 mos_r = rows / base_raw_matrix_size;
1992 mos_c = cols / base_raw_matrix_size;
1993 mosaic_size = mos_r * mos_c;
1994
1995 n_dangling_images = n_slices % mosaic_size;
1996 n_full_mosaics = (n_slices - n_dangling_images) / mosaic_size;
1997
1998 mosaics_per_volume = n_full_mosaics + (n_dangling_images == 0 ? 0 : 1);
1999
2000 if(n_files % mosaics_per_volume != 0)
2001 {
2002 errno = 0;
2003 ErrorReturn(NULL, (ERROR_BADPARM, "siemensRead(): files in volume "
2004 "(%d) not divisible by mosaics per volume (%d)",
2005 n_files, mosaics_per_volume));
2006 }
2007
2008 n_t = n_files / mosaics_per_volume;
2009
2010 }
2011
2012 if(read_volume_flag)
2013 mri = MRIallocSequence
2014 (base_raw_matrix_size, base_raw_matrix_size, n_slices, MRI_SHORT, n_t);
2015 else
2016 {
2017 mri = MRIallocHeader
2018 (base_raw_matrix_size, base_raw_matrix_size, n_slices, MRI_SHORT);
2019 mri->nframes = n_t;
2020 }
2021
2022 /* --- pixel sizes --- */
2023 /* --- mos_r and mos_c factors are strange, but they're there... --- */
2024 fseek(fp, 5000, SEEK_SET);
2025 fread(&d, 8, 1, fp);
2026 mri->xsize = mos_r * orderDoubleBytes(d);
2027 fseek(fp, 5008, SEEK_SET);
2028 fread(&d, 8, 1, fp);
2029 mri->ysize = mos_c * orderDoubleBytes(d);
2030
2031 /* --- slice distance factor --- */
2032 fseek(fp, 4136, SEEK_SET);
2033 fread(&d, 8, 1, fp);
2034 d = orderDoubleBytes(d);
2035 if(d == -19222) /* undefined (Siemens code) -- I assume this to mean 0 */
2036 d = 0.0;
2037 /* --- slice thickness --- */
2038 fseek(fp, 1544, SEEK_SET);
2039 fread(&d2, 8, 1, fp);
2040 d2 = orderDoubleBytes(d2);
2041 /* --- distance between slices --- */
2042 mri->zsize = (1.0 + d) * d2;
2043
2044 /* --- field of view (larger of height, width fov) --- */
2045 fseek(fp, 3744, SEEK_SET);
2046 fread(&d, 8, 1, fp);
2047 d = orderDoubleBytes(d);
2048 fseek(fp, 3752, SEEK_SET);
2049 fread(&d2, 8, 1, fp);
2050 d2 = orderDoubleBytes(d);
2051 mri->fov = (d > d2 ? d : d2);
2052
2053 mri->thick = mri->zsize;
2054 mri->ps = mri->xsize;
2055
2056 strcpy(mri->fname, fname);
2057
2058 mri->location = 0.0;
2059
2060 fseek(fp, 2112, SEEK_SET) ;
2061 mri->flip_angle = RADIANS(freadDouble(fp)) ; /* was in degrees */
2062
2063 fseek(fp, 1560, SEEK_SET);
2064 fread(&d, 8, 1, fp);
2065 mri->tr = orderDoubleBytes(d);
2066 fseek(fp, 1568, SEEK_SET);
2067 fread(&d, 8, 1, fp);
2068 mri->te = orderDoubleBytes(d);
2069 fseek(fp, 1576, SEEK_SET);
2070 fread(&d, 8, 1, fp);
2071 mri->ti = orderDoubleBytes(d);
2072
2073 fseek(fp, 3792, SEEK_SET);
2074 fread(&d, 8, 1, fp); mri->z_r = -orderDoubleBytes(d);
2075 fread(&d, 8, 1, fp); mri->z_a = orderDoubleBytes(d);
2076 fread(&d, 8, 1, fp); mri->z_s = -orderDoubleBytes(d);
2077
2078 fseek(fp, 3832, SEEK_SET);
2079 fread(&d, 8, 1, fp); mri->x_r = -orderDoubleBytes(d);
2080 fread(&d, 8, 1, fp); mri->x_a = orderDoubleBytes(d);
2081 fread(&d, 8, 1, fp); mri->x_s = -orderDoubleBytes(d);
2082
2083 fseek(fp, 3856, SEEK_SET);
2084 fread(&d, 8, 1, fp); mri->y_r = -orderDoubleBytes(d);
2085 fread(&d, 8, 1, fp); mri->y_a = orderDoubleBytes(d);
2086 fread(&d, 8, 1, fp); mri->y_s = -orderDoubleBytes(d);
2087
2088 fseek(fp, 3768, SEEK_SET);
2089 fread(&im_c_r, 8, 1, fp); im_c_r = -orderDoubleBytes(im_c_r);
2090 fread(&im_c_a, 8, 1, fp); im_c_a = orderDoubleBytes(im_c_a);
2091 fread(&im_c_s, 8, 1, fp); im_c_s = -orderDoubleBytes(im_c_s);
2092
2093 mri->c_r = im_c_r - (mosaic_size - 1) * mri->z_r * mri->zsize + \
2094 ((mri->depth - 1.0) / 2.0) * mri->z_r * mri->zsize;
2095 mri->c_a = im_c_a - (mosaic_size - 1) * mri->z_a * mri->zsize + \
2096 ((mri->depth - 1.0) / 2.0) * mri->z_a * mri->zsize;
2097 mri->c_s = im_c_s - (mosaic_size - 1) * mri->z_s * mri->zsize + \
2098 ((mri->depth - 1.0) / 2.0) * mri->z_s * mri->zsize;
2099
2100 mri->ras_good_flag = 1;
2101
2102 fseek(fp, 3760, SEEK_SET);
2103 fread(&i, 4, 1, fp);
2104 i = orderIntBytes(i);
2105
2106 #if 0
2107 if(i == 1 || i == 2)
2108 mri->slice_direction = MRI_HORIZONTAL;
2109 else if(i == 3 || i == 5)
2110 mri->slice_direction = MRI_CORONAL;
2111 else if(i == 4 || i == 6)
2112 mri->slice_direction = MRI_SAGITTAL;
2113 else
2114 #endif
2115 if (i < 1 || i > 6)
2116 {
2117 errno = 0;
2118 ErrorReturn
2119 (NULL,
2120 (ERROR_BADFILE,
2121 "siemensRead(): bad slice direction (%d) in file %s",
2122 i, fname_use));
2123 }
2124
2125 mri->xstart = -mri->width * mri->xsize / 2.0;
2126 mri->xend = -mri->xstart;
2127 mri->ystart = -mri->height * mri->ysize / 2.0;
2128 mri->yend = -mri->ystart;
2129 mri->zstart = -mri->depth * mri->zsize / 2.0;
2130 mri->zend = -mri->zstart;
2131
2132 /*
2133 printf("%d, %d; %d, %hd, %hd; %d\n", n_files, number_of_averages,
2134 base_raw_matrix_size, rows, cols,
2135 slices);
2136 */
2137 /*
2138 rows, cols, brms, mosaic i, j, mosaic size, n slices, n files, n_t
2139 */
2140 fclose(fp);
2141
2142 mri->imnr0 = 1;
2143 mri->imnr1 = mri->depth;
2144 /*
2145 printf("%d, %d, %d, %d\n",
2146 mri->width, mri->height, mri->depth, mri->nframes);
2147 */
2148 if(read_volume_flag)
2149 {
2150
2151 mri_raw = MRIalloc(rows, cols, n_files, MRI_SHORT);
2152
2153 for(file_n = n_low;file_n <= n_high;file_n++)
2154 {
2155
2156 sprintf(c, "%d.%s", file_n, ima);
2157 if((fp = fopen(fname_use, "r")) == NULL)
2158 {
2159 MRIfree(&mri);
2160 errno = 0;
2161 ErrorReturn(NULL, (ERROR_BADFILE,
2162 "siemensRead(): can't open file %s "
2163 "(low = %d, this = %d, high = %d)",
2164 fname_use, n_low, file_n, n_high));
2165 }
2166
2167 fseek(fp, 6144, SEEK_SET);
2168
2169 for(i = 0;i < rows;i++)
2170 {
2171 fread(&MRISvox(mri_raw, 0, i, file_n - n_low),
2172 sizeof(short), cols, fp);
2173 #if (BYTE_ORDER == LITTLE_ENDIAN)
2174 swab(&MRISvox(mri_raw, 0, i, file_n - n_low), \
2175 &MRISvox(mri_raw, 0, i, file_n - n_low),
2176 sizeof(short) * cols);
2177 #endif
2178 }
2179
2180 fclose(fp);
2181
2182 }
2183
2184 for(t = 0;t < mri->nframes;t++)
2185 {
2186 for(s = 0;s < mri->depth;s++)
2187 {
2188 slice_in_mosaic = s % mosaic_size;
2189 mosaic = (s - slice_in_mosaic) / mosaic_size;
2190 file = mri->nframes * mosaic + t;
2191 /*
2192 printf("s, t = %d, %d; f, sm = %d, %d\n",
2193 s, t, file, slice_in_mosaic);
2194 */
2195 bc = slice_in_mosaic % mos_r;
2196 br = (slice_in_mosaic - bc) / mos_r;
2197
2198 for(i = 0;i < mri->width;i++)
2199 {
2200 for(j = 0;j < mri->height;j++)
2201 {
2202 MRISseq_vox(mri, i, j, s, t) = \
2203 MRISvox
2204 (mri_raw, mri->width *
2205 bc + i, mri->height * br + j, file);
2206 }
2207 }
2208
2209 }
2210 }
2211
2212 MRIfree(&mri_raw);
2213
2214 }
2215
2216 return(mri);
2217
2218 } /* end siemensRead() */
2219 /*-----------------------------------------------------------*/
2220 static MRI *mincRead(char *fname, int read_volume)
2221 {
2222 // Real wx, wy, wz;
2223 MRI *mri;
2224 Volume vol;
2225 VIO_Status status;
2226 char *dim_names[4];
2227 int dim_sizes[4];
2228 int ndims;
2229 int dtype;
2230 volume_input_struct input_info;
2231 Real separations[4];
2232 Real voxel[4];
2233 Real worldr, worlda, worlds;
2234 Real val;
2235 int i, j, k, t;
2236 float xfov, yfov, zfov;
2237 Real f;
2238 BOOLEAN sflag = TRUE ;
2239 Transform *pVox2WorldLin;
2240 General_transform *pVox2WorldGen;
2241
2242 /* ----- read the volume ----- */
2243
2244 /* we no longer much around axes and thus */
2245 /* it is safe to read in the standard way */
2246 dim_names[0] = MIxspace;
2247 dim_names[1] = MIyspace;
2248 dim_names[2] = MIzspace;
2249 dim_names[3] = MItime;
2250
2251 #if 0
2252 dim_names[0] = MIzspace;
2253 dim_names[1] = MIyspace;
2254 dim_names[2] = MIxspace;
2255 dim_names[3] = MItime;
2256 #endif
2257
2258 if(!FileExists(fname))
2259 {
2260 errno = 0;
2261 ErrorReturn(NULL, (ERROR_BADFILE,
2262 "mincRead(): can't find file %s", fname));
2263 }
2264
2265 status = start_volume_input(fname, 0, dim_names, NC_UNSPECIFIED, 0, 0, 0,
2266 TRUE, &vol, NULL, &input_info);
2267
2268 if (Gdiag & DIAG_VERBOSE_ON && DIAG_SHOW){
2269 printf("status = %d\n", status);
2270 printf("n_dimensions = %d\n", get_volume_n_dimensions(vol));
2271 printf("nc_data_type = %d\n", vol->nc_data_type);
2272 }
2273
2274 if(status != OK){
2275 errno = 0;
2276 ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): error reading "
2277 "volume from file %s", fname));
2278 }
2279
2280 /* ----- check the number of dimensions ----- */
2281 ndims = get_volume_n_dimensions(vol);
2282 if(ndims != 3 && ndims != 4){
2283 errno = 0;
2284 ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): %d dimensions "
2285 "in file; expecting 3 or 4", ndims));
2286 }
2287
2288 /* ----- get the dimension sizes ----- */
2289 get_volume_sizes(vol, dim_sizes);
2290
2291 /* --- one time point if there are only three dimensions in the file --- */
2292 if(ndims == 3) dim_sizes[3] = 1;
2293
2294 if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2295 printf("DimSizes: %d, %d, %d, %d, %d\n", ndims, dim_sizes[0],
2296 dim_sizes[1], dim_sizes[2], dim_sizes[3]);
2297 if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2298 printf("DataType: %d\n", vol->nc_data_type);
2299
2300 dtype = get_volume_nc_data_type(vol, &sflag) ;
2301 dtype = orderIntBytes(vol->nc_data_type) ;
2302
2303 /* ----- get the data type ----- */
2304 if(vol->nc_data_type == NC_BYTE || vol->nc_data_type == NC_CHAR)
2305 dtype = MRI_UCHAR;
2306 else if(vol->nc_data_type == NC_SHORT)
2307 dtype = MRI_SHORT;
2308 else if(vol->nc_data_type == NC_LONG)
2309 dtype = MRI_LONG;
2310 else if(vol->nc_data_type == NC_FLOAT || vol->nc_data_type == NC_DOUBLE)
2311 dtype = MRI_FLOAT;
2312 else
2313 {
2314 errno = 0;
2315 ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): bad data type "
2316 "(%d) in input file %s", vol->nc_data_type, fname));
2317 }
2318
2319 /* ----- allocate the mri structure ----- */
2320 if(read_volume)
2321 mri = MRIallocSequence(dim_sizes[0], dim_sizes[1], dim_sizes[2],
2322 dtype, dim_sizes[3]);
2323 else{
2324 mri = MRIallocHeader(dim_sizes[0], dim_sizes[1], dim_sizes[2], dtype);
2325 mri->nframes = dim_sizes[3];
2326 }
2327
2328 /* ----- set up the mri structure ----- */
2329 get_volume_separations(vol, separations);
2330 mri->xsize = fabs(separations[0]);
2331 mri->ysize = fabs(separations[1]);
2332 mri->zsize = fabs(separations[2]);
2333 mri->ps = mri->xsize;
2334 mri->thick = mri->zsize;
2335
2336 mri->x_r = vol->direction_cosines[0][0];
2337 mri->x_a = vol->direction_cosines[0][1];
2338 mri->x_s = vol->direction_cosines[0][2];
2339
2340 mri->y_r = vol->direction_cosines[1][0];
2341 mri->y_a = vol->direction_cosines[1][1];
2342 mri->y_s = vol->direction_cosines[1][2];
2343
2344 mri->z_r = vol->direction_cosines[2][0];
2345 mri->z_a = vol->direction_cosines[2][1];
2346 mri->z_s = vol->direction_cosines[2][2];
2347
2348 if(separations[0] < 0){
2349 mri->x_r = -mri->x_r; mri->x_a = -mri->x_a; mri->x_s = -mri->x_s;
2350 }
2351 if(separations[1] < 0){
2352 mri->y_r = -mri->y_r; mri->y_a = -mri->y_a; mri->y_s = -mri->y_s;
2353 }
2354 if(separations[2] < 0){
2355 mri->z_r = -mri->z_r; mri->z_a = -mri->z_a; mri->z_s = -mri->z_s;
2356 }
2357
2358 voxel[0] = (mri->width) / 2.0;
2359 voxel[1] = (mri->height) / 2.0;
2360 voxel[2] = (mri->depth) / 2.0;
2361 voxel[3] = 0.0;
2362 convert_voxel_to_world(vol, voxel, &worldr, &worlda, &worlds);
2363 mri->c_r = worldr;
2364 mri->c_a = worlda;
2365 mri->c_s = worlds;
2366
2367 mri->ras_good_flag = 1;
2368
2369 mri->xend = mri->xsize * mri->width / 2.0; mri->xstart = -mri->xend;
2370 mri->yend = mri->ysize * mri->height / 2.0; mri->ystart = -mri->yend;
2371 mri->zend = mri->zsize * mri->depth / 2.0; mri->zstart = -mri->zend;
2372
2373 xfov = mri->xend - mri->xstart;
2374 yfov = mri->yend - mri->ystart;
2375 zfov = mri->zend - mri->zstart;
2376
2377 mri->fov = ( xfov > yfov ? (xfov > zfov ? xfov : zfov ) :
2378 (yfov > zfov ? yfov : zfov ) );
2379
2380 strcpy(mri->fname, fname);
2381
2382 //////////////////////////////////////////////////////////////////////////
2383 // test transform their way and our way:
2384 // MRIvoxelToWorld(mri, voxel[0], voxel[1], voxel[2], &wx, &wy, &wz);
2385 // printf("MNI calculated %.2f, %.2f, %.2f
2386 // vs. MRIvoxelToWorld: %.2f, %.2f, %.2f\n",
2387 // worldr, worlda, worlds, wx, wy, wz);
2388
2389 /* ----- copy the data from the file to the mri structure ----- */
2390 if(read_volume){
2391
2392 while(input_more_of_volume(vol, &input_info, &f));
2393
2394 for(i = 0;i < mri->width;i++) {
2395 for(j = 0;j < mri->height;j++) {
2396 for(k = 0;k < mri->depth;k++) {
2397 for(t = 0;t < mri->nframes;t++) {
2398 val = get_volume_voxel_value(vol, i, j, k, t, 0);
2399 if(mri->type == MRI_UCHAR)
2400 MRIseq_vox(mri, i, j, k, t) = (unsigned char)val;
2401 if(mri->type == MRI_SHORT)
2402 MRISseq_vox(mri, i, j, k, t) = (short)val;
2403 if(mri->type == MRI_LONG)
2404 MRILseq_vox(mri, i, j, k, t) = (long)val;
2405 if(mri->type == MRI_FLOAT)
2406 MRIFseq_vox(mri, i, j, k, t) = (float)val;
2407 }
2408 }
2409 }
2410 }
2411 }
2412
2413 pVox2WorldGen = get_voxel_to_world_transform(vol);
2414 pVox2WorldLin = get_linear_transform_ptr(pVox2WorldGen);
2415 if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2416 {
2417 printf("MINC Linear Transform\n");
2418 for(i=0;i<4;i++){
2419 for(j=0;j<4;j++) printf("%7.4f ",pVox2WorldLin->m[j][i]);
2420 printf("\n");
2421 }
2422 }
2423
2424 delete_volume_input(&input_info);
2425 delete_volume(vol);
2426
2427
2428 return(mri);
2429
2430 } /* end mincRead() */
2431 #if 0
2432 /*-----------------------------------------------------------*/
2433 static MRI *mincRead2(char *fname, int read_volume)
2434 {
2435
2436 MRI *mri;
2437 Volume vol;
2438 VIO_Status status;
2439 char *dim_names[4];
2440 int dim_sizes[4];
2441 int ndims;
2442 int dtype;
2443 volume_input_struct input_info;
2444 Real separations[4];
2445 Real voxel[4];
2446 Real worldr, worlda, worlds;
2447 Real val;
2448 int i, j, k, t;
2449 float xfov, yfov, zfov;
2450 Real f;
2451 BOOLEAN sflag = TRUE ;
2452 MATRIX *T;
2453 Transform *pVox2WorldLin;
2454 General_transform *pVox2WorldGen;
2455
2456 /* Make sure file exists */
2457 if(!FileExists(fname)){
2458 errno = 0;
2459 ErrorReturn(NULL, (ERROR_BADFILE,
2460 "mincRead(): can't find file %s", fname));
2461 }
2462
2463 /* Specify read-in order */
2464 dim_names[0] = MIxspace; /* cols */
2465 dim_names[1] = MIzspace; /* rows */
2466 dim_names[2] = MIyspace; /* slices */
2467 dim_names[3] = MItime; /* time */
2468
2469 /* Read the header info into vol. input_info needed for further reads */
2470 status = start_volume_input(fname, 0, dim_names, NC_UNSPECIFIED, 0, 0, 0,
2471 TRUE, &vol, NULL, &input_info);
2472
2473 if (Gdiag & DIAG_VERBOSE_ON && DIAG_SHOW){
2474 printf("status = %d\n", status);
2475 printf("n_dimensions = %d\n", get_volume_n_dimensions(vol));
2476 printf("nc_data_type = %d\n", vol->nc_data_type);
2477 }
2478
2479 if(status != OK){
2480 errno = 0;
2481 ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): error reading "
2482 "volume from file %s", fname));
2483 }
2484
2485 /* ----- check the number of dimensions ----- */
2486 ndims = get_volume_n_dimensions(vol);
2487 if(ndims != 3 && ndims != 4){
2488 errno = 0;
2489 ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): %d dimensions "
2490 "in file; expecting 3 or 4", ndims));
2491 }
2492
2493 /* ----- get the dimension sizes ----- */
2494 get_volume_sizes(vol, dim_sizes);
2495
2496 /* --- one time point if there are only three dimensions in the file --- */
2497 if(ndims == 3) dim_sizes[3] = 1;
2498
2499 dtype = get_volume_nc_data_type(vol, &sflag) ;
2500 dtype = orderIntBytes(vol->nc_data_type) ;
2501 get_volume_separations(vol, separations);
2502
2503 for(i=0;i<4;i++)
2504 printf("%d %s %3d %7.3f %6.4f %6.4f %6.4f \n",
2505 i,dim_names[i],dim_sizes[i],separations[i],
2506 vol->direction_cosines[i][0],vol->direction_cosines[i][1],
2507 vol->direction_cosines[i][2]);
2508 if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2509 printf("DataType: %d\n", vol->nc_data_type);
2510
2511 /* Translate data type to that of mri structure */
2512 switch(vol->nc_data_type){
2513 case NC_BYTE: dtype = MRI_UCHAR; break;
2514 case NC_CHAR: dtype = MRI_UCHAR; break;
2515 case NC_SHORT: dtype = MRI_SHORT; break;
2516 case NC_LONG: dtype = MRI_LONG; break;
2517 case NC_FLOAT: dtype = MRI_FLOAT; break;
2518 case NC_DOUBLE: dtype = MRI_FLOAT; break;
2519 default:
2520 errno = 0;
2521 ErrorReturn(NULL, (ERROR_BADPARM, "mincRead(): bad data type "
2522 "(%d) in input file %s", vol->nc_data_type, fname));
2523 break;
2524 }
2525
2526 /* ----- allocate the mri structure ----- */
2527 if(read_volume)
2528 mri = MRIallocSequence(dim_sizes[0], dim_sizes[1], dim_sizes[2],
2529 dtype, dim_sizes[3]);
2530 else{
2531 mri = MRIallocHeader(dim_sizes[0], dim_sizes[1], dim_sizes[2], dtype);
2532 mri->nframes = dim_sizes[3];
2533 }
2534
2535 /* ----- set up the mri structure ----- */
2536 get_volume_separations(vol, separations);
2537 mri->xsize = fabs(separations[0]); /* xsize = col resolution */
2538 mri->ysize = fabs(separations[1]); /* ysize = row resolution */
2539 mri->zsize = fabs(separations[2]); /* zsize = slice resolution */
2540 mri->ps = mri->xsize;
2541 mri->thick = mri->zsize;
2542
2543 /* column direction cosines */
2544 mri->x_r = vol->direction_cosines[0][0];
2545 mri->x_a = vol->direction_cosines[0][1];
2546 mri->x_s = vol->direction_cosines[0][2];
2547
2548 /* row direction cosines */
2549 mri->y_r = vol->direction_cosines[1][0];
2550 mri->y_a = vol->direction_cosines[1][1];
2551 mri->y_s = vol->direction_cosines[1][2];
2552
2553 /* slice direction cosines */
2554 mri->z_r = vol->direction_cosines[2][0];
2555 mri->z_a = vol->direction_cosines[2][1];
2556 mri->z_s = vol->direction_cosines[2][2];
2557
2558 if(separations[0] < 0){
2559 mri->x_r = -mri->x_r; mri->x_a = -mri->x_a; mri->x_s = -mri->x_s;
2560 }
2561 if(separations[1] < 0){
2562 mri->y_r = -mri->y_r; mri->y_a = -mri->y_a; mri->y_s = -mri->y_s;
2563 }
2564 if(separations[2] < 0){
2565 mri->z_r = -mri->z_r; mri->z_a = -mri->z_a; mri->z_s = -mri->z_s;
2566 }
2567
2568 /* Get center point */ // don't. our convention is different
2569 voxel[0] = (mri->width)/2.; // (mri->width - 1) / 2.0;
2570 voxel[1] = (mri->height)/2.; // (mri->height - 1) / 2.0;
2571 voxel[2] = (mri->depth)/2.; //(mri->depth - 1) / 2.0;
2572 voxel[3] = 0.0;
2573 convert_voxel_to_world(vol, voxel, &worldr, &worlda, &worlds);
2574 mri->c_r = worldr;
2575 mri->c_a = worlda;
2576 mri->c_s = worlds;
2577 printf("Center Voxel: %7.3f %7.3f %7.3f\n",voxel[0],voxel[1],voxel[2]);
2578 printf("Center World: %7.3f %7.3f %7.3f\n",mri->c_r,mri->c_a,mri->c_s);
2579
2580 mri->ras_good_flag = 1;
2581
2582 mri->xend = mri->xsize * mri->width / 2.0; mri->xstart = -mri->xend;
2583 mri->yend = mri->ysize * mri->height/ 2.0; mri->ystart = -mri->yend;
2584 mri->zend = mri->zsize * mri->depth / 2.0; mri->zstart = -mri->zend;
2585
2586 xfov = mri->xend - mri->xstart;
2587 yfov = mri->yend - mri->ystart;
2588 zfov = mri->zend - mri->zstart;
2589
2590 mri->fov =
2591 (xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
2592
2593 strcpy(mri->fname, fname);
2594
2595 T = MRIxfmCRS2XYZ(mri,0);
2596 printf("Input Coordinate Transform (CRS2XYZ)-------\n");
2597 MatrixPrint(stdout,T);
2598 MatrixFree(&T);
2599 pVox2WorldGen = get_voxel_to_world_transform(vol);
2600 pVox2WorldLin = get_linear_transform_ptr(pVox2WorldGen);
2601 if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2602 {
2603 printf("MINC Linear Transform ----------------------\n");
2604 for(i=0;i<4;i++){
2605 for(j=0;j<4;j++) printf("%7.4f ",pVox2WorldLin->m[j][i]);
2606 printf("\n");
2607 }
2608 printf("-------------------------------------------\n");
2609 }
2610
2611 /* ----- copy the data from the file to the mri structure ----- */
2612 if(read_volume){
2613
2614 while(input_more_of_volume(vol, &input_info, &f));
2615
2616 for(i = 0;i < mri->width;i++) {
2617 for(j = 0;j < mri->height;j++) {
2618 for(k = 0;k < mri->depth;k++) {
2619 for(t = 0;t < mri->nframes;t++) {
2620 val = get_volume_voxel_value(vol, i, j, k, t, 0);
2621 switch(mri->type){
2622 case MRI_UCHAR: MRIseq_vox(mri,i,j,k,t) = (unsigned char)val;break;
2623 case MRI_SHORT: MRISseq_vox(mri,i,j,k,t) = (short)val;break;
2624 case MRI_LONG: MRILseq_vox(mri,i,j,k,t) = (long)val;break;
2625 case MRI_FLOAT: MRIFseq_vox(mri,i,j,k,t) = (float)val;break;
2626 }
2627 }
2628 }
2629 }
2630 }
2631 }
2632
2633 delete_volume_input(&input_info);
2634 delete_volume(vol);
2635
2636 return(mri);
2637
2638 } /* end mincRead2() */
2639 /*-----------------------------------------------------------*/
2640 static int GetMINCInfo(MRI *mri,
2641 char *dim_names[4],
2642 int dim_sizes[4],
2643 Real separations[4],
2644 Real dircos[3][3],
2645 Real VolCenterVox[3],
2646 Real VolCenterWorld[3])
2647 {
2648 int xspacehit, yspacehit, zspacehit;
2649 float col_dc_x, col_dc_y, col_dc_z;
2650 float row_dc_x, row_dc_y, row_dc_z;
2651 float slc_dc_x, slc_dc_y, slc_dc_z;
2652 Real col_dc_sign, row_dc_sign, slc_dc_sign;
2653 int err,i,j;
2654
2655 col_dc_x = fabs(mri->x_r);
2656 col_dc_y = fabs(mri->x_a);
2657 col_dc_z = fabs(mri->x_s);
2658 col_dc_sign = 1;
2659
2660 row_dc_x = fabs(mri->y_r);
2661 row_dc_y = fabs(mri->y_a);
2662 row_dc_z = fabs(mri->y_s);
2663 row_dc_sign = 1;
2664
2665 slc_dc_x = fabs(mri->z_r);
2666 slc_dc_y = fabs(mri->z_a);
2667 slc_dc_z = fabs(mri->z_s);
2668 slc_dc_sign = 1;
2669
2670 xspacehit = 0;
2671 yspacehit = 0;
2672 zspacehit = 0;
2673
2674 /* Name the Column Axis */
2675 if(col_dc_x >= row_dc_x && col_dc_x >= slc_dc_x){
2676 dim_names[0] = MIxspace;
2677 VolCenterVox[0] = (mri->width-1)/2.0;
2678 if(mri->x_r < 0) col_dc_sign = -1;
2679 xspacehit = 1;
2680 }
2681 else if(col_dc_y >= row_dc_y && col_dc_y >= slc_dc_y){
2682 dim_names[0] = MIyspace;
2683 VolCenterVox[0] = (mri->height-1)/2.0;
2684 if(mri->x_a < 0) col_dc_sign = -1;
2685 yspacehit = 1;
2686 }
2687 else if(col_dc_z >= row_dc_z && col_dc_z >= slc_dc_z){
2688 dim_names[0] = MIzspace;
2689 VolCenterVox[0] = (mri->depth-1)/2.0;
2690 if(mri->x_s < 0) col_dc_sign = -1;
2691 zspacehit = 1;
2692 }
2693
2694 /* Name the Row Axis */
2695 if(!xspacehit && row_dc_x >= slc_dc_x){
2696 dim_names[1] = MIxspace;
2697 VolCenterVox[1] = (mri->width-1)/2.0;
2698 if(mri->y_r < 0) row_dc_sign = -1;
2699 xspacehit = 1;
2700 }
2701 else if(!yspacehit && row_dc_y >= slc_dc_y){
2702 dim_names[1] = MIyspace;
2703 VolCenterVox[1] = (mri->height-1)/2.0;
2704 if(mri->y_a < 0) row_dc_sign = -1;
2705 yspacehit = 1;
2706 }
2707 else if(!zspacehit && row_dc_z >= slc_dc_z){
2708 dim_names[1] = MIzspace;
2709 VolCenterVox[1] = (mri->depth-1)/2.0;
2710 if(mri->y_s < 0) row_dc_sign = -1;
2711 zspacehit = 1;
2712 }
2713
2714 /* Name the Slice Axis */
2715 if(!xspacehit){
2716 dim_names[2] = MIxspace;
2717 VolCenterVox[2] = (mri->width-1)/2.0;
2718 if(mri->z_r < 0) slc_dc_sign = -1;
2719 xspacehit = 1;
2720 }
2721 else if(!yspacehit){
2722 dim_names[2] = MIyspace;
2723 VolCenterVox[2] = (mri->height-1)/2.0;
2724 if(mri->z_a < 0) slc_dc_sign = -1;
2725 yspacehit = 1;
2726 }
2727 if(!zspacehit){
2728 dim_names[2] = MIzspace;
2729 VolCenterVox[2] = (mri->depth-1)/2.0;
2730 if(mri->z_s < 0) slc_dc_sign = -1;
2731 zspacehit = 1;
2732 }
2733
2734 /* Check for errors in the Axis Naming*/
2735 err = 0;
2736 if(!xspacehit){
2737 printf("ERROR: could not assign xspace\n");
2738 err = 1;
2739 }
2740 if(!yspacehit){
2741 printf("ERROR: could not assign yspace\n");
2742 err = 1;
2743 }
2744 if(!zspacehit){
2745 printf("ERROR: could not assign zspace\n");
2746 err = 1;
2747 }
2748 if(err) return(1);
2749
2750 /* Name the Frame Axis */
2751 dim_names[3] = MItime;
2752
2753 /* Set world center */
2754 VolCenterWorld[0] = mri->c_r;
2755 VolCenterWorld[1] = mri->c_a;
2756 VolCenterWorld[2] = mri->c_s;
2757
2758 /* Set dimension lengths */
2759 dim_sizes[0] = mri->width;
2760 dim_sizes[1] = mri->height;
2761 dim_sizes[2] = mri->depth;
2762 dim_sizes[3] = mri->nframes;
2763
2764 /* Set separations */
2765 separations[0] = col_dc_sign * mri->xsize;
2766 separations[1] = row_dc_sign * mri->ysize;
2767 separations[2] = slc_dc_sign * mri->zsize;
2768 separations[3] = mri->tr;
2769
2770 /* Set direction Cosines */
2771 dircos[0][0] = col_dc_sign * mri->x_r;
2772 dircos[0][1] = col_dc_sign * mri->x_a;
2773 dircos[0][2] = col_dc_sign * mri->x_s;
2774
2775 dircos[1][0] = row_dc_sign * mri->y_r;
2776 dircos[1][1] = row_dc_sign * mri->y_a;
2777 dircos[1][2] = row_dc_sign * mri->y_s;
2778
2779 dircos[2][0] = slc_dc_sign * mri->z_r;
2780 dircos[2][1] = slc_dc_sign * mri->z_a;
2781 dircos[2][2] = slc_dc_sign * mri->z_s;
2782
2783 /* This is a hack for the case where the dircos are the default.
2784 The MINC routines will not save the direction cosines as
2785 NetCDF attriubtes if they correspond to the default. */
2786 for(i=0;i<3;i++)
2787 for(j=0;j<3;j++)
2788 if(fabs(dircos[i][j] < .00000000001)) dircos[i][j] = .0000000000000001;
2789
2790 return(0);
2791 }
2792
2793 /*-----------------------------------------------------------*/
2794 static int mincWrite2(MRI *mri, char *fname)
2795 {
2796 Volume minc_volume;
2797 nc_type nc_data_type = NC_BYTE;
2798 int ndim,i,j;
2799 Real min, max;
2800 float fmin, fmax;
2801 char *dim_names[4];
2802 int dim_sizes[4];
2803 Real separations[4];
2804 Real dircos[3][3];
2805 Real VolCenterVox[3];
2806 Real VolCenterWorld[3];
2807 int signed_flag = 0;
2808 int r,c,s,f;
2809 Real VoxVal = 0.0;
2810 int return_value;
2811 VIO_Status status;
2812 MATRIX *T;
2813 Transform *pVox2WorldLin;
2814 General_transform *pVox2WorldGen;
2815
2816 /* Get the min and max for the volume */
2817 if((return_value = MRIlimits(mri, &fmin, &fmax)) != NO_ERROR)
2818 return(return_value);
2819 min = (Real)fmin;
2820 max = (Real)fmax;
2821
2822 /* Translate mri type to NetCDF type */
2823 switch(mri->type){
2824 case MRI_UCHAR: nc_data_type = NC_BYTE; signed_flag = 0; break;
2825 case MRI_SHORT: nc_data_type = NC_SHORT; signed_flag = 1; break;
2826 case MRI_INT: nc_data_type = NC_LONG; signed_flag = 1; break;
2827 case MRI_LONG: nc_data_type = NC_LONG; signed_flag = 1; break;
2828 case MRI_FLOAT: nc_data_type = NC_FLOAT; signed_flag = 1; break;
2829 }
2830
2831 /* Assign default direction cosines, if needed */
2832 if(mri->ras_good_flag == 0){
2833 setDirectionCosine(mri, MRI_CORONAL);
2834 }
2835
2836 GetMINCInfo(mri, dim_names, dim_sizes, separations, dircos,
2837 VolCenterVox,VolCenterWorld);
2838
2839 if(mri->nframes > 1) ndim = 4;
2840 else ndim = 3;
2841
2842 minc_volume = create_volume(ndim, dim_names, nc_data_type,
2843 signed_flag, min, max);
2844 set_volume_sizes(minc_volume, dim_sizes);
2845 alloc_volume_data(minc_volume);
2846
2847 for(i=0;i<3;i++){
2848 printf("%d %s %4d %7.3f %7.3f %7.3f %7.3f \n",
2849 i,dim_names[i],dim_sizes[i],separations[i],
2850 dircos[i][0],dircos[i][1],dircos[i][2]);
2851 set_volume_direction_cosine(minc_volume, i, dircos[i]);
2852 }
2853 printf("Center Voxel: %7.3f %7.3f %7.3f\n",
2854 VolCenterVox[0],VolCenterVox[1],VolCenterVox[2]);
2855 printf("Center World: %7.3f %7.3f %7.3f\n",
2856 VolCenterWorld[0],VolCenterWorld[1],VolCenterWorld[2]);
2857
2858 set_volume_separations(minc_volume, separations);
2859 set_volume_translation(minc_volume, VolCenterVox, VolCenterWorld);
2860
2861 T = MRIxfmCRS2XYZ(mri,0);
2862 printf("MRI Transform -----------------------------\n");
2863 MatrixPrint(stdout,T);
2864 pVox2WorldGen = get_voxel_to_world_transform(minc_volume);
2865 pVox2WorldLin = get_linear_transform_ptr(pVox2WorldGen);
2866 if ((Gdiag & DIAG_SHOW) && DIAG_VERBOSE_ON)
2867 {
2868 printf("MINC Linear Transform ----------------------\n");
2869 for(i=0;i<4;i++){
2870 for(j=0;j<4;j++) printf("%7.4f ",pVox2WorldLin->m[j][i]);
2871 printf("\n");
2872 }
2873 printf("--------------------------------------------\n");
2874 }
2875 MatrixFree(&T);
2876
2877 printf("Setting Volume Values\n");
2878 for(f = 0; f < mri->nframes; f++) { /* frames */
2879 for(c = 0; c < mri->width; c++) { /* columns */
2880 for(r = 0; r < mri->height; r++) { /* rows */
2881 for(s = 0; s < mri->depth; s++) { /* slices */
2882
2883 switch(mri->type){
2884 case MRI_UCHAR: VoxVal = (Real)MRIseq_vox(mri, c, r, s, f);break;
2885 case MRI_SHORT: VoxVal = (Real)MRISseq_vox(mri, c, r, s, f);break;
2886 case MRI_INT: VoxVal = (Real)MRIIseq_vox(mri, c, r, s, f);break;
2887 case MRI_LONG: VoxVal = (Real)MRILseq_vox(mri, c, r, s, f);break;
2888 case MRI_FLOAT: VoxVal = (Real)MRIFseq_vox(mri, c, r, s, f);break;
2889 }
2890 set_volume_voxel_value(minc_volume, c, r, s, f, 0, VoxVal);
2891 }
2892 }
2893 }
2894 }
2895
2896 printf("Writing Volume\n");
2897 status = output_volume((STRING)fname, nc_data_type, signed_flag, min, max,
2898 minc_volume, (STRING)"", NULL);
2899 printf("Cleaning Up\n");
2900 delete_volume(minc_volume);
2901
2902 if(status) {
2903 printf("ERROR: mincWrite: output_volume exited with %d\n",status);
2904 return(1);
2905 }
2906
2907 printf("mincWrite2: done\n");
2908 return(NO_ERROR);
2909 }
2910
2911
2912 /*-------------------------------------------------------
2913 NormalizeVector() - in-place vector normalization
2914 -------------------------------------------------------*/
2915 static int NormalizeVector(float *v, int n)
2916 {
2917 float sum2;
2918 int i;
2919 sum2 = 0;
2920 for(i=0;i<n;i++) sum2 += v[i];
2921 sum2 = sqrt(sum2);
2922 for(i=0;i<n;i++) v[i] /= sum2;
2923 return(0);
2924 }
2925 #endif
2926 /*----------------------------------------------------------*/
2927 /* time course clean */
2928 static int mincWrite(MRI *mri, char *fname)
2929 {
2930
2931 Volume minc_volume;
2932 STRING dimension_names[4] = { "xspace", "yspace", "zspace", "time" };
2933 nc_type nc_data_type;
2934 Real min, max;
2935 float fmin, fmax;
2936 int dimension_sizes[4];
2937 Real separations[4];
2938 Real dir_cos[4];
2939 int return_value;
2940 Real voxel[4], world[4];
2941 int signed_flag;
2942 int di_x, di_y, di_z;
2943 int vi[4];
2944 /* int r, a, s; */
2945 /* float r_max; */
2946 VIO_Status status;
2947
2948 /* di gives the bogus minc index
2949 di[0] is width, 1 is height, 2 is depth, 3 is time if
2950 there is a time dimension of length > 1
2951 minc wants these to be ras */
2952
2953 /* here: minc volume index 0 is r, 1 is a, 2 is s */
2954 /* mri is lia *//* (not true for some volumes *)*/
2955
2956 /* ----- get the orientation of the volume ----- */
2957 if(mri->ras_good_flag == 0)
2958 {
2959 setDirectionCosine(mri, MRI_CORONAL);
2960 }
2961
2962 /* we don't muck around axes anymore */
2963 di_x = 0;
2964 di_y = 1;
2965 di_z = 2;
2966
2967 #if 0
2968 /* The following remapping is only valid for COR files */
2969 /* In order to handle arbitrary volumes, we don't muck around */
2970 /* the axes anymore ... tosa */
2971
2972 /* orig->minc map ***********************************/
2973 /* r axis is mapped to (x_r, y_r, z_r) voxel coords */
2974 /* thus find the biggest value among x_r, y_r, z_r */
2975 /* that one corresponds to the r-axis */
2976 r = 0;
2977 r_max = fabs(mri->x_r);
2978 if(fabs(mri->y_r) > r_max)
2979 {
2980 r_max = fabs(mri->y_r);
2981 r = 1;
2982 }
2983 if(fabs(mri->z_r) > r_max)
2984 r = 2;
2985
2986 /* a axis is mapped to (x_a, y_a, z_a) voxel coords */
2987 if(r == 0)
2988 a = (fabs(mri->y_a) > fabs(mri->z_a) ? 1 : 2);
2989 else if(r == 1)
2990 a = (fabs(mri->x_a) > fabs(mri->z_a) ? 0 : 2);
2991 else
2992 a = (fabs(mri->x_a) > fabs(mri->y_a) ? 0 : 1);
2993
2994 /* s axis is mapped to (x_s, y_s, z_s) voxel coords */
2995 /* use the rest to figure */
2996 s = 3 - r - a;
2997
2998 /* ----- set the appropriate minc axes to this orientation ----- */
2999 /* r gives the mri structure axis of the lr coordinate */
3000 /* lr = minc xspace = 0 */
3001 /* a ..... of the pa coordinate *//* pa = minc yspace = 1 */
3002 /* s ..... of the is coordinate *//* is = minc zspace = 2 */
3003
3004 /* di of this axis must be set to 2 */
3005 /* ... and so on */
3006
3007 /* minc->orig map **************************************/
3008 /* you don't need the routine above but do a similar thing */
3009 /* to get exactly the same, i.e. */
3010 /* x-axis corresponds to (x_r, x_a, x_s) minc coords */
3011 /* y-axis (y_r, y_a, y_s) minc coords */
3012 /* z-axis (z_r, z_a, z_s) minc coords */
3013 /* thus we are doing too much work */
3014
3015 if(r == 0)
3016 {
3017 if(a == 1)
3018 {
3019 di_x = 0;
3020 di_y = 1;
3021 di_z = 2;
3022 }
3023 else
3024 {
3025 di_x = 0;
3026 di_y = 2;
3027 di_z = 1;
3028 }
3029 }
3030 else if(r == 1)
3031 {
3032 if(a == 0)
3033 {
3034 di_x = 1;
3035 di_y = 0;
3036 di_z = 2;
3037 }
3038 else
3039 {
3040 di_x = 2;
3041 di_y = 0;
3042 di_z = 1;
3043 }
3044 }
3045 else
3046 {
3047 if(a == 0)
3048 {
3049 di_x = 1;
3050 di_y = 2;
3051 di_z = 0;
3052 }
3053 else
3054 {
3055 di_x = 2;
3056 di_y = 1;
3057 di_z = 0;
3058 }
3059 }
3060 #endif
3061
3062 /* ----- set the data type ----- */
3063 if(mri->type == MRI_UCHAR)
3064 {
3065 nc_data_type = NC_BYTE;
3066 signed_flag = 0;
3067 }
3068 else if(mri->type == MRI_SHORT)
3069 {
3070 nc_data_type = NC_SHORT;
3071 signed_flag = 1;
3072 }
3073 else if(mri->type == MRI_INT)
3074 {
3075 nc_data_type = NC_LONG;
3076 signed_flag = 1;
3077 }
3078 else if(mri->type == MRI_LONG)
3079 {
3080 nc_data_type = NC_LONG;
3081 signed_flag = 1;
3082 }
3083 else if(mri->type == MRI_FLOAT)
3084 {
3085 nc_data_type = NC_FLOAT;
3086 signed_flag = 1;
3087 }
3088 else
3089 {
3090 errno = 0;
3091 ErrorReturn
3092 (ERROR_BADPARM,
3093 (ERROR_BADPARM,
3094 "mincWrite(): bad data type (%d) in mri structure",
3095 mri->type));
3096 }
3097
3098 if((return_value = MRIlimits(mri, &fmin, &fmax)) != NO_ERROR)
3099 return(return_value);
3100
3101 min = (Real)fmin;
3102 max = (Real)fmax;
3103
3104 if(mri->nframes == 1)
3105 minc_volume = create_volume
3106 (3, dimension_names, nc_data_type, signed_flag, min, max);
3107 else
3108 minc_volume = create_volume
3109 (4, dimension_names, nc_data_type, signed_flag, min, max);
3110
3111 /* di_(x,y,z) is the map from minc to orig */
3112 /* minc dimension size is that of di_x, etc. */
3113 dimension_sizes[di_x] = mri->width;
3114 dimension_sizes[di_y] = mri->height;
3115 dimension_sizes[di_z] = mri->depth;
3116 dimension_sizes[3] = mri->nframes;
3117
3118 set_volume_sizes(minc_volume, dimension_sizes);
3119
3120 alloc_volume_data(minc_volume);
3121
3122 separations[di_x] = (Real)(mri->xsize);
3123 separations[di_y] = (Real)(mri->ysize);
3124 separations[di_z] = (Real)(mri->zsize);
3125 separations[3] = 1.0; // appears to do nothing
3126 set_volume_separations(minc_volume, separations);
3127 /* has side effect to change transform and thus must be set first */
3128
3129 dir_cos[0] = (Real)mri->x_r;
3130 dir_cos[1] = (Real)mri->x_a;
3131 dir_cos[2] = (Real)mri->x_s;
3132 set_volume_direction_cosine(minc_volume, di_x, dir_cos);
3133
3134 dir_cos[0] = (Real)mri->y_r;
3135 dir_cos[1] = (Real)mri->y_a;
3136 dir_cos[2] = (Real)mri->y_s;
3137 set_volume_direction_cosine(minc_volume, di_y, dir_cos);
3138
3139 dir_cos[0] = (Real)mri->z_r;
3140 dir_cos[1] = (Real)mri->z_a;
3141 dir_cos[2] = (Real)mri->z_s;
3142 set_volume_direction_cosine(minc_volume, di_z, dir_cos);
3143
3144 voxel[di_x] = mri->width / 2.0; // promoted to double
3145 voxel[di_y] = mri->height/ 2.0;
3146 voxel[di_z] = mri->depth / 2.0;
3147 voxel[3] = 0.0;
3148 world[0] = (Real)(mri->c_r);
3149 world[1] = (Real)(mri->c_a);
3150 world[2] = (Real)(mri->c_s);
3151 world[3] = 0.0;
3152 set_volume_translation(minc_volume, voxel, world);
3153
3154 /* get the position from (vi[di_x], vi[di_y], vi[di_z]) orig position */
3155 /* put the value to (vi[0], vi[1], vi[2]) minc volume */
3156 /* this will keep the orientation of axes the same as the original */
3157
3158 /* vi[n] gives the index of the variable along minc axis x */
3159 /* vi[di_x] gives the index of the variable
3160 along minc axis di_x, or along mri axis x */
3161 for(vi[3] = 0;vi[3] < mri->nframes;vi[3]++) { /* frames */
3162 for(vi[di_x] = 0;vi[di_x] < mri->width;vi[di_x]++) { /* columns */
3163 for(vi[di_y] = 0;vi[di_y] < mri->height;vi[di_y]++) { /* rows */
3164 for(vi[di_z] = 0;vi[di_z] < mri->depth;vi[di_z]++) { /* slices */
3165
3166 if(mri->type == MRI_UCHAR)
3167 set_volume_voxel_value
3168 (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3169 (Real)MRIseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3170 if(mri->type == MRI_SHORT)
3171 set_volume_voxel_value
3172 (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3173 (Real)MRISseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3174 if(mri->type == MRI_INT)
3175 set_volume_voxel_value
3176 (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3177 (Real)MRIIseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3178 if(mri->type == MRI_LONG)
3179 set_volume_voxel_value
3180 (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3181 (Real)MRILseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3182 if(mri->type == MRI_FLOAT)
3183 set_volume_voxel_value
3184 (minc_volume, vi[0], vi[1], vi[2], vi[3], 0,
3185 (Real)MRIFseq_vox(mri, vi[di_x], vi[di_y], vi[di_z], vi[3]));
3186 }
3187 }
3188 }
3189 }
3190
3191 status = output_volume((STRING)fname, nc_data_type, signed_flag, min, max,
3192 minc_volume, (STRING)"", NULL);
3193 delete_volume(minc_volume);
3194
3195 if(status) {
3196 printf("ERROR: mincWrite: output_volume exited with %d\n",status);
3197 return(1);
3198 }
3199
3200 return(NO_ERROR);
3201
3202 } /* end mincWrite() */
3203
3204
3205 /*----------------------------------------------------------------
3206 bvolumeWrite() - replaces bshortWrite and bfloatWrite.
3207 Bug: fname_passed must the the stem, not the full file name.
3208 -----------------------------------------------------------------*/
3209 static int bvolumeWrite(MRI *vol, char *fname_passed, int type)
3210 {
3211
3212 int i, j, t;
3213 char fname[STRLEN];
3214 short *bufshort;
3215 float *buffloat;
3216 FILE *fp;
3217 int result;
3218 MRI *subject_info = NULL;
3219 char subject_volume_dir[STRLEN];
3220 char *subjects_dir;
3221 char *sn;
3222 char analyse_fname[STRLEN], register_fname[STRLEN];
3223 char output_dir[STRLEN];
3224 char *c;
3225 int od_length;
3226 char t1_path[STRLEN];
3227 MATRIX *cf, *bf, *ibf, *af, *iaf, *as, *bs, *cs, *ics, *r;
3228 MATRIX *r1, *r2, *r3, *r4;
3229 float det;
3230 int bad_flag;
3231 int l;
3232 char stem[STRLEN];
3233 char *c1, *c2, *c3;
3234 struct stat stat_buf;
3235 char subject_dir[STRLEN];
3236 int dealloc, nslices, nframes;
3237 MRI *mri;
3238 float min,max;
3239 int swap_bytes_flag, size, bufsize;
3240 char *ext;
3241 void *buf;
3242
3243 /* check the type and set the extension and size*/
3244 switch(type) {
3245 case MRI_SHORT: ext = "bshort"; size = sizeof(short); break;
3246 case MRI_FLOAT: ext = "bfloat"; size = sizeof(float); break;
3247 default:
3248 fprintf
3249 (stderr,"ERROR: bvolumeWrite: type (%d) is not short or float\n", type);
3250 return(1);
3251 }
3252
3253 if(vol->type != type){
3254 if (DIAG_VERBOSE_ON)
3255 printf("INFO: bvolumeWrite: changing type\n");
3256 nslices = vol->depth;
3257 nframes = vol->nframes;
3258 vol->depth = nslices*nframes;
3259 vol->nframes = 1;
3260 MRIlimits(vol,&min,&max);
3261 if (DIAG_VERBOSE_ON)
3262 printf("INFO: bvolumeWrite: range %g %g\n",min,max);
3263 mri = MRIchangeType(vol,type,min,max,1);
3264 if(mri == NULL) {
3265 fprintf(stderr,"ERROR: bvolumeWrite: MRIchangeType\n");
3266 return(1);
3267 }
3268 vol->depth = nslices;
3269 vol->nframes = nframes;
3270 mri->depth = nslices;
3271 mri->nframes = nframes;
3272 dealloc = 1;
3273 }
3274 else{
3275 mri = vol;
3276 dealloc = 0;
3277 }
3278
3279 /* ----- get the stem from the passed file name ----- */
3280 /*
3281 four options:
3282 1. stem_xxx.bshort
3283 2. stem.bshort
3284 3. stem_xxx
3285 4. stem
3286 other possibles:
3287 stem_.bshort
3288 */
3289 l = strlen(fname_passed);
3290 c1 = fname_passed + l - 11;
3291 c2 = fname_passed + l - 7;
3292 c3 = fname_passed + l - 4;
3293 strcpy(stem, fname_passed);
3294 if(c1 > fname_passed)
3295 {
3296 if( (*c1 == '_' && strcmp(c1+4, ".bshort") == 0) ||
3297 (*c1 == '_' && strcmp(c1+4, ".bfloat") == 0) )
3298 stem[(int)(c1-fname_passed)] = '\0';
3299 }
3300 if(c2 > fname_passed)
3301 {
3302 if( (*c2 == '_' && strcmp(c2+4, ".bshort") == 0) ||
3303 (*c2 == '_' && strcmp(c2+4, ".bfloat") == 0) )
3304 stem[(int)(c2-fname_passed)] = '\0';
3305
3306 }
3307 if(c3 > fname_passed)
3308 {
3309 if(*c3 == '_')
3310 stem[(int)(c3-fname_passed)] = '\0';
3311 }
3312 printf("INFO: bvolumeWrite: stem = %s\n",stem);
3313
3314 c = strrchr(stem, '/');
3315 if(c == NULL)
3316 output_dir[0] = '\0';
3317 else
3318 {
3319 od_length = (int)(c - stem);
3320 strncpy(output_dir, stem, od_length);
3321 /* -- leaving the trailing '/' on a directory is not my
3322 usual convention, but here it's a load easier if there's
3323 no directory in stem... -ch -- */
3324 output_dir[od_length] = '/';
3325 output_dir[od_length+1] = '\0';
3326 }
3327
3328 sprintf(analyse_fname, "%s%s", output_dir, "analyse.dat");
3329 sprintf(register_fname, "%s%s", output_dir, "register.dat");
3330
3331 bufsize = mri->width * size;
3332 bufshort = (short *)malloc(bufsize);
3333 buffloat = (float *)malloc(bufsize);
3334
3335 buf = NULL; /* shuts up compiler */
3336 if(type == MRI_SHORT) buf = bufshort;
3337 else buf = buffloat;
3338
3339 swap_bytes_flag = 0;
3340 #if (BYTE_ORDER==LITTLE_ENDIAN)
3341 swap_bytes_flag = 1;
3342 #endif
3343
3344 //printf("--------------------------------\n");
3345 //MRIdump(mri,stdout);
3346 //MRIdumpBuffer(mri,stdout);
3347 //printf("--------------------------------\n");
3348
3349 for(i = 0;i < mri->depth;i++)
3350 {
3351
3352 /* ----- write the header file ----- */
3353 sprintf(fname, "%s_%03d.hdr", stem, i);
3354 if((fp = fopen(fname, "w")) == NULL)
3355 {
3356 if(dealloc) MRIfree(&mri);
3357 free(bufshort);
3358 free(buffloat);
3359 errno = 0;
3360 ErrorReturn
3361 (ERROR_BADFILE, (ERROR_BADFILE,
3362 "bvolumeWrite(): can't open file %s", fname));
3363 }
3364 fprintf(fp, "%d %d %d %d\n", mri->height, mri->width, mri->nframes, 0);
3365 fclose(fp);
3366
3367 /* ----- write the data file ----- */
3368 sprintf(fname, "%s_%03d.%s", stem, i, ext);
3369 if((fp = fopen(fname, "w")) == NULL)
3370 {
3371 if(dealloc) MRIfree(&mri);
3372 free(bufshort);
3373 free(buffloat);
3374 errno = 0;
3375 ErrorReturn
3376 (ERROR_BADFILE, (ERROR_BADFILE,
3377 "bvolumeWrite(): can't open file %s", fname));
3378 }
3379
3380 for(t = 0;t < mri->nframes;t++) {
3381 for(j = 0;j < mri->height;j++) {
3382 memcpy(buf,mri->slices[t*mri->depth + i][j], bufsize);
3383
3384 if(swap_bytes_flag){
3385 if(type == MRI_SHORT) byteswapbufshort((void*)buf, bufsize);
3386 else byteswapbuffloat((void*)buf, bufsize);
3387 }
3388 fwrite(buf, size, mri->width, fp);
3389 }
3390 }
3391
3392 fclose(fp);
3393 }
3394
3395 free(bufshort);
3396 free(buffloat);
3397
3398 sn = subject_name;
3399 if(mri->subject_name[0] != '\0')
3400 sn = mri->subject_name;
3401
3402 if(sn != NULL)
3403 {
3404 if((subjects_dir = getenv("SUBJECTS_DIR")) == NULL)
3405 {
3406 errno = 0;
3407 ErrorPrintf
3408 (ERROR_BADPARM,
3409 "bvolumeWrite(): environment variable SUBJECTS_DIR unset");
3410 if(dealloc) MRIfree(&mri);
3411 }
3412 else
3413 {
3414
3415 sprintf(subject_dir, "%s/%s", subjects_dir, sn);
3416 if(stat(subject_dir, &stat_buf) < 0)
3417 {
3418 fprintf
3419 (stderr,
3420 "can't stat %s; writing to bhdr instead\n", subject_dir);
3421 }
3422 else
3423 {
3424 if(!S_ISDIR(stat_buf.st_mode))
3425 {
3426 fprintf
3427 (stderr,
3428 "%s is not a directory; writing to bhdr instead\n",
3429 subject_dir);
3430 }
3431 else
3432 {
3433 sprintf(subject_volume_dir, "%s/mri/T1", subject_dir);
3434 subject_info = MRIreadInfo(subject_volume_dir);
3435 if(subject_info == NULL)
3436 {
3437 sprintf(subject_volume_dir, "%s/mri/orig", subject_dir);
3438 subject_info = MRIreadInfo(subject_volume_dir);
3439 if(subject_info == NULL)
3440 fprintf(stderr,
3441 "can't read the subject's orig or T1 volumes; "
3442 "writing to bhdr instead\n");
3443 }
3444 }
3445 }
3446
3447 }
3448
3449 }
3450
3451 if(subject_info != NULL)
3452 {
3453 if(subject_info->ras_good_flag == 0)
3454 {
3455 setDirectionCosine(subject_info, MRI_CORONAL);
3456 }
3457 }
3458
3459 cf = bf = ibf = af = iaf = as = bs = cs = ics = r = NULL;
3460 r1 = r2 = r3 = r4 = NULL;
3461
3462 /* ----- write the register.dat and analyse.dat or bhdr files ----- */
3463 if(subject_info != NULL)
3464 {
3465
3466 bad_flag = FALSE;
3467
3468 if((as = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3469 {
3470 errno = 0;
3471 ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3472 bad_flag = TRUE;
3473 }
3474 stuff_four_by_four
3475 (as, subject_info->x_r, subject_info->y_r, subject_info->z_r, subject_info->c_r,
3476 subject_info->y_r, subject_info->y_r, subject_info->y_r, subject_info->c_r,
3477 subject_info->z_r, subject_info->z_r, subject_info->z_r, subject_info->c_r,
3478 0.0, 0.0, 0.0, 1.0);
3479
3480 if((af = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3481 {
3482 errno = 0;
3483 ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3484 bad_flag = TRUE;
3485 }
3486 stuff_four_by_four(af, mri->x_r, mri->y_r, mri->z_r, mri->c_r,
3487 mri->y_r, mri->y_r, mri->y_r, mri->c_r,
3488 mri->z_r, mri->z_r, mri->z_r, mri->c_r,
3489 0.0, 0.0, 0.0, 1.0);
3490
3491 if((bs = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3492 {
3493 errno = 0;
3494 ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3495 bad_flag = TRUE;
3496 }
3497 stuff_four_by_four(bs, 1, 0, 0, (subject_info->width - 1) / 2.0,
3498 0, 1, 0, (subject_info->height - 1) / 2.0,
3499 0, 0, 1, (subject_info->depth - 1) / 2.0,
3500 0, 0, 0, 1.0);
3501
3502 if((bf = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3503 {
3504 errno = 0;
3505 ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3506 bad_flag = TRUE;
3507 }
3508 stuff_four_by_four(bf, 1, 0, 0, (mri->width - 1) / 2.0,
3509 0, 1, 0, (mri->height - 1) / 2.0,
3510 0, 0, 1, (mri->depth - 1) / 2.0,
3511 0, 0, 0, 1.0);
3512
3513 if((cs = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3514 {
3515 errno = 0;
3516 ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3517 bad_flag = TRUE;
3518 }
3519 stuff_four_by_four
3520 (cs,
3521 -subject_info->xsize, 0, 0,(subject_info->width * mri->xsize) / 2.0,\
3522 0, 0, subject_info->zsize, -(subject_info->depth * mri->zsize) / 2.0, \
3523 0, -subject_info->ysize, 0, (subject_info->height * mri->ysize) / 2.0, \
3524 0, 0, 0, 1);
3525
3526 if((cf = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
3527 {
3528 errno = 0;
3529 ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error creating matrix");
3530 bad_flag = TRUE;
3531 }
3532 stuff_four_by_four
3533 (cf,
3534 -mri->xsize, 0, 0, (mri->width * mri->xsize) / 2.0,
3535 0, 0, mri->zsize, -(mri->depth * mri->zsize) / 2.0,
3536 0, -mri->ysize, 0, (mri->height * mri->ysize) / 2.0,
3537 0, 0, 0, 1);
3538
3539 if(bad_flag)
3540 {
3541 errno = 0;
3542 ErrorPrintf
3543 (ERROR_BADPARM,
3544 "bvolumeWrite(): error creating one "
3545 "or more matrices; aborting register.dat "
3546 "write and writing bhdr instead");
3547 MRIfree(&subject_info);
3548 }
3549
3550 }
3551
3552 if(subject_info != NULL)
3553 {
3554
3555 bad_flag = FALSE;
3556
3557 if((det = MatrixDeterminant(as)) == 0.0)
3558 {
3559 errno = 0;
3560 ErrorPrintf
3561 (ERROR_BADPARM,
3562 "bvolumeWrite(): bad determinant in "
3563 "matrix (check structural volume)");
3564 bad_flag = TRUE;
3565 }
3566 if((det = MatrixDeterminant(bs)) == 0.0)
3567 {
3568 errno = 0;
3569 ErrorPrintf
3570 (ERROR_BADPARM,
3571 "bvolumeWrite(): bad determinant in "
3572 "matrix (check structural volume)");
3573 bad_flag = TRUE;
3574 }
3575 if((det = MatrixDeterminant(cs)) == 0.0)
3576 {
3577 errno = 0;
3578 ErrorPrintf
3579 (ERROR_BADPARM,
3580 "bvolumeWrite(): bad determinant in "
3581 "matrix (check structural volume)");
3582 bad_flag = TRUE;
3583 }
3584
3585 if((det = MatrixDeterminant(af)) == 0.0)
3586 {
3587 errno = 0;
3588 ErrorPrintf
3589 (ERROR_BADPARM,
3590 "bvolumeWrite(): bad determinant in "
3591 "matrix (check functional volume)");
3592 bad_flag = TRUE;
3593 }
3594 if((det = MatrixDeterminant(bf)) == 0.0)
3595 {
3596 errno = 0;
3597 ErrorPrintf
3598 (ERROR_BADPARM,
3599 "bvolumeWrite(): bad determinant in "
3600 "matrix (check functional volume)");
3601 bad_flag = TRUE;
3602 }
3603 if((det = MatrixDeterminant(cf)) == 0.0)
3604 {
3605 errno = 0;
3606 ErrorPrintf
3607 (ERROR_BADPARM,
3608 "bvolumeWrite(): bad determinant in "
3609 "matrix (check functional volume)");
3610 bad_flag = TRUE;
3611 }
3612
3613 if(bad_flag)
3614 {
3615 errno = 0;
3616 ErrorPrintf
3617 (ERROR_BADPARM, "bvolumeWrite(): one or more zero determinants;"
3618 " aborting register.dat write and writing bhdr instead");
3619 MRIfree(&subject_info);
3620 }
3621
3622 }
3623
3624 if(subject_info != NULL)
3625 {
3626
3627 bad_flag = FALSE;
3628
3629 if((iaf = MatrixInverse(af, NULL)) == NULL)
3630 {
3631 errno = 0;
3632 ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error inverting matrix");
3633 bad_flag = TRUE;
3634 }
3635 if((ibf = MatrixInverse(bf, NULL)) == NULL)
3636 {
3637 errno = 0;
3638 ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error inverting matrix");
3639 bad_flag = TRUE;
3640 }
3641 if((ics = MatrixInverse(cs, NULL)) == NULL)
3642 {
3643 errno = 0;
3644 ErrorPrintf(ERROR_BADPARM, "bvolumeWrite(): error inverting matrix");
3645 bad_flag = TRUE;
3646 }
3647
3648 if(bad_flag)
3649 {
3650 errno = 0;
3651 ErrorPrintf
3652 (ERROR_BADPARM, "bvolumeWrite(): one or more zero determinants; "
3653 "aborting register.dat write and writing bhdr instead");
3654 MRIfree(&subject_info);
3655 }
3656 }
3657
3658 bad_flag = FALSE;
3659
3660 if(subject_info != NULL)
3661 {
3662
3663 if((r1 = MatrixMultiply(bs, ics, NULL)) == NULL)
3664 {
3665 bad_flag = TRUE;
3666 MRIfree(&subject_info);
3667 }
3668
3669 }
3670
3671 if(subject_info != NULL)
3672 {
3673
3674 if((r2 = MatrixMultiply(as, r1, NULL)) == NULL)
3675 {
3676 bad_flag = TRUE;
3677 MRIfree(&subject_info);
3678 }
3679
3680 }
3681
3682 if(subject_info != NULL)
3683 {
3684
3685 if((r3 = MatrixMultiply(iaf, r2, NULL)) == NULL)
3686 {
3687 bad_flag = TRUE;
3688 MRIfree(&subject_info);
3689 }
3690
3691 }
3692
3693 if(subject_info != NULL)
3694 {
3695
3696 if((r4 = MatrixMultiply(ibf, r3, NULL)) == NULL)
3697 {
3698 bad_flag = TRUE;
3699 MRIfree(&subject_info);
3700 }
3701
3702 }
3703
3704 if(subject_info != NULL)
3705 {
3706
3707 if((r = MatrixMultiply(cf, r4, NULL)) == NULL)
3708 {
3709 bad_flag = TRUE;
3710 MRIfree(&subject_info);
3711 }
3712
3713 }
3714
3715 if(bad_flag)
3716 {
3717 errno = 0;
3718 ErrorPrintf
3719 (ERROR_BADPARM, "bvolumeWrite(): error during matrix multiplications; "
3720 "aborting register.dat write and writing bhdr instead");
3721 }
3722
3723 if( as != NULL) MatrixFree( &as);
3724 if( bs != NULL) MatrixFree( &bs);
3725 if( cs != NULL) MatrixFree( &cs);
3726 if( af != NULL) MatrixFree( &af);
3727 if( bf != NULL) MatrixFree( &bf);
3728 if( cf != NULL) MatrixFree( &cf);
3729 if(iaf != NULL) MatrixFree(&iaf);
3730 if(ibf != NULL) MatrixFree(&ibf);
3731 if(ics != NULL) MatrixFree(&ics);
3732 if( r1 != NULL) MatrixFree( &r1);
3733 if( r2 != NULL) MatrixFree( &r2);
3734 if( r3 != NULL) MatrixFree( &r3);
3735 if( r4 != NULL) MatrixFree( &r4);
3736
3737 if(subject_info != NULL)
3738 {
3739
3740 if(mri->path_to_t1[0] == '\0')
3741 sprintf(t1_path, ".");
3742 else
3743 strcpy(t1_path, mri->path_to_t1);
3744
3745 if(FileExists(analyse_fname))
3746 fprintf(stderr, "warning: overwriting file %s\n", analyse_fname);
3747
3748 if((fp = fopen(analyse_fname, "w")) == NULL)
3749 {
3750 MRIfree(&subject_info);
3751 errno = 0;
3752 ErrorReturn
3753 (ERROR_BADFILE,
3754 (ERROR_BADFILE,
3755 "bvolumeWrite(): couldn't open file %s for writing",
3756 analyse_fname));
3757 }
3758
3759 fprintf(fp, "%s\n", t1_path);
3760 fprintf(fp, "%s_%%03d.bshort\n", stem);
3761 fprintf(fp, "%d %d\n", mri->depth, mri->nframes);
3762 fprintf(fp, "%d %d\n", mri->width, mri->height);
3763
3764 fclose(fp);
3765
3766 if(FileExists(analyse_fname))
3767 fprintf(stderr, "warning: overwriting file %s\n", register_fname);
3768
3769 if((fp = fopen(register_fname, "w")) == NULL)
3770 {
3771 MRIfree(&subject_info);
3772 errno = 0;
3773 ErrorReturn
3774 (ERROR_BADFILE,
3775 (ERROR_BADFILE,
3776 "bvolumeWrite(): couldn't open file %s for writing",
3777 register_fname));
3778 }
3779
3780 fprintf(fp, "%s\n", sn);
3781 fprintf(fp, "%g\n", mri->xsize);
3782 fprintf(fp, "%g\n", mri->zsize);
3783 fprintf(fp, "%g\n", 1.0);
3784 fprintf(fp, "%g %g %g %g\n", \
3785 *MATRIX_RELT(r, 1, 1),
3786 *MATRIX_RELT(r, 1, 2),
3787 *MATRIX_RELT(r, 1, 3),
3788 *MATRIX_RELT(r, 1, 4));
3789 fprintf(fp, "%g %g %g %g\n", \
3790 *MATRIX_RELT(r, 2, 1),
3791 *MATRIX_RELT(r, 2, 2),
3792 *MATRIX_RELT(r, 2, 3),
3793 *MATRIX_RELT(r, 2, 4));
3794 fprintf(fp, "%g %g %g %g\n", \
3795 *MATRIX_RELT(r, 3, 1),
3796 *MATRIX_RELT(r, 3, 2),
3797 *MATRIX_RELT(r, 3, 3),
3798 *MATRIX_RELT(r, 3, 4));
3799 fprintf(fp, "%g %g %g %g\n", \
3800 *MATRIX_RELT(r, 4, 1),
3801 *MATRIX_RELT(r, 4, 2),
3802 *MATRIX_RELT(r, 4, 3),
3803 *MATRIX_RELT(r, 4, 4));
3804
3805 fclose(fp);
3806
3807 MatrixFree(&r);
3808
3809 }
3810
3811 if(subject_info == NULL)
3812 {
3813 sprintf(fname, "%s.bhdr", stem);
3814 if((fp = fopen(fname, "w")) == NULL)
3815 {
3816 if(dealloc) MRIfree(&mri);
3817 errno = 0;
3818 ErrorReturn
3819 (ERROR_BADFILE,
3820 (ERROR_BADFILE, "bvolumeWrite(): can't open file %s", fname));
3821 }
3822
3823 result = write_bhdr(mri, fp);
3824
3825 fclose(fp);
3826
3827 if(result != NO_ERROR)
3828 return(result);
3829
3830 }
3831 else
3832 MRIfree(&subject_info);
3833
3834 if(dealloc) MRIfree(&mri);
3835
3836 return(NO_ERROR);
3837
3838 } /* end bvolumeWrite() */
3839
3840 static MRI *get_b_info
3841 (char *fname_passed, int read_volume, char *directory, char *stem, int type)
3842 {
3843
3844 MRI *mri, *mri2;
3845 FILE *fp;
3846 int nslices=0, nt;
3847 int nx, ny;
3848 int result;
3849 char fname[STRLEN];
3850 char extension[STRLEN];
3851 char bhdr_name[STRLEN];
3852
3853 if(type == MRI_SHORT) sprintf(extension, "bshort");
3854 else if(type == MRI_FLOAT) sprintf(extension, "bfloat");
3855 else{
3856 errno = 0;
3857 ErrorReturn(NULL, (ERROR_UNSUPPORTED,
3858 "internal error: get_b_info() passed type %d", type));
3859 }
3860
3861 result = decompose_b_fname(fname_passed, directory, stem);
3862 if(result != NO_ERROR) return(NULL);
3863
3864 if(directory[0] == '\0') sprintf(directory, ".");
3865
3866 #if 0
3867
3868 char sn[STRLEN];
3869 char fname_descrip[STRLEN];
3870 float fov_x, fov_y, fov_z;
3871 MATRIX *m;
3872 int res;
3873 char register_fname[STRLEN], analyse_fname[STRLEN];
3874 float ipr, st, intensity;
3875 float m11, m12, m13, m14;
3876 float m21, m22, m23, m24;
3877 float m31, m32, m33, m34;
3878 float m41, m42, m43, m44;
3879 char t1_path[STRLEN];
3880
3881 /* ----- try register.dat and analyse.dat, then bhdr, then defaults ----- */
3882 sprintf(register_fname, "%s/register.dat", directory);
3883 sprintf(analyse_fname, "%s/analyse.dat", directory);
3884
3885 if((fp = fopen(register_fname, "r")) != NULL)
3886 {
3887
3888 fscanf(fp, "%s", sn);
3889 fscanf(fp, "%f", &ipr);
3890 fscanf(fp, "%f", &st);
3891 fscanf(fp, "%f", &intensity);
3892 fscanf(fp, "%f %f %f %f", &m11, &m12, &m13, &m14);
3893 fscanf(fp, "%f %f %f %f", &m21, &m22, &m23, &m24);
3894 fscanf(fp, "%f %f %f %f", &m31, &m32, &m33, &m34);
3895 fscanf(fp, "%f %f %f %f", &m41, &m42, &m43, &m44);
3896 fclose(fp);
3897
3898 if((fp = fopen(analyse_fname, "r")) != NULL)
3899 {
3900
3901 fscanf(fp, "%s", t1_path);
3902 fscanf(fp, "%s", fname_descrip);
3903 fscanf(fp, "%d %d", &nslices, &nt);
3904 fscanf(fp, "%d %d", &nx, &ny);
3905 fclose(fp);
3906
3907 if(read_volume)
3908 {
3909 mri = MRIallocSequence(nx, ny, nslices, MRI_SHORT, nt);
3910 }
3911 else
3912 {
3913 mri = MRIallocHeader(nx, ny, nslices, MRI_SHORT);
3914 mri->nframes = nt;
3915 }
3916
3917 strcpy(mri->fname, fname_passed);
3918 mri->imnr0 = 1;
3919 mri->imnr1 = nslices;
3920 mri->xsize = mri->ysize = mri->ps = ipr;
3921 mri->zsize = mri->thick = st;
3922
3923 fov_x = mri->xsize * mri->width;
3924 fov_y = mri->ysize * mri->height;
3925 fov_z = mri->zsize * mri->depth;
3926
3927 mri->fov = (fov_x > fov_y ? (fov_x > fov_z ? fov_x : fov_z) :
3928 (fov_y > fov_z ? fov_y : fov_z));
3929
3930 mri->xend = fov_x / 2.0;
3931 mri->xstart = -mri->xend;
3932 mri->yend = fov_y / 2.0;
3933 mri->ystart = -mri->yend;
3934 mri->zend = fov_z / 2.0;
3935 mri->zstart = -mri->zend;
3936
3937 mri->brightness = intensity;
3938 strcpy(mri->subject_name, sn);
3939 strcpy(mri->path_to_t1, t1_path);
3940 strcpy(mri->fname_format, fname_descrip);
3941
3942 m = MatrixAlloc(4, 4, MATRIX_REAL);
3943 if(m == NULL)
3944 {
3945 MRIfree(&mri);
3946 errno = 0;
3947 ErrorReturn(NULL, (ERROR_NO_MEMORY, "error allocating "
3948 "matrix in %s read", extension));
3949 }
3950 stuff_four_by_four(m, m11, m12, m13, m14,
3951 m21, m22, m23, m24,
3952 m31, m32, m33, m34,
3953 m41, m42, m43, m44);
3954 mri->register_mat = m;
3955 res = orient_with_register(mri);
3956 if(res != NO_ERROR){
3957 MRIfree(&mri);
3958 return(NULL);
3959 }
3960 return(mri);
3961 }
3962 }
3963 #endif
3964
3965 mri = MRIallocHeader(1, 1, 1, type);
3966
3967 /* ----- try to read the stem.bhdr ----- */
3968 sprintf(bhdr_name, "%s/%s.bhdr", directory, stem);
3969 if((fp = fopen(bhdr_name, "r")) != NULL)
3970 {
3971 read_bhdr(mri, fp);
3972 sprintf(fname, "%s/%s_000.hdr", directory, stem);
3973 if((fp = fopen(fname, "r")) == NULL){
3974 MRIfree(&mri);
3975 errno = 0;
3976 ErrorReturn(NULL, (ERROR_BADFILE, "cannot open %s", fname));
3977 }
3978 fscanf(fp, "%d %d %d %*d", &ny, &nx, &nt);
3979 mri->nframes = nt;
3980 fclose(fp);
3981 }
3982 else
3983 { /* ----- get defaults ----- */
3984 fprintf
3985 (stderr,
3986 "-----------------------------------------------------------------\n"
3987 "Could not find the direction cosine information.\n"
3988 "Will use the CORONAL orientation.\n"
3989 "If not suitable, please provide the information in %s file\n"
3990 "-----------------------------------------------------------------\n",
3991 bhdr_name);
3992 sprintf(fname, "%s/%s_000.hdr", directory, stem);
3993 if((fp = fopen(fname, "r")) == NULL)
3994 {
3995 MRIfree(&mri);
3996 errno = 0;
3997 ErrorReturn(NULL, (ERROR_BADFILE, "can't find file %s (last resort);"
3998 "bailing out on read", fname));
3999 }
4000 fscanf(fp, "%d %d %d %*d", &ny, &nx, &nt);
4001 fclose(fp);
4002
4003 /* --- get the number of slices --- */
4004 sprintf(fname, "%s/%s_000.%s", directory, stem, extension);
4005 if(!FileExists(fname)){
4006 MRIfree(&mri);
4007 errno = 0;
4008 ErrorReturn(NULL, (ERROR_BADFILE, "can't find file %s; "
4009 "bailing out on read", fname));
4010 }
4011 for(nslices = 0;FileExists(fname);nslices++)
4012 sprintf(fname, "%s/%s_%03d.%s", directory, stem, nslices, extension);
4013 nslices--;
4014
4015 mri->width = nx;
4016 mri->height = ny;
4017 mri->depth = nslices;
4018 mri->nframes = nt;
4019
4020 mri->imnr0 = 1;
4021 mri->imnr1 = nslices;
4022
4023 mri->thick = mri->ps = 1.0;
4024 mri->xsize = mri->ysize = mri->zsize = 1.0;
4025
4026 setDirectionCosine(mri, MRI_CORONAL);
4027
4028 mri->ras_good_flag = 0;
4029
4030 strcpy(mri->fname, fname_passed);
4031
4032 }
4033
4034 mri->imnr0 = 1;
4035 mri->imnr1 = nslices;
4036
4037 mri->xend = mri->width * mri->xsize / 2.0;
4038 mri->xstart = -mri->xend;
4039 mri->yend = mri->height * mri->ysize / 2.0;
4040 mri->ystart = -mri->yend;
4041 mri->zend = mri->depth * mri->zsize / 2.0;
4042 mri->zstart = -mri->zend;
4043
4044 mri->fov = ((mri->xend - mri->xstart) > (mri->yend - mri->ystart) ?
4045 (mri->xend - mri->xstart) : (mri->yend - mri->ystart));
4046
4047
4048 if(read_volume)
4049 {
4050 mri2 = MRIallocSequence(mri->width, mri->height, mri->depth,
4051 mri->type, mri->nframes);
4052 MRIcopyHeader(mri, mri2);
4053 MRIfree(&mri);
4054 mri = mri2;
4055 }
4056
4057 return(mri);
4058
4059 } /* end get_b_info() */
4060
4061 /*-------------------------------------------------------------------
4062 bvolumeRead() - this replaces bshortRead and bfloatRead.
4063 -------------------------------------------------------------------*/
4064 static MRI *bvolumeRead(char *fname_passed, int read_volume, int type)
4065 {
4066
4067 MRI *mri;
4068 FILE *fp;
4069 char fname[STRLEN];
4070 char directory[STRLEN];
4071 char stem[STRLEN];
4072 int swap_bytes_flag;
4073 int slice, frame, row, k;
4074 int nread;
4075 char *ext;
4076 int size;
4077 float min, max;
4078
4079 /* check the type and set the extension and size*/
4080 switch(type) {
4081 case MRI_SHORT: ext = "bshort"; size = sizeof(short); break;
4082 case MRI_FLOAT: ext = "bfloat"; size = sizeof(float); break;
4083 default:
4084 fprintf(stderr,"ERROR: bvolumeRead: type (%d) is not "
4085 "short or float\n", type);
4086 return(NULL);
4087 }
4088
4089 /* Get the header info (also allocs if needed) */
4090 mri = get_b_info(fname_passed, read_volume, directory, stem, type);
4091 if(mri == NULL) return(NULL);
4092
4093 /* If not reading the volume, return now */
4094 if(! read_volume) return(mri);
4095
4096 /* Read in the header of the first slice to get the endianness */
4097 sprintf(fname, "%s/%s_%03d.hdr", directory, stem, 0);
4098 if((fp = fopen(fname, "r")) == NULL){
4099 fprintf(stderr, "ERROR: can't open file %s; assuming big-endian bvolume\n",
4100 fname);
4101 swap_bytes_flag = 0;
4102 }
4103 else{
4104 fscanf(fp, "%*d %*d %*d %d", &swap_bytes_flag);
4105 #if (BYTE_ORDER == LITTLE_ENDIAN)
4106 swap_bytes_flag = !swap_bytes_flag;
4107 #endif
4108 fclose(fp);
4109 }
4110
4111 /* Go through each slice */
4112 for(slice = 0;slice < mri->depth; slice++){
4113
4114 /* Open the file for this slice */
4115 sprintf(fname, "%s/%s_%03d.%s", directory, stem, slice, ext);
4116 if((fp = fopen(fname, "r")) == NULL){
4117 MRIfree(&mri);
4118 errno = 0;
4119 ErrorReturn(NULL, (ERROR_BADFILE,
4120 "bvolumeRead(): error opening file %s", fname));
4121 }
4122 //fprintf(stderr, "Reading %s ... \n", fname);
4123 /* Loop through the frames */
4124 for(frame = 0; frame < mri->nframes; frame ++){
4125 k = slice + mri->depth*frame;
4126
4127 /* Loop through the rows */
4128 for(row = 0;row < mri->height; row++){
4129
4130 /* read in all the columns for a row */
4131 nread = fread(mri->slices[k][row], size, mri->width, fp);
4132 if( nread != mri->width){
4133 fclose(fp);
4134 MRIfree(&mri);
4135 errno = 0;
4136 ErrorReturn(NULL, (ERROR_BADFILE, "bvolumeRead(): "
4137 "error reading from file %s", fname));
4138 }
4139
4140 if(swap_bytes_flag){
4141 if(type == MRI_SHORT)
4142 swab(mri->slices[k][row], mri->slices[k][row], mri->width * size);
4143 else
4144 byteswapbuffloat((void*)mri->slices[k][row],size*mri->width);
4145 }
4146 } /* row loop */
4147 } /* frame loop */
4148
4149 fclose(fp);
4150 } /* slice loop */
4151
4152 MRIlimits(mri,&min,&max);
4153 printf("INFO: bvolumeRead: min = %g, max = %g\n",min,max);
4154
4155 mri->imnr0 = 1;
4156 mri->imnr1 = mri->depth;
4157 mri->thick = mri->zsize;
4158
4159 return(mri);
4160
4161 } /* end bvolumeRead() */
4162
4163
4164 #if 0
4165 static int orient_with_register(MRI *mri)
4166 {
4167
4168 MRI *subject_mri;
4169 char *subjects_dir;
4170 char subject_directory[STRLEN];
4171 MATRIX *sa, *fa;
4172 MATRIX *sr, *fr;
4173 MATRIX *rinv, *sainv;
4174 MATRIX *r1, *r2;
4175 int res;
4176 float det;
4177
4178 subject_mri = NULL;
4179 if((subjects_dir = getenv("SUBJECTS_DIR")) != NULL)
4180 {
4181 sprintf
4182 (subject_directory, "%s/%s/mri/T1", subjects_dir, mri->subject_name);
4183 if((subject_mri = MRIreadInfo(subject_directory)) == NULL)
4184 {
4185 errno = 0;
4186 ErrorPrintf
4187 (ERROR_BADPARM,
4188 "can't get get information from %s; ", subject_directory);
4189 sprintf
4190 (subject_directory,
4191 "%s/%s/mri/T1", subjects_dir, mri->subject_name);
4192 ErrorPrintf
4193 (ERROR_BADPARM, "trying %s instead...\n", subject_directory);
4194 if((subject_mri = MRIreadInfo(subject_directory)) == NULL)
4195 ErrorPrintf
4196 (ERROR_BADPARM,
4197 "can't get information from %s\n", subject_directory);
4198 }
4199 }
4200 else
4201 {
4202 errno = 0;
4203 ErrorPrintf
4204 (ERROR_BADPARM, "can't get environment variable SUBJECTS_DIR");
4205 }
4206
4207 if(subject_mri == NULL)
4208 {
4209
4210 errno = 0;
4211 ErrorPrintf(ERROR_BADPARM, "guessing at COR- orientation...\n");
4212
4213 subject_mri = MRIallocHeader(256, 256, 256, MRI_UCHAR);
4214 subject_mri->fov = 256.0;
4215 subject_mri->thick = subject_mri->ps = 1.0;
4216 subject_mri->xsize = subject_mri->ysize = subject_mri->zsize = 1.0;
4217 setDirectionCosine(subject_mri, MRI_CORONAL);
4218 subject_mri->ras_good_flag = 1;
4219 }
4220
4221 det = MatrixDeterminant(mri->register_mat);
4222 if(det == 0.0)
4223 {
4224 MRIfree(&subject_mri);
4225 errno = 0;
4226 ErrorPrintf
4227 (ERROR_BADPARM,
4228 "orient_with_register(): registration matrix has zero determinant");
4229 ErrorPrintf(ERROR_BADPARM, "matrix is:");
4230 MatrixPrint(stderr, mri->register_mat);
4231 return(ERROR_BADPARM);
4232 }
4233
4234 rinv = MatrixInverse(mri->register_mat, NULL);
4235
4236 if(rinv == NULL)
4237 {
4238 MRIfree(&subject_mri);
4239 errno = 0;
4240 ErrorPrintf
4241 (ERROR_BADPARM,
4242 "orient_with_register(): error inverting registration matrix");
4243 ErrorPrintf(ERROR_BADPARM, "matrix is:");
4244 MatrixPrint(stderr, mri->register_mat);
4245 return(ERROR_BADPARM);
4246 }
4247
4248 sr = extract_i_to_r(subject_mri);
4249
4250 sa = MatrixAlloc(4, 4, MATRIX_REAL);
4251 fa = MatrixAlloc(4, 4, MATRIX_REAL);
4252
4253 if(sr == NULL || sa == NULL || fa == NULL)
4254 {
4255 if(sr != NULL)
4256 MatrixFree(&sr);
4257 if(sa != NULL)
4258 MatrixFree(&sa);
4259 if(fa != NULL)
4260 MatrixFree(&fa);
4261 MatrixFree(&rinv);
4262 MRIfree(&subject_mri);
4263 errno = 0;
4264 ErrorReturn
4265 (ERROR_NO_MEMORY,
4266 (ERROR_NO_MEMORY,
4267 "orient_with_register(): error allocating matrix"));
4268 }
4269
4270 stuff_four_by_four
4271 (sa, -subject_mri->xsize, 0.0, 0.0, subject_mri->width * subject_mri->xsize / 2.0,
4272 0.0, 0.0, subject_mri->zsize, -subject_mri->depth * subject_mri->zsize / 2.0,
4273 0.0, -subject_mri->ysize, 0.0, subject_mri->height * subject_mri->ysize / 2.0,
4274 0.0, 0.0, 0.0, 1.0);
4275
4276 MRIfree(&subject_mri);
4277
4278 stuff_four_by_four(fa, -mri->xsize, 0.0, 0.0, mri->width * mri->xsize / 2.0,
4279 0.0, 0.0, mri->zsize, -mri->depth * mri->zsize / 2.0,
4280 0.0, -mri->ysize, 0.0, mri->height * mri->ysize / 2.0,
4281 0.0, 0.0, 0.0, 1.0);
4282 det = MatrixDeterminant(sa);
4283 if(det == 0.0)
4284 {
4285 MatrixFree(&sr);
4286 MatrixFree(&sa);
4287 MatrixFree(&fa);
4288 MatrixFree(&rinv);
4289 errno = 0;
4290 ErrorPrintf(ERROR_BADPARM,
4291 "orient_with_register(): destination (ijk) -> r "
4292 "space matrix has zero determinant");
4293 ErrorPrintf(ERROR_BADPARM, "matrix is:");
4294 MatrixPrint(stderr, sa);
4295 return(ERROR_BADPARM);
4296 }
4297
4298 sainv = MatrixInverse(sa, NULL);
4299 MatrixFree(&sa);
4300
4301 if(sainv == NULL)
4302 {
4303 MatrixFree(&sr);
4304 MatrixFree(&sa);
4305 MatrixFree(&fa);
4306 MatrixFree(&rinv);
4307 errno = 0;
4308 ErrorPrintf
4309 (ERROR_BADPARM,
4310 "orient_with_register(): error inverting "
4311 "destination (ijk) -> r space matrix");
4312 ErrorPrintf(ERROR_BADPARM, "matrix is:");
4313 MatrixPrint(stderr, sainv);
4314 return(ERROR_BADPARM);
4315 }
4316
4317 r1 = MatrixMultiply(rinv, fa, NULL);
4318 MatrixFree(&rinv);
4319 MatrixFree(&fa);
4320 if(r1 == NULL)
4321 {
4322 MatrixFree(&sr);
4323 MatrixFree(&sa);
4324 MatrixFree(&sainv);
4325 errno = 0;
4326 ErrorReturn(ERROR_BADPARM,
4327 (ERROR_BADPARM,
4328 "orient_with_register(): error multiplying matrices"));
4329 }
4330
4331 r2 = MatrixMultiply(sainv, r1, NULL);
4332 MatrixFree(&r1);
4333 MatrixFree(&sainv);
4334 if(r2 == NULL)
4335 {
4336 MatrixFree(&sr);
4337 MatrixFree(&sa);
4338 errno = 0;
4339 ErrorReturn(ERROR_BADPARM,
4340 (ERROR_BADPARM,
4341 "orient_with_register(): error multiplying matrices"));
4342 }
4343
4344 fr = MatrixMultiply(sr, r2, NULL);
4345 MatrixFree(&sr);
4346 MatrixFree(&r2);
4347 if(fr == NULL)
4348 {
4349 errno = 0;
4350 ErrorReturn(ERROR_BADPARM,
4351 (ERROR_BADPARM,
4352 "orient_with_register(): error multiplying matrices"));
4353 }
4354
4355 res = apply_i_to_r(mri, fr);
4356 MatrixFree(&fr);
4357
4358 if(res != NO_ERROR)
4359 return(res);
4360
4361 return(NO_ERROR);
4362
4363 } /* end orient_with_register() */
4364 #endif
4365
4366 int decompose_b_fname(char *fname, char *dir, char *stem)
4367 {
4368
4369 char *slash, *dot, *stem_start, *underscore;
4370 int fname_length;
4371 int und_pos;
4372 char fname_copy[STRLEN];
4373
4374 /*
4375
4376 options for file names:
4377
4378 stem_xxx.bshort
4379 stem_xxx
4380 stem_.bshort
4381 stem_
4382 stem.bshort
4383 stem
4384
4385 with or without a preceding directory
4386
4387 */
4388
4389 strcpy(fname_copy, fname);
4390
4391 slash = strrchr(fname_copy, '/');
4392 dot = strrchr(fname_copy, '.');
4393 underscore = strrchr(fname_copy, '_');
4394
4395 if(slash == NULL)
4396 {
4397 stem_start = fname_copy;
4398 sprintf(dir, ".");
4399 }
4400 else
4401 {
4402 *slash = '\0';
4403 strcpy(dir, fname_copy);
4404 stem_start = slash + 1;
4405 }
4406
4407 if(*stem_start == '\0')
4408 {
4409 errno = 0;
4410 ErrorReturn
4411 (ERROR_BADPARM,
4412 (ERROR_BADPARM,
4413 "decompose_b_fname(): bad bshort/bfloat file specifier \"%s\"",
4414 fname));
4415 }
4416
4417 if(dot != NULL)
4418 if(strcmp(dot, ".bshort") == 0 || strcmp(dot, ".bfloat") == 0)
4419 *dot = '\0';
4420
4421 fname_length = strlen(stem_start);
4422
4423 if(underscore == NULL)
4424 strcpy(stem, stem_start);
4425 else
4426 {
4427 und_pos = (underscore - stem_start);
4428 if(und_pos == fname_length - 1 || und_pos == fname_length - 4)
4429 *underscore = '\0';
4430 strcpy(stem, stem_start);
4431 }
4432
4433 return(NO_ERROR);
4434
4435 } /* end decompose_b_fname() */
4436
4437 /*-------------------------------------------------------------*/
4438 static int write_bhdr(MRI *mri, FILE *fp)
4439 {
4440 float vl; /* vector length */
4441 float tlr, tla, tls; /* top left coordinates */
4442 float trr, tra, trs; /* top right coordinates */
4443 float brr, bra, brs; /* bottom right coordinates */
4444 float nr, na, ns; /* normal coordinates */
4445 MATRIX *T, *crs1, *ras1;
4446
4447 crs1 = MatrixAlloc(4,1,MATRIX_REAL);
4448 crs1->rptr[1][4] = 1;
4449 ras1 = MatrixAlloc(4,1,MATRIX_REAL);
4450
4451 /* Construct the matrix to convert CRS to XYZ, assuming
4452 that CRS is 1-based */
4453 T = MRIxfmCRS2XYZ(mri,0);
4454 //printf("------- write_bhdr: T ---------\n");
4455 //MatrixPrint(stdout,T);
4456 //printf("------------------------------\n");
4457
4458 /* The "top left" is the center of the first voxel */
4459 tlr = T->rptr[1][4];
4460 tla = T->rptr[2][4];
4461 tls = T->rptr[3][4];
4462
4463 /* The "top right" is the center of the last voxel + 1 in the
4464 column direction - this unfortunate situation is historical.
4465 It makes the difference between the TL and TR equal to the
4466 edge-to-edge FOV in the column direction. */
4467 crs1->rptr[1][1] = mri->width;
4468 crs1->rptr[1][2] = 0;
4469 crs1->rptr[1][3] = 0;
4470 MatrixMultiply(T,crs1,ras1);
4471 trr = ras1->rptr[1][1];
4472 tra = ras1->rptr[1][2];
4473 trs = ras1->rptr[1][3];
4474
4475 /* The "bottom right" is the center of the last voxel + 1 in the
4476 column and row directions - this unfortunate situation is
4477 historical. It makes the difference between the TR and BR equal
4478 to the edge-to-edge FOV in the row direction. */
4479 crs1->rptr[1][1] = mri->width;
4480 crs1->rptr[1][2] = mri->height;
4481 crs1->rptr[1][3] = 0;
4482 MatrixMultiply(T,crs1,ras1);
4483 brr = ras1->rptr[1][1];
4484 bra = ras1->rptr[1][2];
4485 brs = ras1->rptr[1][3];
4486
4487 MatrixFree(&T);
4488 MatrixFree(&crs1);
4489 MatrixFree(&ras1);
4490
4491 /* ----- normalize this just in case ----- */
4492 vl = sqrt(mri->z_r*mri->z_r + mri->z_a*mri->z_a + mri->z_s*mri->z_s);
4493 nr = mri->z_r / vl;
4494 na = mri->z_a / vl;
4495 ns = mri->z_s / vl;
4496
4497 #if 0
4498 time_t time_now;
4499 float cr, ca, cs; /* first slice center coordinates */
4500 cr = mri->c_r - (mri->depth - 1) / 2.0 * mri->z_r * mri->zsize;
4501 ca = mri->c_a - (mri->depth - 1) / 2.0 * mri->z_a * mri->zsize;
4502 cs = mri->c_s - (mri->depth - 1) / 2.0 * mri->z_s * mri->zsize;
4503
4504 tlr = cr - mri->width / 2.0 * mri->x_r * mri->xsize - mri->height / 2.0 *
4505 mri->y_r * mri->ysize;
4506 tla = ca - mri->width / 2.0 * mri->x_a * mri->xsize - mri->height / 2.0 *
4507 mri->y_a * mri->ysize;
4508 tls = cs - mri->width / 2.0 * mri->x_s * mri->xsize - mri->height / 2.0 *
4509 mri->y_s * mri->ysize;
4510
4511 trr = cr + mri->width / 2.0 * mri->x_r * mri->xsize - mri->height / 2.0 *
4512 mri->y_r * mri->ysize;
4513 tra = ca + mri->width / 2.0 * mri->x_a * mri->xsize - mri->height / 2.0 *
4514 mri->y_a * mri->ysize;
4515 trs = cs + mri->width / 2.0 * mri->x_s * mri->xsize - mri->height / 2.0 *
4516 mri->y_s * mri->ysize;
4517
4518 brr = cr + mri->width / 2.0 * mri->x_r * mri->xsize + mri->height / 2.0 *
4519 mri->y_r * mri->ysize;
4520 bra = ca + mri->width / 2.0 * mri->x_a * mri->xsize + mri->height / 2.0 *
4521 mri->y_a * mri->ysize;
4522 brs = cs + mri->width / 2.0 * mri->x_s * mri->xsize + mri->height / 2.0 *
4523 mri->y_s * mri->ysize;
4524
4525 time(&time_now);
4526
4527 //fprintf(fp, "bhdr generated by %s\n", Progname);
4528 //fprintf(fp, "%s\n", ctime(&time_now));
4529 //fprintf(fp, "\n");
4530 #endif
4531
4532 fprintf(fp, " cols: %d\n", mri->width);
4533 fprintf(fp, " rows: %d\n", mri->height);
4534 fprintf(fp, " nslices: %d\n", mri->depth);
4535 fprintf(fp, " n_time_points: %d\n", mri->nframes);
4536 fprintf(fp, " slice_thick: %f\n", mri->zsize);
4537 fprintf(fp, " top_left_r: %f\n", tlr);
4538 fprintf(fp, " top_left_a: %f\n", tla);
4539 fprintf(fp, " top_left_s: %f\n", tls);
4540 fprintf(fp, " top_right_r: %f\n", trr);
4541 fprintf(fp, " top_right_a: %f\n", tra);
4542 fprintf(fp, " top_right_s: %f\n", trs);
4543 fprintf(fp, "bottom_right_r: %f\n", brr);
4544 fprintf(fp, "bottom_right_a: %f\n", bra);
4545 fprintf(fp, "bottom_right_s: %f\n", brs);
4546 fprintf(fp, " normal_r: %f\n", nr);
4547 fprintf(fp, " normal_a: %f\n", na);
4548 fprintf(fp, " normal_s: %f\n", ns);
4549 fprintf(fp, " image_te: %f\n", mri->te);
4550 fprintf(fp, " image_tr: %f\n", mri->tr/1000.0); // convert to sec
4551 fprintf(fp, " image_ti: %f\n", mri->ti);
4552 fprintf(fp, " flip_angle: %f\n", mri->flip_angle);
4553
4554 return(NO_ERROR);
4555
4556 } /* end write_bhdr() */
4557
4558 /*------------------------------------------------------*/
4559 int read_bhdr(MRI *mri, FILE *fp)
4560 {
4561
4562 char line[STRLEN];
4563 char *l;
4564 float tlr=0.;
4565 float tla=0.;
4566 float tls=0.; /* top left coordinates */
4567 float trr=0.;
4568 float tra=0.;
4569 float trs=0.; /* top right coordinates */
4570 float brr=0.;
4571 float bra=0.;
4572 float brs=0.; /* bottom right coordinates */
4573 float xr=0.;
4574 float xa=0.;
4575 float xs=0.;
4576 float yr=0.;
4577 float ya=0.;
4578 float ys=0.;
4579 MATRIX *T, *CRSCenter, *RASCenter;
4580
4581 while(1){ // don't use "while (!feof(fp))"
4582
4583 /* --- read the line --- */
4584 fgets(line, STRLEN, fp);
4585
4586 if (feof(fp)) // wow, it was beyound the end of the file. get out.
4587 break;
4588
4589 /* --- remove the newline --- */
4590 if(line[strlen(line)-1] == '\n')
4591 line[strlen(line)-1] = '\0';
4592
4593 /* --- skip the initial spaces --- */
4594 for(l = line;isspace((int)(*l));l++);
4595
4596 /* --- get the varible name and value(s) --- */
4597 if(strlen(l) > 0){
4598 if(strncmp(l, "cols: ", 6) == 0)
4599 sscanf(l, "%*s %d", &mri->width);
4600 else if(strncmp(l, "rows: ", 6) == 0)
4601 sscanf(l, "%*s %d", &mri->height);
4602 else if(strncmp(l, "nslices: ", 9) == 0)
4603 sscanf(l, "%*s %d", &mri->depth);
4604 else if(strncmp(l, "n_time_points: ", 15) == 0)
4605 sscanf(l, "%*s %d", &mri->nframes);
4606 else if(strncmp(l, "slice_thick: ", 13) == 0)
4607 sscanf(l, "%*s %f", &mri->zsize);
4608 else if(strncmp(l, "image_te: ", 10) == 0)
4609 sscanf(l, "%*s %f", &mri->te);
4610 else if(strncmp(l, "image_tr: ", 10) == 0){
4611 sscanf(l, "%*s %f", &mri->tr);
4612 mri->tr = 1000.0 * mri->tr; // convert from sec to msec
4613 }
4614 else if(strncmp(l, "image_ti: ", 10) == 0)
4615 sscanf(l, "%*s %f", &mri->ti);
4616 else if(strncmp(l, "flip_angle: ", 10) == 0)
4617 sscanf(l, "%*s %lf", &mri->flip_angle);
4618 else if(strncmp(l, "top_left_r: ", 12) == 0)
4619 sscanf(l, "%*s %g", &tlr);
4620 else if(strncmp(l, "top_left_a: ", 12) == 0)
4621 sscanf(l, "%*s %g", &tla);
4622 else if(strncmp(l, "top_left_s: ", 12) == 0)
4623 sscanf(l, "%*s %g", &tls);
4624 else if(strncmp(l, "top_right_r: ", 13) == 0)
4625 sscanf(l, "%*s %g", &trr);
4626 else if(strncmp(l, "top_right_a: ", 13) == 0)
4627 sscanf(l, "%*s %g", &tra);
4628 else if(strncmp(l, "top_right_s: ", 13) == 0)
4629 sscanf(l, "%*s %g", &trs);
4630 else if(strncmp(l, "bottom_right_r: ", 16) == 0)
4631 sscanf(l, "%*s %g", &brr);
4632 else if(strncmp(l, "bottom_right_a: ", 16) == 0)
4633 sscanf(l, "%*s %g", &bra);
4634 else if(strncmp(l, "bottom_right_s: ", 16) == 0)
4635 sscanf(l, "%*s %g", &brs);
4636 else if(strncmp(l, "normal_r: ", 10) == 0)
4637 sscanf(l, "%*s %g", &mri->z_r);
4638 else if(strncmp(l, "normal_a: ", 10) == 0)
4639 sscanf(l, "%*s %g", &mri->z_a);
4640 else if(strncmp(l, "normal_s: ", 10) == 0)
4641 sscanf(l, "%*s %g", &mri->z_s);
4642 else { /* --- ignore it --- */ }
4643 }
4644 } /* end while(!feof()) */
4645 // forget to close file
4646 fclose(fp);
4647
4648 // vox to ras matrix is
4649 //
4650 // Xr*Sx Yr*Sy Zr*Sz Tr
4651 // Xa*Sx Ya*Sy Za*Sz Ta
4652 // Xs*Sx Ys*Sy Zs*Sz Ts
4653 // 0 0 0 1
4654 //
4655 // Therefore
4656 //
4657 // trr = Xr*Sx*W + Tr, tlr = Tr
4658 // tra = Xa*Sx*W + Ta, tla = Ta
4659 // trs = Xs*Sx*W + Ts, tls = Ts
4660 //
4661 // Thus
4662 //
4663 // Sx = sqrt ( ((trr-tlr)/W)^2 + ((tra-tla)/W)^2 + ((trs-tls)/W)^2)
4664 // since Xr^2 + Xa^2 + Xs^2 = 1
4665 // Xr = (trr-tlr)/(W*Sx)
4666 // Xa = (tra-tla)/(W*Sx)
4667 // Xs = (trs-tls)/(W*Sx)
4668 //
4669 // Similar things for others
4670 //
4671 xr = (trr - tlr) / mri->width;
4672 xa = (tra - tla) / mri->width;
4673 xs = (trs - tls) / mri->width;
4674 mri->xsize = sqrt(xr*xr + xa*xa + xs*xs);
4675 if (mri->xsize) // avoid nan
4676 {
4677 mri->x_r = xr / mri->xsize;
4678 mri->x_a = xa / mri->xsize;
4679 mri->x_s = xs / mri->xsize;
4680 }
4681 else // fake values
4682 {
4683 mri->xsize = 1;
4684 mri->x_r = -1;
4685 mri->x_a = 0;
4686 mri->x_s = 0;
4687 }
4688 yr = (brr - trr) / mri->height;
4689 ya = (bra - tra) / mri->height;
4690 ys = (brs - trs) / mri->height;
4691 mri->ysize = sqrt(yr*yr + ya*ya + ys*ys);
4692 if (mri->ysize) // avoid nan
4693 {
4694 mri->y_r = yr / mri->ysize;
4695 mri->y_a = ya / mri->ysize;
4696 mri->y_s = ys / mri->ysize;
4697 }
4698 else // fake values
4699 {
4700 mri->ysize = 1;
4701 mri->y_r = 0;
4702 mri->y_a = 0;
4703 mri->y_s = -1;
4704 }
4705 T = MRIxfmCRS2XYZ(mri,0);
4706
4707 T->rptr[1][4] = tlr;
4708 T->rptr[2][4] = tla;
4709 T->rptr[3][4] = tls;
4710
4711 //printf("------- read_bhdr: T ---------\n");
4712 //MatrixPrint(stdout,T);
4713 //printf("------------------------------\n");
4714
4715 CRSCenter = MatrixAlloc(4,1,MATRIX_REAL);
4716 CRSCenter->rptr[1][1] = (mri->width)/2.0;
4717 CRSCenter->rptr[2][1] = (mri->height)/2.0;
4718 CRSCenter->rptr[3][1] = (mri->depth)/2.0;
4719 CRSCenter->rptr[4][1] = 1;
4720
4721 RASCenter = MatrixMultiply(T,CRSCenter,NULL);
4722 mri->c_r = RASCenter->rptr[1][1];
4723 mri->c_a = RASCenter->rptr[2][1];
4724 mri->c_s = RASCenter->rptr[3][1];
4725
4726 MatrixFree(&T);
4727 MatrixFree(&CRSCenter);
4728 MatrixFree(&RASCenter);
4729
4730 #if 0
4731 /* This computation of the center is incorrect because TL is the center of
4732 the first voxel (not the edge of the FOV). TR and BR are actually
4733 outside of the FOV. */
4734 mri->c_r =
4735 (brr + tlr) / 2.0 + (mri->depth - 1) * mri->z_r * mri->zsize / 2.0 ;
4736 mri->c_a =
4737 (bra + tla) / 2.0 + (mri->depth - 1) * mri->z_a * mri->zsize / 2.0 ;
4738 mri->c_s =
4739 (brs + tls) / 2.0 + (mri->depth - 1) * mri->z_s * mri->zsize / 2.0 ;
4740 #endif
4741
4742 mri->ras_good_flag = 1;
4743
4744 mri->thick = mri->zsize;
4745 mri->ps = mri->xsize;
4746
4747 return(NO_ERROR);
4748
4749 } /* end read_bhdr() */
4750
4751
4752 static MRI *genesisRead(char *fname, int read_volume)
4753 {
4754 char fname_format[STRLEN];
4755 char fname_format2[STRLEN];
4756 char fname_dir[STRLEN];
4757 char fname_base[STRLEN];
4758 char *c;
4759 MRI *mri = NULL;
4760 int im_init;
4761 int im_low, im_high;
4762 int im_low2, im_high2;
4763 char fname_use[STRLEN];
4764 char temp_string[STRLEN];
4765 FILE *fp;
4766 int width, height;
4767 int pixel_data_offset;
4768 int image_header_offset;
4769 float tl_r, tl_a, tl_s;
4770 float tr_r, tr_a, tr_s;
4771 float br_r, br_a, br_s;
4772 float c_r, c_a, c_s;
4773 float n_r, n_a, n_s;
4774 float xlength, ylength, zlength;
4775 int i, y;
4776 MRI *header;
4777 float xfov, yfov, zfov;
4778 float nlength;
4779 int twoformats = 0, odd_only, even_only ;
4780
4781 odd_only = even_only = 0 ;
4782 if (getenv("GE_ODD"))
4783 {
4784 odd_only = 1 ;
4785 printf("only using odd # GE files\n") ;
4786 }
4787 else if (getenv("GE_EVEN"))
4788 {
4789 even_only = 1 ;
4790 printf("only using even # GE files\n") ;
4791 }
4792
4793 /* ----- check the first (passed) file ----- */
4794 if(!FileExists(fname))
4795 {
4796 errno = 0;
4797 ErrorReturn
4798 (NULL,
4799 (ERROR_BADFILE, "genesisRead(): error opening file %s", fname));
4800 }
4801
4802 /* ----- split the file name into name and directory ----- */
4803 c = strrchr(fname, '/');
4804 if(c == NULL)
4805 {
4806 fname_dir[0] = '\0';
4807 strcpy(fname_base, fname);
4808 }
4809 else
4810 {
4811 strncpy(fname_dir, fname, (c - fname + 1));
4812 fname_dir[c-fname+1] = '\0';
4813 strcpy(fname_base, c+1);
4814 }
4815
4816 /* ----- derive the file name format (for sprintf) ----- */
4817 // this one fix fname_format only
4818 if(strncmp(fname_base, "I.", 2) == 0)
4819 {
4820 twoformats = 0;
4821 im_init = atoi(&fname_base[2]);
4822 sprintf(fname_format, "I.%%03d");
4823 }
4824 // this one fix both fname_format and fname_format2
4825 else if(strlen(fname_base) >= 3) /* avoid core dumps below... */
4826 {
4827 twoformats = 1;
4828 c = &fname_base[strlen(fname_base)-3];
4829 if(strcmp(c, ".MR") == 0)
4830 {
4831 *c = '\0';
4832 for(c--;isdigit(*c) && c >= fname_base;c--);
4833 c++;
4834 im_init = atoi(c);
4835 *c = '\0';
4836 // this is too quick to assume of this type
4837 // another type %s%%03d.MR" must be examined
4838 sprintf(fname_format, "%s%%d.MR", fname_base);
4839 sprintf(fname_format2, "%s%%03d.MR", fname_base);
4840 }
4841 else
4842 {
4843 errno = 0;
4844 ErrorReturn
4845 (NULL,
4846 (ERROR_BADPARM,
4847 "genesisRead(): can't determine file name format for %s",
4848 fname));
4849 }
4850 }
4851 else
4852 {
4853 errno = 0;
4854 ErrorReturn
4855 (NULL,
4856 (ERROR_BADPARM,
4857 "genesisRead(): can't determine file name format for %s", fname));
4858 }
4859
4860 if (strlen(fname_format) != 0)
4861 {
4862 strcpy(temp_string, fname_format);
4863 sprintf(fname_format, "%s%s", fname_dir, temp_string);
4864 printf("fname_format : %s\n", fname_format);
4865 }
4866 if (strlen(fname_format2) != 0)
4867 {
4868 strcpy(temp_string, fname_format2);
4869 sprintf(fname_format2, "%s%s", fname_dir, temp_string);
4870 printf("fname_format2 : %s\n", fname_format2);
4871 }
4872 /* ----- find the low and high files ----- */
4873 if (odd_only || even_only)
4874 {
4875 if ((odd_only && ISEVEN(im_init)) ||
4876 (even_only && ISODD(im_init)))
4877 im_init++ ;
4878 im_low = im_init;
4879 do
4880 {
4881 im_low -=2 ;
4882 sprintf(fname_use, fname_format, im_low);
4883 } while(FileExists(fname_use));
4884 im_low += 2 ;
4885
4886 im_high = im_init;
4887 do
4888 {
4889 im_high += 2 ;
4890 sprintf(fname_use, fname_format, im_high);
4891 } while(FileExists(fname_use));
4892 im_high -=2;
4893 }
4894 else
4895 {
4896 im_low = im_init;
4897 do
4898 {
4899 im_low--;
4900 sprintf(fname_use, fname_format, im_low);
4901 } while(FileExists(fname_use));
4902 im_low++;
4903
4904 im_high = im_init;
4905 do
4906 {
4907 im_high++;
4908 sprintf(fname_use, fname_format, im_high);
4909 } while(FileExists(fname_use));
4910 im_high--;
4911 }
4912
4913 if (twoformats)
4914 {
4915 // now test fname_format2
4916 im_low2 = im_init;
4917 do
4918 {
4919 im_low2--;
4920 sprintf(fname_use, fname_format2, im_low2);
4921 } while(FileExists(fname_use));
4922 im_low2++;
4923
4924 im_high2 = im_init;
4925 do
4926 {
4927 im_high2++;
4928 sprintf(fname_use, fname_format2, im_high2);
4929 } while(FileExists(fname_use));
4930 im_high2--;
4931 }
4932 else
4933 {
4934 im_high2 = im_low2 = 0;
4935 }
4936 // now decide which one to pick
4937 if ((im_high2-im_low2) > (im_high-im_low))
4938 {
4939 // we have to use fname_format2
4940 strcpy(fname_format, fname_format2);
4941 im_high = im_high2;
4942 im_low = im_low2;
4943 }
4944 // otherwise the same
4945
4946 /* ----- allocate the mri structure ----- */
4947 header = MRIallocHeader(1, 1, 1, MRI_SHORT);
4948
4949 if (odd_only || even_only)
4950 header->depth = (im_high - im_low)/2 + 1;
4951 else
4952 header->depth = im_high - im_low + 1;
4953 header->imnr0 = 1;
4954 header->imnr1 = header->depth;
4955
4956 /* ----- get the header information from the first file ----- */
4957 sprintf(fname_use, fname_format, im_low);
4958 if((fp = fopen(fname_use, "r")) == NULL)
4959 {
4960 MRIfree(&header);
4961 errno = 0;
4962 ErrorReturn
4963 (NULL,
4964 (ERROR_BADFILE, "genesisRead(): error opening file %s\n", fname_use));
4965 }
4966
4967 fseek(fp, 8, SEEK_SET);
4968 fread(&width, 4, 1, fp);
4969 width = orderIntBytes(width);
4970 fread(&height, 4, 1, fp);
4971 height = orderIntBytes(height);
4972 fseek(fp, 148, SEEK_SET);
4973 fread(&image_header_offset, 4, 1, fp);
4974 image_header_offset = orderIntBytes(image_header_offset);
4975
4976 header->width = width;
4977 header->height = height;
4978
4979 strcpy(header->fname, fname);
4980
4981 fseek(fp, image_header_offset + 26, SEEK_SET);
4982 fread(&(header->thick), 4, 1, fp);
4983 header->thick = orderFloatBytes(header->thick);
4984 header->zsize = header->thick;
4985
4986 fseek(fp, image_header_offset + 50, SEEK_SET);
4987 fread(&(header->xsize), 4, 1, fp);
4988 header->xsize = orderFloatBytes(header->xsize);
4989 fread(&(header->ysize), 4, 1, fp);
4990 header->ysize = orderFloatBytes(header->ysize);
4991 header->ps = header->xsize;
4992
4993 /* all in micro-seconds */
4994 #define MICROSECONDS_PER_MILLISECOND 1e3
4995 fseek(fp, image_header_offset + 194, SEEK_SET);
4996 header->tr = freadInt(fp)/MICROSECONDS_PER_MILLISECOND ;
4997 fseek(fp, image_header_offset + 198, SEEK_SET);
4998 header->ti = freadInt(fp)/MICROSECONDS_PER_MILLISECOND ;
4999 fseek(fp, image_header_offset + 202, SEEK_SET);
5000 header->te = freadInt(fp)/MICROSECONDS_PER_MILLISECOND ;
5001 fseek(fp, image_header_offset + 254, SEEK_SET);
5002 header->flip_angle = RADIANS(freadShort(fp)) ; /* was in degrees */
5003 fseek(fp, image_header_offset + 210, SEEK_SET); // # of echoes
5004 header->nframes = freadShort(fp) ;
5005 if (header->nframes > 1)
5006 {
5007 printf("multi-echo genesis file detected (%d echoes)...\n",
5008 header->nframes) ;
5009 }
5010 else if (header->nframes == 0)
5011 {
5012 printf("zero frames specified in file - setting to 1\n") ;
5013 header->nframes = 1 ;
5014 }
5015
5016
5017 fseek(fp, image_header_offset + 130, SEEK_SET);
5018 fread(&c_r, 4, 1, fp); c_r = orderFloatBytes(c_r);
5019 fread(&c_a, 4, 1, fp); c_a = orderFloatBytes(c_a);
5020 fread(&c_s, 4, 1, fp); c_s = orderFloatBytes(c_s);
5021 fread(&n_r, 4, 1, fp); n_r = orderFloatBytes(n_r);
5022 fread(&n_a, 4, 1, fp); n_a = orderFloatBytes(n_a);
5023 fread(&n_s, 4, 1, fp); n_s = orderFloatBytes(n_s);
5024 fread(&tl_r, 4, 1, fp); tl_r = orderFloatBytes(tl_r);
5025 fread(&tl_a, 4, 1, fp); tl_a = orderFloatBytes(tl_a);
5026 fread(&tl_s, 4, 1, fp); tl_s = orderFloatBytes(tl_s);
5027 fread(&tr_r, 4, 1, fp); tr_r = orderFloatBytes(tr_r);
5028 fread(&tr_a, 4, 1, fp); tr_a = orderFloatBytes(tr_a);
5029 fread(&tr_s, 4, 1, fp); tr_s = orderFloatBytes(tr_s);
5030 fread(&br_r, 4, 1, fp); br_r = orderFloatBytes(br_r);
5031 fread(&br_a, 4, 1, fp); br_a = orderFloatBytes(br_a);
5032 fread(&br_s, 4, 1, fp); br_s = orderFloatBytes(br_s);
5033
5034 nlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
5035 n_r = n_r / nlength;
5036 n_a = n_a / nlength;
5037 n_s = n_s / nlength;
5038
5039 if (getenv("KILLIANY_SWAP") != NULL)
5040 {
5041 printf("WARNING - swapping normal direction!\n") ;
5042 n_a *= -1 ;
5043 }
5044
5045 header->x_r = (tr_r - tl_r);
5046 header->x_a = (tr_a - tl_a);
5047 header->x_s = (tr_s - tl_s);
5048 header->y_r = (br_r - tr_r);
5049 header->y_a = (br_a - tr_a);
5050 header->y_s = (br_s - tr_s);
5051
5052 /* --- normalize -- the normal vector from the file
5053 should have length 1, but just in case... --- */
5054 xlength =
5055 sqrt(header->x_r*header->x_r +
5056 header->x_a*header->x_a +
5057 header->x_s*header->x_s);
5058 ylength =
5059 sqrt(header->y_r*header->y_r +
5060 header->y_a*header->y_a +
5061 header->y_s*header->y_s);
5062 zlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
5063
5064 header->x_r = header->x_r / xlength;
5065 header->x_a = header->x_a / xlength;
5066 header->x_s = header->x_s / xlength;
5067 header->y_r = header->y_r / ylength;
5068 header->y_a = header->y_a / ylength;
5069 header->y_s = header->y_s / ylength;
5070 header->z_r = n_r / zlength;
5071 header->z_a = n_a / zlength;
5072 header->z_s = n_s / zlength;
5073
5074 header->c_r = (tl_r + br_r) / 2.0 + n_r *
5075 header->zsize * (header->depth - 1.0) / 2.0;
5076 header->c_a = (tl_a + br_a) / 2.0 + n_a *
5077 header->zsize * (header->depth - 1.0) / 2.0;
5078 header->c_s = (tl_s + br_s) / 2.0 + n_s *
5079 header->zsize * (header->depth - 1.0) / 2.0;
5080
5081 header->ras_good_flag = 1;
5082
5083 header->xend = header->xsize * header->width / 2;
5084 header->xstart = -header->xend;
5085 header->yend = header->ysize * header->height / 2;
5086 header->ystart = -header->yend;
5087 header->zend = header->zsize * header->depth / 2;
5088 header->zstart = -header->zend;
5089
5090 xfov = header->xend - header->xstart;
5091 yfov = header->yend - header->ystart;
5092 zfov = header->zend - header->zstart;
5093
5094 header->fov =
5095 (xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
5096
5097 fclose(fp);
5098
5099 if(read_volume)
5100 mri = MRIallocSequence(header->width, header->height,
5101 header->depth, header->type, header->nframes);
5102 else
5103 mri = MRIallocHeader(header->width, header->height,
5104 header->depth, header->type);
5105
5106 MRIcopyHeader(header, mri);
5107 MRIfree(&header);
5108
5109 /* ----- read the volume if required ----- */
5110 if(read_volume)
5111 {
5112 int slice, frame ;
5113 for(slice = 0, i = im_low;
5114 i <= im_high;
5115 (odd_only || even_only) ? i+=2 : i++, slice++)
5116 {
5117 frame = (i-im_low) % mri->nframes ;
5118 sprintf(fname_use, fname_format, i);
5119 if((fp = fopen(fname_use, "r")) == NULL)
5120 {
5121 MRIfree(&mri);
5122 errno = 0;
5123 ErrorReturn(NULL,
5124 (ERROR_BADFILE,
5125 "genesisRead(): error opening file %s", fname_use));
5126 }
5127
5128 fseek(fp, 4, SEEK_SET);
5129 fread(&pixel_data_offset, 4, 1, fp);
5130 pixel_data_offset = orderIntBytes(pixel_data_offset);
5131 fseek(fp, pixel_data_offset, SEEK_SET);
5132
5133 for(y = 0;y < mri->height;y++)
5134 {
5135 if(fread(&MRISseq_vox(mri, 0, y, slice, frame),
5136 sizeof(short), mri->width, fp) != mri->width)
5137 {
5138 fclose(fp);
5139 MRIfree(&mri);
5140 errno = 0;
5141 ErrorReturn
5142 (NULL,
5143 (ERROR_BADFILE,
5144 "genesisRead(): error reading from file file %s",
5145 fname_use));
5146 }
5147 #if (BYTE_ORDER == LITTLE_ENDIAN)
5148 //swab(mri->slices[slice][y],
5149 // mri->slices[slice][y], 2 * mri->width);
5150 swab(&MRISseq_vox(mri, 0, y, slice, frame),
5151 &MRISseq_vox(mri, 0, y, slice, frame),
5152 sizeof(short) * mri->width);
5153 #endif
5154 }
5155
5156 fclose(fp);
5157
5158 if (frame != (mri->nframes-1))
5159 slice-- ;
5160 }
5161
5162 }
5163
5164 return(mri);
5165
5166 } /* end genesisRead() */
5167
5168 static MRI *gelxRead(char *fname, int read_volume)
5169 {
5170
5171 char fname_format[STRLEN];
5172 char fname_dir[STRLEN];
5173 char fname_base[STRLEN];
5174 char *c;
5175 MRI *mri = NULL;
5176 int im_init;
5177 int im_low, im_high;
5178 char fname_use[STRLEN];
5179 char temp_string[STRLEN];
5180 FILE *fp;
5181 int width, height;
5182 float tl_r, tl_a, tl_s;
5183 float tr_r, tr_a, tr_s;
5184 float br_r, br_a, br_s;
5185 float c_r, c_a, c_s;
5186 float n_r, n_a, n_s;
5187 float xlength, ylength, zlength;
5188 int i, y;
5189 int ecount, scount, icount;
5190 int good_flag;
5191 MRI *header;
5192 float xfov, yfov, zfov;
5193
5194 /* ----- check the first (passed) file ----- */
5195 if(!FileExists(fname))
5196 {
5197 errno = 0;
5198 ErrorReturn
5199 (NULL, (ERROR_BADFILE, "genesisRead(): error opening file %s", fname));
5200 }
5201
5202 /* ----- split the file name into name and directory ----- */
5203 c = strrchr(fname, '/');
5204 if(c == NULL)
5205 {
5206 fname_dir[0] = '\0';
5207 strcpy(fname_base, fname);
5208 }
5209 else
5210 {
5211 strncpy(fname_dir, fname, (c - fname + 1));
5212 fname_dir[c-fname+1] = '\0';
5213 strcpy(fname_base, c+1);
5214 }
5215
5216 ecount = scount = icount = 0;
5217 good_flag = TRUE;
5218 for(c = fname_base;*c != '\0';c++)
5219 {
5220 if(*c == 'e')
5221 ecount++;
5222 else if(*c == 's')
5223 scount++;
5224 else if(*c == 'i')
5225 icount++;
5226 else if(!isdigit(*c))
5227 good_flag = FALSE;
5228 }
5229 if(good_flag && ecount == 1 && scount == 1 && icount == 1)
5230 {
5231 c = strrchr(fname_base, 'i');
5232 im_init = atoi(c+1);
5233 *c = '\0';
5234 sprintf(fname_format, "%si%%d", fname_base);
5235 }
5236 else
5237 {
5238 errno = 0;
5239 ErrorReturn
5240 (NULL,
5241 (ERROR_BADPARM,
5242 "genesisRead(): can't determine file name format for %s", fname));
5243 }
5244
5245 strcpy(temp_string, fname_format);
5246 sprintf(fname_format, "%s%s", fname_dir, temp_string);
5247
5248 /* ----- find the low and high files ----- */
5249 im_low = im_init;
5250 do
5251 {
5252 im_low--;
5253 sprintf(fname_use, fname_format, im_low);
5254 } while(FileExists(fname_use));
5255 im_low++;
5256
5257 im_high = im_init;
5258 do
5259 {
5260 im_high++;
5261 sprintf(fname_use, fname_format, im_high);
5262 } while(FileExists(fname_use));
5263 im_high--;
5264
5265 /* ----- allocate the mri structure ----- */
5266 header = MRIallocHeader(1, 1, 1, MRI_SHORT);
5267
5268 header->depth = im_high - im_low + 1;
5269 header->imnr0 = 1;
5270 header->imnr1 = header->depth;
5271
5272 /* ----- get the header information from the first file ----- */
5273 sprintf(fname_use, fname_format, im_low);
5274 if((fp = fopen(fname_use, "r")) == NULL)
5275 {
5276 errno = 0;
5277 ErrorReturn
5278 (NULL,
5279 (ERROR_BADFILE, "genesisRead(): error opening file %s\n", fname_use));
5280 }
5281
5282 fseek(fp, 3236, SEEK_SET);
5283 fread(&width, 4, 1, fp); width = orderIntBytes(width);
5284 fread(&height, 4, 1, fp); height = orderIntBytes(height);
5285 header->width = width;
5286 header->height = height;
5287
5288 strcpy(header->fname, fname);
5289
5290 fseek(fp, 2184 + 28, SEEK_SET);
5291 fread(&(header->thick), 4, 1, fp);
5292 header->thick = orderFloatBytes(header->thick);
5293 header->zsize = header->thick;
5294
5295 fseek(fp, 2184 + 52, SEEK_SET);
5296 fread(&(header->xsize), 4, 1, fp);
5297 header->xsize = orderFloatBytes(header->xsize);
5298 fread(&(header->ysize), 4, 1, fp);
5299 header->ysize = orderFloatBytes(header->ysize);
5300 header->ps = header->xsize;
5301
5302 fseek(fp, 2184 + 136, SEEK_SET);
5303 fread(&c_r, 4, 1, fp); c_r = orderFloatBytes(c_r);
5304 fread(&c_a, 4, 1, fp); c_a = orderFloatBytes(c_a);
5305 fread(&c_s, 4, 1, fp); c_s = orderFloatBytes(c_s);
5306 fread(&n_r, 4, 1, fp); n_r = orderFloatBytes(n_r);
5307 fread(&n_a, 4, 1, fp); n_a = orderFloatBytes(n_a);
5308 fread(&n_s, 4, 1, fp); n_s = orderFloatBytes(n_s);
5309 fread(&tl_r, 4, 1, fp); tl_r = orderFloatBytes(tl_r);
5310 fread(&tl_a, 4, 1, fp); tl_a = orderFloatBytes(tl_a);
5311 fread(&tl_s, 4, 1, fp); tl_s = orderFloatBytes(tl_s);
5312 fread(&tr_r, 4, 1, fp); tr_r = orderFloatBytes(tr_r);
5313 fread(&tr_a, 4, 1, fp); tr_a = orderFloatBytes(tr_a);
5314 fread(&tr_s, 4, 1, fp); tr_s = orderFloatBytes(tr_s);
5315 fread(&br_r, 4, 1, fp); br_r = orderFloatBytes(br_r);
5316 fread(&br_a, 4, 1, fp); br_a = orderFloatBytes(br_a);
5317 fread(&br_s, 4, 1, fp); br_s = orderFloatBytes(br_s);
5318
5319 header->x_r = (tr_r - tl_r);
5320 header->x_a = (tr_a - tl_a);
5321 header->x_s = (tr_s - tl_s);
5322 header->y_r = (br_r - tr_r);
5323 header->y_a = (br_a - tr_a);
5324 header->y_s = (br_s - tr_s);
5325
5326 /* --- normalize -- the normal vector from the file
5327 should have length 1, but just in case... --- */
5328 xlength = sqrt(header->x_r*header->x_r +
5329 header->x_a*header->x_a +
5330 header->x_s*header->x_s);
5331 ylength = sqrt(header->y_r*header->y_r +
5332 header->y_a*header->y_a +
5333 header->y_s*header->y_s);
5334 zlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
5335
5336 header->x_r = header->x_r / xlength;
5337 header->x_a = header->x_a / xlength;
5338 header->x_s = header->x_s / xlength;
5339 header->y_r = header->y_r / ylength;
5340 header->y_a = header->y_a / ylength;
5341 header->y_s = header->y_s / ylength;
5342 header->z_r = n_r / zlength;
5343 header->z_a = n_a / zlength;
5344 header->z_s = n_s / zlength;
5345
5346 header->c_r = (tl_r + br_r) / 2.0 + n_r *
5347 header->zsize * (header->depth - 1.0) / 2.0;
5348 header->c_a = (tl_a + br_a) / 2.0 + n_a *
5349 header->zsize * (header->depth - 1.0) / 2.0;
5350 header->c_s = (tl_s + br_s) / 2.0 + n_s *
5351 header->zsize * (header->depth - 1.0) / 2.0;
5352
5353 header->ras_good_flag = 1;
5354
5355 header->xend = header->xsize * header->width / 2;
5356 header->xstart = -header->xend;
5357 header->yend = header->ysize * header->height / 2;
5358 header->ystart = -header->yend;
5359 header->zend = header->zsize * header->depth / 2;
5360 header->zstart = -header->zend;
5361
5362 xfov = header->xend - header->xstart;
5363 yfov = header->yend - header->ystart;
5364 zfov = header->zend - header->zstart;
5365
5366 header->fov =
5367 ( xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
5368
5369 fclose(fp);
5370
5371 if(read_volume)
5372 mri = MRIalloc
5373 (header->width, header->height, header->depth, MRI_SHORT);
5374 else
5375 mri = MRIallocHeader
5376 (header->width, header->height, header->depth, MRI_SHORT);
5377
5378 MRIcopyHeader(header, mri);
5379 MRIfree(&header);
5380
5381 /* ----- read the volume if required ----- */
5382 if(read_volume)
5383 {
5384 for(i = im_low;i <= im_high; i++)
5385 {
5386
5387 sprintf(fname_use, fname_format, i);
5388 if((fp = fopen(fname_use, "r")) == NULL)
5389 {
5390 MRIfree(&mri);
5391 errno = 0;
5392 ErrorReturn
5393 (NULL,
5394 (ERROR_BADFILE,
5395 "genesisRead(): error opening file %s", fname_use));
5396 }
5397
5398 fseek(fp, 8432, SEEK_SET);
5399
5400 for(y = 0;y < mri->height;y++)
5401 {
5402 if(fread(mri->slices[i-im_low][y], 2, mri->width, fp) !=
5403 mri->width)
5404 {
5405 fclose(fp);
5406 MRIfree(&mri);
5407 errno = 0;
5408 ErrorReturn
5409 (NULL,
5410 (ERROR_BADFILE,
5411 "genesisRead(): error reading from file file %s",
5412 fname_use));
5413 }
5414 #if (BYTE_ORDER == LITTLE_ENDIAN)
5415 swab(mri->slices[i-im_low][y], mri->slices[i-im_low][y],
5416 2 * mri->width);
5417 #endif
5418 }
5419
5420 fclose(fp);
5421
5422 }
5423
5424 }
5425
5426 return(mri);
5427
5428 } /* end gelxRead() */
5429
5430 /*----------------------------------------------------------------------
5431 GetSPMStartFrame() - gets an environment variable called
5432 SPM_START_FRAME and uses its value as the number of the first frame
5433 for an SPM series. If this variable does not exist, then uses 1.
5434 ----------------------------------------------------------------------*/
5435 int GetSPMStartFrame(void)
5436 {
5437 char *s;
5438 int startframe;
5439 s = getenv("SPM_START_FRAME");
5440 if(s == NULL) return(1);
5441 sscanf(s,"%d",&startframe);
5442 printf("Using env var SPM_START_FRAME = %d\n",startframe);
5443
5444 return(startframe);
5445 }
5446
5447
5448 /*-------------------------------------------------------------------------
5449 CountAnalyzeFiles() - counts the number analyze files associated with
5450 the given analyze file name. The name can take several forms:
5451 stem.img - a single file
5452 stem - stem. If nzpad < 0, then an extension of .img is implied.
5453 Otherwise, it looks for a series of files named stemXXX.img
5454 where XXX is a zero padded integer. The width of the padding
5455 is controlled by nzpad. The stem is returned in ppstem (unless
5456 ppstem == NULL).
5457 Note: the files must actually exist.
5458 -------------------------------------------------------------------------*/
5459 int CountAnalyzeFiles(char *analyzefname, int nzpad, char **ppstem)
5460 {
5461 int len, ncopy;
5462 char *stem, fmt[1000], fname[1000];
5463 int nfiles, keepcounting, startframe;
5464 FILE *fp;
5465 nfiles = 0;
5466
5467 len = strlen(analyzefname);
5468
5469 /* Determine whether the file name has a .img extension */
5470 if(len > 4 && strcmp(&(analyzefname[len-4]),".img")==0){
5471 ncopy = len-4;
5472 nfiles = 1;
5473 if(nzpad >= 0) {
5474 printf("ERROR: CountAnalyzeFiles: file with .img extension specified "
5475 " with zero pad variable.\n");
5476 return(-1);
5477 }
5478 }
5479 else {
5480 ncopy = len;
5481 if(nzpad < 0) nfiles = 1;
5482 }
5483
5484 /* Get the stem (ie, everything without the .img */
5485 stem = (char *) calloc(len+1,sizeof(char));
5486 memcpy(stem,analyzefname,ncopy);
5487
5488 if(ppstem != NULL) *ppstem = stem;
5489
5490 /* If there's only one file, check that it's there */
5491 if(nfiles == 1){
5492 sprintf(fname,"%s.img",stem);
5493 if(ppstem == NULL) free(stem);
5494 fp = fopen(fname,"r");
5495 if(fp == NULL) return(0);
5496 fclose(fp);
5497 return(1);
5498 }
5499
5500 /* If there are multiple files, count them, starting at 1 */
5501 sprintf(fmt,"%s%%0%dd.img",stem,nzpad);
5502 keepcounting = 1;
5503 startframe = GetSPMStartFrame();
5504 nfiles = 0;
5505 while(keepcounting){
5506 sprintf(fname,fmt,nfiles+startframe);
5507 fp = fopen(fname,"r");
5508 if(fp == NULL) keepcounting = 0;
5509 else {
5510 fclose(fp);
5511 nfiles ++;
5512 }
5513 }
5514
5515 if(ppstem == NULL) free(stem);
5516 return(nfiles);
5517 }
5518 /*-------------------------------------------------------------------------*/
5519 static int DumpAnalyzeHeader(FILE *fp, dsr *hdr)
5520 {
5521 fprintf(fp,"Header Key\n");
5522 fprintf(fp," sizeof_hdr %d\n",hdr->hk.sizeof_hdr);
5523 fprintf(fp," data_type %s\n",hdr->hk.data_type);
5524 fprintf(fp," db_name %s\n",hdr->hk.db_name);
5525 fprintf(fp," extents %d\n",hdr->hk.extents);
5526 fprintf(fp," session_error %d\n",hdr->hk.session_error);
5527 fprintf(fp," regular %c\n",hdr->hk.regular);
5528 fprintf(fp," hkey_un0 %c\n",hdr->hk.hkey_un0);
5529 fprintf(fp,"Image Dimension \n");
5530 fprintf(fp," dim %d %d %d %d %d %d %d %d \n",
5531 hdr->dime.dim[0],hdr->dime.dim[1],hdr->dime.dim[2],hdr->dime.dim[3],
5532 hdr->dime.dim[4],hdr->dime.dim[5],hdr->dime.dim[6],hdr->dime.dim[7]);
5533 fprintf(fp," pixdim %f %f %f %f %f %f %f %f \n",
5534 hdr->dime.pixdim[0],hdr->dime.pixdim[1],hdr->dime.pixdim[2],
5535 hdr->dime.pixdim[3],hdr->dime.pixdim[4],hdr->dime.pixdim[5],
5536 hdr->dime.pixdim[6],hdr->dime.pixdim[7]);
5537 fprintf(fp," vox_units %s\n",hdr->dime.vox_units);
5538 fprintf(fp," cal_units %s\n",hdr->dime.cal_units);
5539 fprintf(fp," datatype %d\n",hdr->dime.datatype);
5540 fprintf(fp," bitpix %d\n",hdr->dime.bitpix);
5541 fprintf(fp," glmax %g\n",(float)hdr->dime.glmax);
5542 fprintf(fp," glmin %g\n",(float)hdr->dime.glmin);
5543 fprintf(fp," orient %d\n",hdr->hist.orient);
5544
5545 return(0);
5546
5547 }
5548 /*-------------------------------------------------------------------------*/
5549 static dsr *ReadAnalyzeHeader(char *hdrfile, int *swap,
5550 int *mritype, int *bytes_per_voxel)
5551 {
5552 FILE *fp;
5553 dsr *hdr;
5554
5555 /* Open and read the header */
5556 fp = fopen(hdrfile,"r");
5557 if(fp == NULL){
5558 printf("ERROR: ReadAnalyzeHeader(): cannot open %s\n",hdrfile);
5559 return(NULL);
5560 }
5561
5562 /* Read the header file */
5563 hdr = (dsr *) calloc(1, sizeof(dsr));
5564 fread(hdr, sizeof(dsr), 1, fp);
5565 fclose(fp);
5566
5567 *swap = 0;
5568 if(hdr->hk.sizeof_hdr != sizeof(dsr))
5569 {
5570 *swap = 1;
5571 swap_analyze_header(hdr);
5572 }
5573
5574 if(hdr->dime.datatype == DT_UNSIGNED_CHAR)
5575 {
5576 *mritype = MRI_UCHAR;
5577 *bytes_per_voxel = 1;
5578 }
5579 else if(hdr->dime.datatype == DT_SIGNED_SHORT)
5580 {
5581 *mritype = MRI_SHORT;
5582 *bytes_per_voxel = 2;
5583 }
5584 else if(hdr->dime.datatype == DT_SIGNED_INT)
5585 {
5586 *mritype = MRI_INT;
5587 *bytes_per_voxel = 4;
5588 }
5589 else if(hdr->dime.datatype == DT_FLOAT)
5590 {
5591 *mritype = MRI_FLOAT;
5592 *bytes_per_voxel = 4;
5593 }
5594 else if(hdr->dime.datatype == DT_DOUBLE)
5595 {
5596 *mritype = MRI_FLOAT;
5597 *bytes_per_voxel = 8;
5598 }
5599 else
5600 {
5601 free(hdr);
5602 errno = 0;
5603 ErrorReturn(NULL, (ERROR_UNSUPPORTED, "ReadAnalyzeHeader: "
5604 "unsupported data type %d", hdr->dime.datatype));
5605 }
5606
5607 return(hdr);
5608 }
5609
5610
5611 /*-------------------------------------------------------------------------
5612 analyzeRead() - see the end of file for the old (pre-10/11/01) analyzeRead().
5613 The fname can take one of several forms.
5614 -------------------------------------------------------------------------*/
5615 static MRI *analyzeRead(char *fname, int read_volume)
5616 {
5617 extern int N_Zero_Pad_Input;
5618 int nfiles, k, nread;
5619 char *stem;
5620 char imgfile[1000], hdrfile[1000], matfile[1000], fmt[1000];
5621 char *buf;
5622 FILE *fp;
5623 dsr *hdr;
5624 int swap, mritype, bytes_per_voxel, cantreadmatfile=0;
5625 int ncols, nrows, nslcs, nframes, row, slice, frame, startframe;
5626 MATRIX *T=NULL, *PcrsCenter, *PxyzCenter, *T1=NULL, *Q=NULL;
5627 MRI *mri;
5628 float min, max;
5629 struct stat StatBuf;
5630 int nv,nreal;
5631 char direction[64];
5632 int signX, signY, signZ;
5633
5634 fp = NULL;
5635 startframe = GetSPMStartFrame();
5636
5637 /* Count the number of files associated with this file name,
5638 and get the stem. */
5639 nfiles = CountAnalyzeFiles(fname,N_Zero_Pad_Input,&stem);
5640
5641 /* If there are no files, return NULL */
5642 if(nfiles < 0) return(NULL);
5643 if(nfiles == 0){
5644 printf("ERROR: analyzeRead(): cannot find any files for %s\n",fname);
5645 return(NULL);
5646 }
5647 //printf("INFO: analyzeRead(): found %d files for %s\n",nfiles,fname);
5648
5649 /* Create file names of header and mat files */
5650 if(N_Zero_Pad_Input > -1){
5651 sprintf(fmt,"%s%%0%dd.%%s",stem,N_Zero_Pad_Input);
5652 sprintf(hdrfile,fmt,startframe,"hdr");
5653 sprintf(matfile,fmt,startframe,"mat");
5654 }
5655 else{
5656 sprintf(hdrfile,"%s.hdr",stem);
5657 sprintf(matfile,"%s.mat",stem);
5658 sprintf(imgfile,"%s.img",stem);
5659 }
5660
5661 hdr = ReadAnalyzeHeader(hdrfile, &swap, &mritype, &bytes_per_voxel);
5662 if(hdr == NULL) return(NULL);
5663 if (Gdiag & DIAG_VERBOSE_ON) DumpAnalyzeHeader(stdout,hdr);
5664
5665 /* Get the number of frames as either the fourth dimension or
5666 the number of files. */
5667 if(nfiles == 1){
5668 nframes = hdr->dime.dim[4];
5669 if(nframes==0) nframes = 1;
5670 }
5671 else nframes = nfiles;
5672
5673 ncols = hdr->dime.dim[1];
5674 nrows = hdr->dime.dim[2];
5675 nslcs = hdr->dime.dim[3];
5676 nv = ncols*nrows*nslcs*nframes;
5677
5678 if( ncols == 1 || nrows == 1 ) {
5679 lstat(imgfile, &StatBuf);
5680 if(StatBuf.st_size != nv*bytes_per_voxel){
5681 nreal = StatBuf.st_size / bytes_per_voxel;
5682 if(ncols ==1) nrows = nreal;
5683 else ncols = nreal;
5684 printf("INFO: %s really has %d rows/cols\n",imgfile,nreal);
5685 }
5686 }
5687
5688 /* Alloc the Header and/or Volume */
5689 if(read_volume)
5690 mri = MRIallocSequence(ncols, nrows, nslcs, mritype, nframes);
5691 else {
5692 mri = MRIallocHeader(ncols, nrows, nslcs, mritype);
5693 mri->nframes = nframes;
5694 }
5695
5696 /* Load Variables into header */
5697 mri->xsize = fabs(hdr->dime.pixdim[1]); /* col res */
5698 mri->ysize = fabs(hdr->dime.pixdim[2]); /* row res */
5699 mri->zsize = fabs(hdr->dime.pixdim[3]); /* slice res */
5700 mri->tr = 1000*hdr->dime.pixdim[4]; /* time res */
5701
5702 signX = (hdr->dime.pixdim[1] > 0) ? 1 : -1;
5703 signY = (hdr->dime.pixdim[2] > 0) ? 1 : -1;
5704 signZ = (hdr->dime.pixdim[3] > 0) ? 1 : -1;
5705
5706 /* Read the matfile, if there */
5707 if(FileExists(matfile)){
5708 T1 = MatlabRead(matfile); // orientation info
5709 if(T1 == NULL){
5710 printf
5711 ("WARNING: analyzeRead(): matfile %s exists but could not read ... \n",
5712 matfile);
5713 printf(" may not be matlab4 mat file ... proceeding without it.\n");
5714 fflush(stdout);
5715 cantreadmatfile=1;
5716 }
5717 else{
5718 /* Convert from 1-based to 0-based */
5719 Q = MtxCRS1toCRS0(Q);
5720 T = MatrixMultiply(T1,Q,T);
5721 //printf("------- Analyze Input Matrix (zero-based) --------\n");
5722 //MatrixPrint(stdout,T);
5723 //printf("-------------------------------------\n");
5724 mri->ras_good_flag = 1;
5725 MatrixFree(&Q);
5726 MatrixFree(&T1);
5727 }
5728 }
5729 if(! FileExists(matfile) || cantreadmatfile){
5730 /* when not found, it is a fun exercise. */
5731 /* see http://wideman-one.com/gw/brain/analyze/formatdoc.htm */
5732 /* for amgibuities. */
5733 /* I will follow his advise */
5734 /* hist.orient Mayo name Voxel[Index0, Index1, Index2] */
5735 /* Index0 Index1 Index2 */
5736 /* 0 transverse unflipped R-L P-A I-S LAS */
5737 /* 3 transverse flipped R-L A-P I-S LPS */
5738 /* 1 coronal unflipped R-L I-S P-A LSA */
5739 /* 4 coronal flipped R-L S-I P-A LIA */
5740 /* 2 sagittal unflipped P-A I-S R-L ASL */
5741 /* 5 sagittal flipped P-A S-I R-L AIL */
5742 // P->A I->S L->R
5743
5744 /* FLIRT distributes analyze format image which has a marked LR */
5745 /* in fls/etc/standard/avg152T1_LR-marked.img. The convention */
5746 /* is tested with this image for hdr->hist.orient== 0. */
5747 /* note that flirt image has negative pixdim[1], but their software */
5748 /* ignores the sign anyway. */
5749 if (hdr->hist.orient==0) /* x = - r, y = a, z = s */
5750 {
5751 strcpy(direction, "transverse unflipped (default)");
5752 T = MatrixAlloc(4, 4, MATRIX_REAL);
5753 T->rptr[1][1] = -mri->xsize;
5754 T->rptr[2][2] = mri->ysize;
5755 T->rptr[3][3] = mri->zsize;
5756 T->rptr[1][4] = mri->xsize*(mri->width/2.0);
5757 T->rptr[2][4] = -mri->ysize*(mri->height/2.0);
5758 T->rptr[3][4] = -mri->zsize*(mri->depth/2.0);
5759 T->rptr[4][4] = 1.;
5760 }
5761 else if (hdr->hist.orient==1) /* x = -r, y = s, z = a */
5762 {
5763 strcpy(direction, "coronal unflipped");
5764 T = MatrixAlloc(4, 4, MATRIX_REAL);
5765 T->rptr[1][1] = -mri->xsize;
5766 T->rptr[2][3] = mri->zsize;
5767 T->rptr[3][2] = mri->ysize;
5768 T->rptr[1][4] = mri->xsize*(mri->width/2.0);
5769 T->rptr[2][4] = -mri->zsize*(mri->depth/2.0);
5770 T->rptr[3][4] = -mri->ysize*(mri->height/2.0);
5771 T->rptr[4][4] = 1.;
5772 }
5773 else if (hdr->hist.orient==2) /* x = a, y = s, z = -r */
5774 {
5775 strcpy(direction, "sagittal unflipped");
5776 T = MatrixAlloc(4, 4, MATRIX_REAL);
5777 T->rptr[1][3] = -mri->zsize;
5778 T->rptr[2][1] = mri->xsize;
5779 T->rptr[3][2] = mri->ysize;
5780 T->rptr[1][4] = mri->zsize*(mri->depth/2.0);
5781 T->rptr[2][4] = -mri->xsize*(mri->width/2.0);
5782 T->rptr[3][4] = -mri->ysize*(mri->height/2.0);
5783 T->rptr[4][4] = 1.;
5784 }
5785 else if (hdr->hist.orient==3) /* x = -r, y = -a, z = s */
5786 {
5787 strcpy(direction, "transverse flipped");
5788 T = MatrixAlloc(4, 4, MATRIX_REAL);
5789 T->rptr[1][1] = -mri->xsize;
5790 T->rptr[2][2] = -mri->ysize;
5791 T->rptr[3][3] = mri->zsize;
5792 T->rptr[1][4] = mri->xsize*(mri->width/2.0);
5793 T->rptr[2][4] = mri->ysize*(mri->height/2.0);
5794 T->rptr[3][4] = -mri->zsize*(mri->depth/2.0);
5795 T->rptr[4][4] = 1.;
5796 }
5797 else if (hdr->hist.orient==4) /* x = -r, y = -s, z = a */
5798 {
5799 strcpy(direction, "coronal flipped");
5800 T = MatrixAlloc(4, 4, MATRIX_REAL);
5801 T->rptr[1][1] = -mri->xsize;
5802 T->rptr[2][3] = mri->zsize;
5803 T->rptr[3][2] = -mri->ysize;
5804 T->rptr[1][4] = mri->xsize*(mri->width/2.0);
5805 T->rptr[2][4] = -mri->zsize*(mri->depth/2.0);
5806 T->rptr[3][4] = mri->ysize*(mri->height/2.0);
5807 T->rptr[4][4] = 1.;
5808 }
5809 else if (hdr->hist.orient==5) /* x = a, y = -s, z = -r */
5810 {
5811 strcpy(direction, "sagittal flipped");
5812 T = MatrixAlloc(4, 4, MATRIX_REAL);
5813 T->rptr[1][3] = -mri->zsize;
5814 T->rptr[2][1] = mri->xsize;
5815 T->rptr[3][2] = -mri->ysize;
5816 T->rptr[1][4] = mri->zsize*(mri->depth/2.0);
5817 T->rptr[2][4] = -mri->xsize*(mri->width/2.0);
5818 T->rptr[3][4] = mri->ysize*(mri->height/2.0);
5819 T->rptr[4][4] = 1.;
5820 }
5821 if (hdr->hist.orient == -1){
5822 /* Unknown, so assume: x = -r, y = -a, z = s */
5823 strcpy(direction, "transverse flipped");
5824 T = MatrixAlloc(4, 4, MATRIX_REAL);
5825 T->rptr[1][1] = -mri->xsize;
5826 T->rptr[2][2] = -mri->ysize;
5827 T->rptr[3][3] = mri->zsize;
5828 T->rptr[1][4] = mri->xsize*(mri->width/2.0);
5829 T->rptr[2][4] = mri->ysize*(mri->height/2.0);
5830 T->rptr[3][4] = -mri->zsize*(mri->depth/2.0);
5831 T->rptr[4][4] = 1.;
5832 mri->ras_good_flag = 0;
5833 fprintf(stderr,
5834 "WARNING: could not find %s file for direction cosine info.\n"
5835 "WARNING: Analyze 7.5 hdr->hist.orient value = -1, not valid.\n"
5836 "WARNING: assuming %s\n",matfile, direction);
5837 }
5838 else{
5839 mri->ras_good_flag = 1;
5840 fprintf
5841 (stderr,
5842 "-----------------------------------------------------------------\n"
5843 "INFO: could not find %s file for direction cosine info.\n"
5844 "INFO: use Analyze 7.5 hdr->hist.orient value: %d, %s.\n"
5845 "INFO: if not valid, please provide the information in %s file\n"
5846 "-----------------------------------------------------------------\n",
5847 matfile, hdr->hist.orient, direction, matfile
5848 );
5849 }
5850 }
5851
5852 /* ---- Assign the Geometric Paramaters -----*/
5853 mri->x_r = T->rptr[1][1]/mri->xsize;
5854 mri->x_a = T->rptr[2][1]/mri->xsize;
5855 mri->x_s = T->rptr[3][1]/mri->xsize;
5856
5857 /* Row Direction Cosines */
5858 mri->y_r = T->rptr[1][2]/mri->ysize;
5859 mri->y_a = T->rptr[2][2]/mri->ysize;
5860 mri->y_s = T->rptr[3][2]/mri->ysize;
5861
5862 /* Slice Direction Cosines */
5863 mri->z_r = T->rptr[1][3]/mri->zsize;
5864 mri->z_a = T->rptr[2][3]/mri->zsize;
5865 mri->z_s = T->rptr[3][3]/mri->zsize;
5866
5867 /* Center of the FOV in voxels */
5868 PcrsCenter = MatrixAlloc(4, 1, MATRIX_REAL);
5869 PcrsCenter->rptr[1][1] = mri->width/2.0;
5870 PcrsCenter->rptr[2][1] = mri->height/2.0;
5871 PcrsCenter->rptr[3][1] = mri->depth/2.0;
5872 PcrsCenter->rptr[4][1] = 1.0;
5873
5874 /* Center of the FOV in XYZ */
5875 PxyzCenter = MatrixMultiply(T,PcrsCenter,NULL);
5876 mri->c_r = PxyzCenter->rptr[1][1];
5877 mri->c_a = PxyzCenter->rptr[2][1];
5878 mri->c_s = PxyzCenter->rptr[3][1];
5879
5880 MatrixFree(&PcrsCenter);
5881 MatrixFree(&PxyzCenter);
5882 MatrixFree(&T);
5883
5884 if(!read_volume) return(mri);
5885
5886 /* Alloc the maximum amount of memory that a row could need */
5887 buf = (char *)malloc(mri->width * 8);
5888
5889 /* Open the one file, if there is one file */
5890 if(nfiles == 1){
5891 fp = fopen(imgfile,"r");
5892 if(fp == NULL){
5893 printf("ERROR: analyzeRead(): could not open %s\n",imgfile);
5894 MRIfree(&mri);
5895 return(NULL);
5896 }
5897 fseek(fp, (int)(hdr->dime.vox_offset), SEEK_SET);
5898 }
5899
5900 /*--------------------- Frame Loop --------------------------*/
5901 for(frame = 0; frame < nframes; frame++){
5902
5903 /* Open the frame file if there is more than one file */
5904 if(N_Zero_Pad_Input > -1){
5905 sprintf(imgfile,fmt,frame+startframe,"img");
5906 fp = fopen(imgfile,"r");
5907 if(fp == NULL){
5908 printf("ERROR: analyzeRead(): could not open %s\n",imgfile);
5909 MRIfree(&mri);
5910 return(NULL);
5911 }
5912 fseek(fp, (int)(hdr->dime.vox_offset), SEEK_SET);
5913 }
5914
5915 /* ----------- Slice Loop ----------------*/
5916 for(slice = 0;slice < mri->depth; slice++){
5917 k = slice + mri->depth * frame;
5918
5919 /* --------- Row Loop ------------------*/
5920 for(row = 0; row < mri->height; row++)
5921 {
5922
5923 nread = fread(buf, bytes_per_voxel, mri->width, fp);
5924 if(nread != mri->width){
5925 errno = 0;
5926 printf("frame = %d, slice = %d, k=%d, row = %d\n",
5927 frame,slice,k,row);
5928 printf("nread = %d, nexpected = %d\n",nread,mri->width);
5929 fflush(stdout);
5930 MRIfree(&mri);free(buf);fclose(fp);
5931 ErrorReturn(NULL, (ERROR_BADFILE, "analyzeRead2(): error reading "
5932 "from file %s\n", imgfile));
5933 }
5934
5935 if(swap){
5936 if(bytes_per_voxel == 2)
5937 byteswapbufshort((void*)buf,bytes_per_voxel*mri->width);
5938 if(bytes_per_voxel == 4)
5939 byteswapbuffloat((void*)buf,bytes_per_voxel*mri->width);
5940 //nflip(buf, bytes_per_voxel, mri->width); /* byte swap */
5941 }
5942
5943 memcpy
5944 (mri->slices[k][row], buf, bytes_per_voxel*mri->width); /*copy*/
5945
5946 } /* End Row Loop */
5947 } /* End Slice Loop */
5948
5949 /* Close file if each frame is in a separate file */
5950 if(N_Zero_Pad_Input > -1) fclose(fp);
5951
5952 } /* End Frame Loop */
5953
5954 if(N_Zero_Pad_Input < 0) fclose(fp);
5955
5956 free(buf);
5957 free(hdr);
5958
5959 MRIlimits(mri,&min,&max);
5960 printf("INFO: analyzeRead(): min = %g, max = %g\n",min,max);
5961
5962 return(mri);
5963 }
5964
5965 /*---------------------------------------------------------------
5966 analyzeWrite() - writes out a volume in SPM analyze format. If the
5967 file name has a .img extension, then the first frame is stored into
5968 the given file name. If it does not include the extension, then the
5969 volume is saved as a series of frame files using fname as a base
5970 followed by the zero-padded frame number (see analyzeWriteSeries). A
5971 series can be saved from mri_convert by specifying the basename and
5972 adding "--out_type spm". See also analyzeWrite4D(). DNG
5973 ---------------------------------------------------------------*/
5974 static int analyzeWrite(MRI *mri, char *fname)
5975 {
5976 int len;
5977 int error_value;
5978
5979 /* Check for .img extension */
5980 len = strlen(fname);
5981 if(len > 4){
5982 if(fname[len-4] == '.' && fname[len-3] == 'i' &&
5983 fname[len-2] == 'm' && fname[len-1] == 'g' ){
5984 /* There is a trailing .img - save frame 0 into fname */
5985 error_value = analyzeWriteFrame(mri, fname, 0);
5986 return(error_value);
5987 }
5988 }
5989 /* There is no trailing .img - save as a series */
5990 error_value = analyzeWriteSeries(mri, fname);
5991 return(error_value);
5992 }
5993 /*---------------------------------------------------------------
5994 analyzeWriteFrame() - this used to be analyzeWrite() but was modified
5995 by DNG to be able to save a particular frame so that it could be
5996 used to write out an entire series.
5997 ---------------------------------------------------------------*/
5998 static void printDirCos(MRI *mri)
5999 {
6000 fprintf(stderr, "Direction cosines for %s are:\n", mri->fname);
6001 fprintf(stderr, " x_r = %8.4f, y_r = %8.4f, z_r = %8.4f, c_r = %10.4f\n",
6002 mri->x_r, mri->y_r, mri->z_r, mri->c_r);
6003 fprintf(stderr, " x_a = %8.4f, y_a = %8.4f, z_a = %8.4f, c_a = %10.4f\n",
6004 mri->x_a, mri->y_a, mri->z_a, mri->c_a);
6005 fprintf(stderr, " x_s = %8.4f, y_s = %8.4f, z_s = %8.4f, c_s = %10.4f\n",
6006 mri->x_s, mri->y_s, mri->z_s, mri->c_s);
6007 }
6008
6009 static int analyzeWriteFrame(MRI *mri, char *fname, int frame)
6010 {
6011 dsr hdr;
6012 float max, min, det;
6013 MATRIX *T, *invT;
6014 char hdr_fname[STRLEN];
6015 char mat_fname[STRLEN];
6016 char *c;
6017 FILE *fp;
6018 int error_value;
6019 int i, j, k;
6020 int bytes_per_voxel;
6021 short i1, i2, i3;
6022 int shortmax;
6023 char *orientname[7] =
6024 { "transverse unflipped", "coronal unflipped", "sagittal unflipped",
6025 "transverse flipped", "coronal flipped", "sagittal flipped",
6026 "unknown" };
6027
6028 if(frame >= mri->nframes){
6029 fprintf(stderr,"ERROR: analyzeWriteFrame(): frame number (%d) exceeds "
6030 "number of frames (%d)\n",frame,mri->nframes);
6031 return(1);
6032 }
6033
6034 shortmax = (int)(pow(2.0,15.0));
6035 if(mri->width > shortmax){
6036 printf("ANALYZE FORMAT ERROR: ncols %d in volume exceeds %d\n",
6037 mri->width,shortmax);
6038 exit(1);
6039 }
6040 if(mri->height > shortmax){
6041 printf("ANALYZE FORMAT ERROR: nrows %d in volume exceeds %d\n",
6042 mri->height,shortmax);
6043 exit(1);
6044 }
6045 if(mri->depth > shortmax){
6046 printf("ANALYZE FORMAT ERROR: nslices %d in volume exceeds %d\n",
6047 mri->depth,shortmax);
6048 exit(1);
6049 }
6050 if(mri->nframes > shortmax){
6051 printf("ANALYZE FORMAT ERROR: nframes %d in volume exceeds %d\n",
6052 mri->nframes,shortmax);
6053 exit(1);
6054 }
6055
6056 c = strrchr(fname, '.');
6057 if(c == NULL)
6058 {
6059 errno = 0;
6060 ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM, "analyzeWriteFrame(): "
6061 "bad file name %s", fname));
6062 }
6063 if(strcmp(c, ".img") != 0)
6064 {
6065 errno = 0;
6066 ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM, "analyzeWriteFrame(): "
6067 "bad file name %s", fname));
6068 }
6069
6070 strcpy(hdr_fname, fname);
6071 sprintf(hdr_fname + (c - fname), ".hdr");
6072
6073 strcpy(mat_fname, fname);
6074 sprintf(mat_fname + (c - fname), ".mat");
6075
6076 memset(&hdr, 0x00, sizeof(hdr));
6077
6078 hdr.hk.sizeof_hdr = sizeof(hdr);
6079
6080 hdr.dime.vox_offset = 0.0;
6081
6082 if(mri->type == MRI_UCHAR)
6083 {
6084 hdr.dime.datatype = DT_UNSIGNED_CHAR;
6085 bytes_per_voxel = 1;
6086 }
6087 else if(mri->type == MRI_SHORT)
6088 {
6089 hdr.dime.datatype = DT_SIGNED_SHORT;
6090 bytes_per_voxel = 2;
6091 }
6092 /* --- assuming long and int are identical --- */
6093 else if(mri->type == MRI_INT || mri->type == MRI_LONG)
6094 {
6095 hdr.dime.datatype = DT_SIGNED_INT;
6096 bytes_per_voxel = 4;
6097 }
6098 else if(mri->type == MRI_FLOAT)
6099 {
6100 hdr.dime.datatype = DT_FLOAT;
6101 bytes_per_voxel = 4;
6102 }
6103 else
6104 {
6105 errno = 0;
6106 ErrorReturn
6107 (ERROR_BADPARM,
6108 (ERROR_BADPARM,
6109 "analyzeWriteFrame(): bad data type %d", mri->type));
6110 }
6111
6112 /* Added by DNG 10/2/01 */
6113 hdr.dime.dim[0] = 4; /* number of dimensions */
6114 hdr.dime.dim[4] = 1; /* time */
6115 hdr.dime.pixdim[4] = mri->tr/1000.0; // convert to sec
6116 hdr.dime.bitpix = 8*bytes_per_voxel;
6117 memcpy(hdr.dime.vox_units,"mm\0",3);
6118 /*----------------------------*/
6119
6120 hdr.dime.dim[1] = mri->width; /* ncols */
6121 hdr.dime.dim[2] = mri->height; /* nrows */
6122 hdr.dime.dim[3] = mri->depth; /* nslices */
6123
6124 hdr.dime.pixdim[1] = mri->xsize; /* col res */
6125 hdr.dime.pixdim[2] = mri->ysize; /* row res */
6126 hdr.dime.pixdim[3] = mri->zsize; /* slice res */
6127
6128 MRIlimits(mri, &min, &max);
6129 hdr.dime.glmin = (int)min;
6130 hdr.dime.glmax = (int)max;
6131
6132 /* Construct the matrix to convert CRS to XYZ, assuming
6133 that CRS is 1-based */
6134 T = MRIxfmCRS2XYZ(mri,1);
6135
6136 det = MatrixDeterminant(T) ;
6137 if(det == 0){
6138 printf("WARNING: cannot determine volume orientation, "
6139 "assuming identity. It's ok if the output is a surface.\n");
6140 T = MatrixIdentity(4, T) ;
6141 if(mri->xsize > 0) T->rptr[1][1] = mri->xsize;
6142 if(mri->ysize > 0) T->rptr[2][2] = mri->ysize;
6143 if(mri->zsize > 0) T->rptr[3][3] = mri->zsize;
6144 }
6145 if(frame == 0){
6146 printf("Analyze Output Matrix\n");
6147 MatrixPrint(stdout,T);
6148 printf("--------------------\n");
6149 }
6150
6151 /* ----- write the matrix to the .mat file ----- */
6152 error_value = MatlabWrite(T, mat_fname, "M");
6153 if(error_value != NO_ERROR) return(error_value);
6154
6155 /* Compute inverse ot T (converts from XYZ to CRS) */
6156 invT = MatrixInverse(T,NULL);
6157 /* If the inverse cannot be computed, set to the identity */
6158 if(invT == NULL) invT = MatrixIdentity(4,NULL);
6159
6160 /* Load the CRS into the originator field as 3 shorts for SPM */
6161 /* These come from the last column of invT */
6162 i1 = (short)(rint(*MATRIX_RELT(invT, 1, 4)));
6163 memcpy( (&hdr.hist.originator[0]), &i1, sizeof(short));
6164 i2 = (short)(rint(*MATRIX_RELT(invT, 2, 4)));
6165 memcpy( (&hdr.hist.originator[0] + sizeof(short)), &i2, sizeof(short));
6166 i3 = (short)(rint(*MATRIX_RELT(invT, 3, 4)));
6167 memcpy( (&hdr.hist.originator[0] + 2*sizeof(short)), &i3, sizeof(short));
6168
6169 MatrixFree(&T);
6170 MatrixFree(&invT);
6171
6172 /* Set the hist.orient field -- this is not always correct */
6173 /* see http://wideman-one.com/gw/brain/analyze/formatdoc.htm */
6174 if(fabs(mri->z_s) > fabs(mri->z_r) && fabs(mri->z_s) > fabs(mri->z_a))
6175 {
6176 // Transverse: Superior/Inferior > both Right and Anterior
6177 if (mri->x_r < 0 && mri->y_a > 0 && mri->z_s > 0)
6178 hdr.hist.orient = 0; // transverse unflipped LAS
6179 else if (mri->x_r < 0 && mri->y_a <0 && mri->z_s > 0)
6180 hdr.hist.orient = 3; // transverse flipped LPS
6181 else
6182 {
6183 fprintf
6184 (stderr,
6185 "No such orientation specified in Analyze7.5. "
6186 "Set orient to 0.\n");
6187 fprintf(stderr, "Not a problem as long as you use the .mat file.\n");
6188 printDirCos(mri);
6189 hdr.hist.orient = 0;
6190 }
6191 }
6192 if(fabs(mri->z_a) > fabs(mri->z_r) && fabs(mri->z_a) > fabs(mri->z_s))
6193 {
6194 // Cor: Anterior/Post > both Right and Superior
6195 if(mri->x_r < 0 && mri->y_s > 0 && mri->z_a > 0)
6196 hdr.hist.orient = 1; // cor unflipped LSA
6197 else if (mri->x_r <0 && mri->y_s < 0 && mri->z_a > 0)
6198 hdr.hist.orient = 4; // cor flipped LIA
6199 else
6200 {
6201 fprintf(stderr,
6202 "No such orientation specified in Analyze7.5. "
6203 "Set orient to 0\n");
6204 printDirCos(mri);
6205 hdr.hist.orient = 0;
6206 }
6207 }
6208 if(fabs(mri->z_r) > fabs(mri->z_a) && fabs(mri->z_r) > fabs(mri->z_s))
6209 {
6210 // Sag: Righ/Left > both Anterior and Superior
6211 if(mri->x_a > 0 && mri->y_s > 0 && mri->z_r < 0)
6212 hdr.hist.orient = 2; // sag unflipped ASL
6213 else if (mri->x_a > 0 && mri->y_s < 0 && mri->z_r < 0)
6214 hdr.hist.orient = 5; // sag flipped AIL
6215 else
6216 {
6217 fprintf
6218 (stderr,
6219 "No such orientation specified in Analyze7.5. Set orient to 0\n");
6220 printDirCos(mri);
6221 hdr.hist.orient = 0;
6222 }
6223 }
6224 printf("INFO: set hdr.hist.orient to '%s'\n",
6225 orientname[(int) hdr.hist.orient]);
6226
6227 /* ----- open the header file ----- */
6228 if((fp = fopen(hdr_fname, "w")) == NULL){
6229 errno = 0;
6230 ErrorReturn
6231 (ERROR_BADFILE,
6232 (ERROR_BADFILE,
6233 "analyzeWriteFrame(): error opening file %s for writing",
6234 hdr_fname));
6235 }
6236 /* ----- write the header ----- */
6237 /* should write element-by-element */
6238 if(fwrite(&hdr, sizeof(hdr), 1, fp) != 1){
6239 errno = 0;
6240 ErrorReturn
6241 (ERROR_BADFILE,
6242 (ERROR_BADFILE,
6243 "analyzeWriteFrame(): error writing to file %s", hdr_fname));
6244 }
6245 fclose(fp);
6246
6247 /* ----- open the data file ----- */
6248 if((fp = fopen(fname, "w")) == NULL){
6249 errno = 0;
6250 ErrorReturn
6251 (ERROR_BADFILE,
6252 (ERROR_BADFILE,
6253 "analyzeWriteFrame(): error opening file %s for writing", fname));
6254 }
6255
6256 /* ----- write the data ----- */
6257 for(i = 0;i < mri->depth;i++){
6258 /* this is the change to make it save a given frame */
6259 k = i + mri->depth*frame;
6260 for(j = 0;j < mri->height;j++){
6261 if(fwrite(mri->slices[k][j], bytes_per_voxel, mri->width, fp) !=
6262 mri->width)
6263 {
6264 errno = 0;
6265 ErrorReturn(ERROR_BADFILE, (ERROR_BADFILE, "analyzeWriteFrame(): "
6266 " error writing to file %s",
6267 fname));
6268 } /* end if */
6269 } /* end row loop */
6270 } /* end col loop */
6271
6272 fclose(fp);
6273
6274 return(0);
6275
6276 } /* end analyzeWriteFrame() */
6277
6278 /*-------------------------------------------------------------*/
6279 static int analyzeWriteSeries(MRI *mri, char *fname)
6280 {
6281 extern int N_Zero_Pad_Output;
6282 int frame;
6283 int err;
6284 char framename[STRLEN];
6285 char spmnamefmt[STRLEN];
6286
6287 /* NOTE: This function assumes that fname does not have a .img extension. */
6288
6289 /* N_Zero_Pad_Output is a global variable used to control the name of */
6290 /* files in successive frames within the series. It can be set from */
6291 /* mri_convert using "--spmnzeropad N" where N is the width of the pad. */
6292 if(N_Zero_Pad_Output < 0) N_Zero_Pad_Output = 3;
6293
6294 /* Create the format string used to create the filename for each frame. */
6295 /* The frame file name format will be fname%0Nd.img where N is the amount */
6296 /* of zero padding. The (padded) frame numbers will go from 1 to nframes. */
6297 sprintf(spmnamefmt,"%%s%%0%dd.img",N_Zero_Pad_Output);
6298
6299 /* loop over slices */
6300 for(frame = 0; frame < mri->nframes; frame ++){
6301 sprintf(framename,spmnamefmt,fname,frame+1);
6302 //printf("%3d %s\n",frame,framename);
6303 err = analyzeWriteFrame(mri, framename, frame);
6304 if(err) return(err);
6305 }
6306
6307 return(0);
6308 }
6309
6310 /*---------------------------------------------------------------
6311 analyzeWrite4D() - saves data in analyze 4D format.
6312 ---------------------------------------------------------------*/
6313 static int analyzeWrite4D(MRI *mri, char *fname)
6314 {
6315 dsr hdr;
6316 float max, min, det;
6317 MATRIX *T, *invT;
6318 char hdr_fname[STRLEN];
6319 char mat_fname[STRLEN];
6320 char *c;
6321 FILE *fp;
6322 int error_value;
6323 int i, j, k, frame;
6324 int bytes_per_voxel;
6325 short i1, i2, i3;
6326 int shortmax;
6327
6328 c = strrchr(fname, '.');
6329 if(c == NULL)
6330 {
6331 errno = 0;
6332 ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM, "analyzeWrite4D(): "
6333 "bad file name %s", fname));
6334 }
6335 if(strcmp(c, ".img") != 0)
6336 {
6337 errno = 0;
6338 ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM, "analyzeWrite4D(): "
6339 "bad file name %s", fname));
6340 }
6341
6342 shortmax = (int)(pow(2.0,15.0));
6343 if(mri->width > shortmax)
6344 printf("ANALYZE FORMAT WARNING: ncols %d in volume exceeds %d\n",
6345 mri->width,shortmax);
6346 if(mri->height > shortmax)
6347 printf("ANALYZE FORMAT WARNING: nrows %d in volume exceeds %d\n",
6348 mri->height,shortmax);
6349 if(mri->depth > shortmax)
6350 printf("ANALYZE FORMAT WARNING: nslices %d in volume exceeds %d\n",
6351 mri->depth,shortmax);
6352 if(mri->nframes > shortmax)
6353 printf("ANALYZE FORMAT WARNING: nframes %d in volume exceeds %d\n",
6354 mri->nframes,shortmax);
6355
6356 /* create the file name for the header */
6357 strcpy(hdr_fname, fname);
6358 sprintf(hdr_fname + (c - fname), ".hdr");
6359
6360 /* create the file name for the mat file */
6361 strcpy(mat_fname, fname);
6362 sprintf(mat_fname + (c - fname), ".mat");
6363
6364 memset(&hdr, 0x00, sizeof(hdr));
6365 hdr.hk.sizeof_hdr = sizeof(hdr);
6366
6367 hdr.dime.vox_offset = 0.0;
6368
6369 if(mri->type == MRI_UCHAR)
6370 {
6371 hdr.dime.datatype = DT_UNSIGNED_CHAR;
6372 bytes_per_voxel = 1;
6373 }
6374 else if(mri->type == MRI_SHORT)
6375 {
6376 hdr.dime.datatype = DT_SIGNED_SHORT;
6377 bytes_per_voxel = 2;
6378 }
6379 /* --- assuming long and int are identical --- */
6380 else if(mri->type == MRI_INT || mri->type == MRI_LONG)
6381 {
6382 hdr.dime.datatype = DT_SIGNED_INT;
6383 bytes_per_voxel = 4;
6384 }
6385 else if(mri->type == MRI_FLOAT)
6386 {
6387 hdr.dime.datatype = DT_FLOAT;
6388 bytes_per_voxel = 4;
6389 }
6390 else
6391 {
6392 errno = 0;
6393 ErrorReturn
6394 (ERROR_BADPARM,
6395 (ERROR_BADPARM,
6396 "analyzeWrite4D(): bad data type %d", mri->type));
6397 }
6398
6399 hdr.dime.bitpix = 8*bytes_per_voxel;
6400 memcpy(hdr.dime.vox_units,"mm\0",3);
6401
6402 hdr.dime.dim[1] = mri->width; /* ncols */
6403 hdr.dime.dim[2] = mri->height; /* nrows */
6404 hdr.dime.dim[3] = mri->depth; /* nslices */
6405 hdr.dime.dim[4] = mri->nframes;
6406 hdr.dime.dim[0] = 4; /* flirt expects to be always 4 */
6407
6408 hdr.dime.pixdim[1] = mri->xsize; /* col res */
6409 hdr.dime.pixdim[2] = mri->ysize; /* row res */
6410 hdr.dime.pixdim[3] = mri->zsize; /* slice res */
6411 hdr.dime.pixdim[4] = mri->tr/1000.0; /* time res in sec*/
6412
6413 MRIlimits(mri, &min, &max);
6414 hdr.dime.glmin = (int)min;
6415 hdr.dime.glmax = (int)max;
6416
6417 /* Construct the matrix to convert CRS to XYZ, assuming
6418 that CRS is 1-based */
6419 T = MRIxfmCRS2XYZ(mri,1);
6420
6421 det = MatrixDeterminant(T) ;
6422 if(det == 0){
6423 printf("WARNING: cannot determine volume orientation, "
6424 "assuming identity. It's ok if the output is a surface.\n");
6425 T = MatrixIdentity(4, T) ;
6426 if(mri->xsize > 0) T->rptr[1][1] = mri->xsize;
6427 if(mri->ysize > 0) T->rptr[2][2] = mri->ysize;
6428 if(mri->zsize > 0) T->rptr[3][3] = mri->zsize;
6429 }
6430 printf("Analyze Output Matrix\n");
6431 MatrixPrint(stdout,T);
6432 printf("--------------------\n");
6433
6434
6435 /* Set the hist.orient field -- this is not always correct */
6436 /* see http://wideman-one.com/gw/brain/analyze/formatdoc.htm */
6437 if(fabs(mri->z_s) > fabs(mri->z_r) && fabs(mri->z_s) > fabs(mri->z_a)){
6438 // Transverse: Superior/Inferior > both Right and Anterior
6439 if(mri->x_r > 0) hdr.hist.orient = 0; // transverse unflipped
6440 else hdr.hist.orient = 3; // transverse flipped
6441 }
6442 if(fabs(mri->z_a) > fabs(mri->z_r) && fabs(mri->z_a) > fabs(mri->z_s)){
6443 // Cor: Anterior/Post > both Right and Superior
6444 if(mri->x_r > 0) hdr.hist.orient = 1; // cor unflipped
6445 else hdr.hist.orient = 4; // cor flipped
6446 }
6447 if(fabs(mri->z_r) > fabs(mri->z_a) && fabs(mri->z_r) > fabs(mri->z_s)){
6448 // Sag: Righ/Left > both Anterior and Superior
6449 if(mri->x_r > 0) hdr.hist.orient = 2; // sag unflipped
6450 else hdr.hist.orient = 5; // sag flipped
6451 }
6452 hdr.hist.orient = -1;
6453 printf("INFO: set hdr.hist.orient to %d\n",hdr.hist.orient);
6454
6455 /* ----- write T to the .mat file ----- */
6456 error_value = MatlabWrite(T, mat_fname, "M");
6457 if(error_value != NO_ERROR) return(error_value);
6458
6459 /* This matrix converts from XYZ to CRS */
6460 invT = MatrixInverse(T,NULL);
6461 /* If the inverse cannot be computed, set to the identity */
6462 if(invT == NULL) invT = MatrixIdentity(4,NULL);
6463
6464 /* Load the CRS into the originator field as 3 shorts for SPM */
6465 /* These come from the last column of invT */
6466 i1 = (short)(rint(*MATRIX_RELT(invT, 1, 4)));
6467 memcpy( (&hdr.hist.originator[0]), &i1, sizeof(short));
6468 i2 = (short)(rint(*MATRIX_RELT(invT, 2, 4)));
6469 memcpy( (&hdr.hist.originator[0] + sizeof(short)), &i2, sizeof(short));
6470 i3 = (short)(rint(*MATRIX_RELT(invT, 3, 4)));
6471 memcpy( (&hdr.hist.originator[0] + 2*sizeof(short)), &i3, sizeof(short));
6472
6473 MatrixFree(&T);
6474 MatrixFree(&invT);
6475
6476 /* ----- write the header ----- */
6477 if((fp = fopen(hdr_fname, "w")) == NULL)
6478 {
6479 errno = 0;
6480 ErrorReturn
6481 (ERROR_BADFILE,
6482 (ERROR_BADFILE,
6483 "analyzeWrite4D(): error opening file %s for writing",
6484 hdr_fname));
6485 }
6486 if(fwrite(&hdr, sizeof(hdr), 1, fp) != 1)
6487 {
6488 errno = 0;
6489 ErrorReturn
6490 (ERROR_BADFILE,
6491 (ERROR_BADFILE,
6492 "analyzeWrite4D(): error writing to file %s",
6493 hdr_fname));
6494 }
6495 fclose(fp);
6496
6497 /* ----- write the data ----- */
6498 if((fp = fopen(fname, "w")) == NULL)
6499 {
6500 errno = 0;
6501 ErrorReturn
6502 (ERROR_BADFILE,
6503 (ERROR_BADFILE,
6504 "analyzeWrite4D(): error opening file %s for writing",
6505 fname));
6506 }
6507
6508 for(frame = 0; frame < mri->nframes; frame ++){
6509 for(i = 0;i < mri->depth;i++){
6510 k = i + mri->depth*frame;
6511 for(j = 0;j < mri->height;j++){
6512 if(fwrite(mri->slices[k][j], bytes_per_voxel, mri->width, fp) !=
6513 mri->width){
6514 errno = 0;
6515 ErrorReturn(ERROR_BADFILE, (ERROR_BADFILE, "analyzeWrite4D(): "
6516 "error writing to file %s", fname));
6517 }
6518 }
6519 }
6520 }
6521
6522 fclose(fp);
6523
6524 return(0);
6525
6526 } /* end analyzeWrite4D() */
6527
6528 /*-------------------------------------------------------------*/
6529 static void swap_analyze_header(dsr *hdr)
6530 {
6531
6532 int i;
6533 char c;
6534
6535 hdr->hk.sizeof_hdr = swapInt(hdr->hk.sizeof_hdr);
6536 hdr->hk.extents = swapShort(hdr->hk.extents);
6537 hdr->hk.session_error = swapShort(hdr->hk.session_error);
6538
6539 for(i = 0;i < 5;i++)
6540 hdr->dime.dim[i] = swapShort(hdr->dime.dim[i]);
6541 hdr->dime.unused1 = swapShort(hdr->dime.unused1);
6542 hdr->dime.datatype = swapShort(hdr->dime.datatype);
6543 hdr->dime.bitpix = swapShort(hdr->dime.bitpix);
6544 hdr->dime.dim_un0 = swapShort(hdr->dime.dim_un0);
6545 hdr->dime.vox_offset = swapFloat(hdr->dime.vox_offset);
6546 hdr->dime.roi_scale = swapFloat(hdr->dime.roi_scale);
6547 hdr->dime.funused1 = swapFloat(hdr->dime.funused1);
6548 hdr->dime.funused2 = swapFloat(hdr->dime.funused2);
6549 hdr->dime.cal_max = swapFloat(hdr->dime.cal_max);
6550 hdr->dime.cal_min = swapFloat(hdr->dime.cal_min);
6551 hdr->dime.compressed = swapInt(hdr->dime.compressed);
6552 hdr->dime.verified = swapInt(hdr->dime.verified);
6553 hdr->dime.glmin = swapInt(hdr->dime.glmin);
6554 hdr->dime.glmax = swapInt(hdr->dime.glmax);
6555 for(i = 0;i < 8;i++)
6556 hdr->dime.pixdim[i] = swapFloat(hdr->dime.pixdim[i]);
6557
6558 hdr->hist.views = swapInt(hdr->hist.views);
6559 hdr->hist.vols_added = swapInt(hdr->hist.vols_added);
6560 hdr->hist.start_field = swapInt(hdr->hist.start_field);
6561 hdr->hist.field_skip = swapInt(hdr->hist.field_skip);
6562 hdr->hist.omax = swapInt(hdr->hist.omax);
6563 hdr->hist.omin = swapInt(hdr->hist.omin);
6564 hdr->hist.smax = swapInt(hdr->hist.smax);
6565 hdr->hist.smin = swapInt(hdr->hist.smin);
6566
6567 /* spm uses the originator char[10] as shorts */
6568 for(i = 0;i < 5;i++)
6569 {
6570 c = hdr->hist.originator[2*i+1];
6571 hdr->hist.originator[2*i+1] = hdr->hist.originator[2*i];
6572 hdr->hist.originator[2*i] = c;
6573 }
6574
6575 } /* end swap_analyze_header */
6576 /*------------------------------------------------------*/
6577
6578 #if 0
6579 static int bad_ras_fill(MRI *mri)
6580 {
6581 if(mri->slice_direction == MRI_CORONAL)
6582 {
6583 mri->x_r = -1.0; mri->y_r = 0.0; mri->z_r = 0.0;
6584 mri->x_a = 0.0; mri->y_a = 0.0; mri->z_a = 1.0;
6585 mri->x_s = 0.0; mri->y_s = -1.0; mri->z_s = 0.0;
6586 mri->c_r = 0.0; mri->c_a = 0.0; mri->c_s = 0.0;
6587 }
6588 else if(mri->slice_direction == MRI_SAGITTAL)
6589 {
6590 mri->x_r = 0.0; mri->y_r = 0.0; mri->z_r = -1.0;
6591 mri->x_a = 1.0; mri->y_a = 0.0; mri->z_a = 0.0;
6592 mri->x_s = 0.0; mri->y_s = 1.0; mri->z_s = 0.0;
6593 mri->c_r = 0.0; mri->c_a = 0.0; mri->c_s = 0.0;
6594 }
6595 else if(mri->slice_direction == MRI_HORIZONTAL)
6596 {
6597 mri->x_r = 1.0; mri->y_r = 0.0; mri->z_r = 0.0;
6598 mri->x_a = 0.0; mri->y_a = -1.0; mri->z_a = 0.0;
6599 mri->x_s = 0.0; mri->y_s = 0.0; mri->z_s = 1.0;
6600 mri->c_r = 0.0; mri->c_a = 0.0; mri->c_s = 0.0;
6601 }
6602 else
6603 {
6604 errno = 0;
6605 ErrorReturn
6606 (ERROR_BADPARM,
6607 (ERROR_BADPARM, "bad_ras_fill(): unknown slice direction"));
6608 }
6609
6610 return(NO_ERROR);
6611
6612 } /* end bad_ras_fill() */
6613 #endif
6614
6615 #if 0
6616 // #ifdef VT_TO_CV
6617
6618 static int voxel_center_to_center_voxel(MRI *mri, float *x, float *y, float *z)
6619 {
6620
6621 int result;
6622 MATRIX *m, *i, *r, *mi;
6623
6624 if(!mri->ras_good_flag)
6625 if((result = bad_ras_fill(mri)) != NO_ERROR)
6626 return(result);
6627
6628 if((m = extract_i_to_r(mri)) == NULL)
6629 return(ERROR_BADPARM);
6630
6631 mi = MatrixInverse(m, NULL);
6632 if(mi == NULL)
6633 {
6634 MatrixFree(&m);
6635 errno = 0;
6636 ErrorReturn
6637 (ERROR_BADPARM,
6638 (ERROR_BADPARM,
6639 "voxel_center_to_center_voxel(): error inverting matrix"));
6640 }
6641
6642 r = MatrixAlloc(4, 1, MATRIX_REAL);
6643 if(r == NULL)
6644 {
6645 MatrixFree(&m);
6646 MatrixFree(&mi);
6647 errno = 0;
6648 ErrorReturn
6649 (ERROR_NOMEMORY,
6650 (ERROR_NOMEMORY,
6651 "voxel_center_to_center_voxel(): couldn't allocate matrix"));
6652 }
6653
6654 *MATRIX_RELT(r, 1, 1) = 0.0;
6655 *MATRIX_RELT(r, 2, 1) = 0.0;
6656 *MATRIX_RELT(r, 3, 1) = 0.0;
6657 *MATRIX_RELT(r, 4, 1) = 1.0;
6658
6659 i = MatrixMultiply(mi, r, NULL);
6660 if(i == NULL)
6661 {
6662 MatrixFree(&m);
6663 MatrixFree(&mi);
6664 MatrixFree(&r);
6665 errno = 0;
6666 ErrorReturn
6667 (ERROR_BADPARM,
6668 (ERROR_BADPARM,
6669 "voxel_center_to_center_voxel(): "
6670 "error in matrix multiplication"));
6671 }
6672
6673 *x = *MATRIX_RELT(i, 1, 1);
6674 *y = *MATRIX_RELT(i, 2, 1);
6675 *z = *MATRIX_RELT(i, 3, 1);
6676
6677 MatrixFree(&m);
6678 MatrixFree(&mi);
6679 MatrixFree(&i);
6680 MatrixFree(&r);
6681
6682 return(NO_ERROR);
6683
6684 } /* end voxel_center_to_center_voxel() */
6685
6686 // #endif
6687
6688 static int center_voxel_to_voxel_center(MRI *mri, float x, float y, float z)
6689 {
6690
6691 int result;
6692 MATRIX *m;
6693
6694 if(!mri->ras_good_flag)
6695 if((result = bad_ras_fill(mri)) != NO_ERROR)
6696 return(result);
6697
6698 if((m = extract_i_to_r(mri)) == NULL)
6699 return(ERROR_BADPARM);
6700
6701 *MATRIX_RELT(m, 1, 4) =
6702 0 - (*MATRIX_RELT(m, 1, 1) * x +
6703 *MATRIX_RELT(m, 1, 2) * y +
6704 *MATRIX_RELT(m, 1, 3) * z);
6705 *MATRIX_RELT(m, 2, 4) =
6706 0 - (*MATRIX_RELT(m, 2, 1) * x +
6707 *MATRIX_RELT(m, 2, 2) * y +
6708 *MATRIX_RELT(m, 2, 3) * z);
6709 *MATRIX_RELT(m, 3, 4) =
6710 0 - (*MATRIX_RELT(m, 3, 1) * x +
6711 *MATRIX_RELT(m, 3, 2) * y +
6712 *MATRIX_RELT(m, 3, 3) * z);
6713
6714 apply_i_to_r(mri, m);
6715
6716 MatrixFree(&m);
6717
6718 return(NO_ERROR);
6719
6720 } /* end center_voxel_to_voxel_center() */
6721 #endif // if 0
6722
6723 static MRI *gdfRead(char *fname, int read_volume)
6724 {
6725
6726 MRI *mri;
6727 FILE *fp;
6728 char line[STRLEN];
6729 char *c;
6730 char file_path[STRLEN];
6731 float ipr[2];
6732 float st;
6733 char units_string[STRLEN], orientation_string[STRLEN],
6734 data_type_string[STRLEN];
6735 int size[2];
6736 int path_d, ipr_d, st_d, u_d, dt_d, o_d, s_d,
6737 x_ras_d, y_ras_d, z_ras_d, c_ras_d;
6738 int data_type;
6739 int orientation = MRI_UNDEFINED;
6740 char *or;
6741 char os_orig[STRLEN];
6742 float units_factor;
6743 char file_path_1[STRLEN], file_path_2[STRLEN];
6744 int i, j, k;
6745 short *sbuf = NULL;
6746 float *fbuf = NULL;
6747 unsigned char *ucbuf = NULL;
6748 int n_files;
6749 char fname_use[STRLEN];
6750 int pad_zeros_flag;
6751 int file_offset = 0;
6752 float x_r, x_a, x_s;
6753 float y_r, y_a, y_s;
6754 float z_r, z_a, z_s;
6755 float c_r, c_a, c_s;
6756
6757 if((fp = fopen(fname, "r")) == NULL)
6758 {
6759 errno = 0;
6760 ErrorReturn
6761 (NULL,
6762 (ERROR_BADFILE, "gdfRead(): error opening file %s", fname));
6763 }
6764
6765 /* --- defined flags --- */
6766 path_d = ipr_d = st_d = u_d = dt_d =
6767 o_d = s_d = x_ras_d = y_ras_d = z_ras_d = c_ras_d = FALSE;
6768
6769 while(fgets(line, STRLEN, fp) != NULL)
6770 {
6771
6772 /* --- strip the newline --- */
6773 if((c = strrchr(line, '\n')) != NULL)
6774 *c = '\0';
6775
6776 if(strncmp(line, "IMAGE_FILE_PATH", 15) == 0)
6777 {
6778 sscanf(line, "%*s %s", file_path);
6779 path_d = TRUE;
6780 }
6781 else if(strncmp(line, "IP_RES", 6) == 0)
6782 {
6783 sscanf(line, "%*s %f %f", &ipr[0], &ipr[1]);
6784 ipr_d = TRUE;
6785 }
6786 else if(strncmp(line, "SL_THICK", 8) == 0)
6787 {
6788 sscanf(line, "%*s %f", &st);
6789 st_d = TRUE;
6790 }
6791 else if(strncmp(line, "UNITS", 5) == 0)
6792 {
6793 sscanf(line, "%*s %s", units_string);
6794 u_d = TRUE;
6795 }
6796 else if(strncmp(line, "SIZE", 4) == 0)
6797 {
6798 sscanf(line, "%*s %d %d", &size[0], &size[1]);
6799 s_d = TRUE;
6800 }
6801 else if(strncmp(line, "FS_X_RAS", 8) == 0)
6802 {
6803 sscanf(line, "%*s %f %f %f", &x_r, &x_a, &x_s);
6804 x_ras_d = TRUE;
6805 }
6806 else if(strncmp(line, "FS_Y_RAS", 8) == 0)
6807 {
6808 sscanf(line, "%*s %f %f %f", &y_r, &y_a, &y_s);
6809 y_ras_d = TRUE;
6810 }
6811 else if(strncmp(line, "FS_Z_RAS", 8) == 0)
6812 {
6813 sscanf(line, "%*s %f %f %f", &z_r, &z_a, &z_s);
6814 z_ras_d = TRUE;
6815 }
6816 else if(strncmp(line, "FS_C_RAS", 8) == 0)
6817 {
6818 sscanf(line, "%*s %f %f %f", &c_r, &c_a, &c_s);
6819 c_ras_d = TRUE;
6820 }
6821 else if(strncmp(line, "DATA_TYPE", 9) == 0)
6822 {
6823 strcpy(data_type_string, &line[10]);
6824 dt_d = TRUE;
6825 }
6826 else if(strncmp(line, "ORIENTATION", 11) == 0)
6827 {
6828 sscanf(line, "%*s %s", orientation_string);
6829 strcpy(os_orig, orientation_string);
6830 o_d = TRUE;
6831 }
6832 else if(strncmp(line, "FILE_OFFSET", 11) == 0)
6833 {
6834 sscanf(line, "%*s %d", &file_offset);
6835 }
6836 else
6837 {
6838 }
6839
6840 }
6841
6842 fclose(fp);
6843
6844 if(!(path_d && ipr_d && st_d && s_d))
6845 {
6846 errno = 0;
6847 ErrorPrintf
6848 (ERROR_BADPARM, "gdfRead(): missing field(s) from %s:", fname);
6849 if(!path_d)
6850 ErrorPrintf(ERROR_BADPARM, " IMAGE_FILE_PATH");
6851 if(!ipr_d)
6852 ErrorPrintf(ERROR_BADPARM, " IP_RES");
6853 if(!st_d)
6854 ErrorPrintf(ERROR_BADPARM, " SL_THICK");
6855 if(!s_d)
6856 ErrorPrintf(ERROR_BADPARM, " SIZE");
6857 return(NULL);
6858 }
6859
6860 if(!(o_d))
6861 {
6862 if(x_ras_d && y_ras_d && z_ras_d)
6863 {
6864 printf("missing field ORIENTATION in file %s, "
6865 "but you've got {xyz}_{ras}, so never mind\n", fname);
6866 }
6867 else
6868 {
6869 printf
6870 ("missing field ORIENTATION in file %s; assuming 'coronal'\n",
6871 fname);
6872 sprintf(orientation_string, "coronal");
6873 }
6874 }
6875
6876 if(!(dt_d))
6877 {
6878 printf("missing field DATA_TYPE in file %s; assuming 'short'\n", fname);
6879 sprintf(data_type_string, "short");
6880 }
6881
6882 if(!(u_d))
6883 {
6884 printf("missing field UNITS in file %s; assuming 'mm'\n", fname);
6885 sprintf(units_string, "mm");
6886 }
6887
6888 StrLower(data_type_string);
6889 StrLower(orientation_string);
6890 StrLower(units_string);
6891
6892 /* --- data type --- */
6893 if(strcmp(data_type_string, "short") == 0)
6894 data_type = MRI_SHORT;
6895 else if(strcmp(data_type_string, "float") == 0)
6896 data_type = MRI_FLOAT;
6897 else if(strcmp(data_type_string, "unsigned char") == 0)
6898 data_type = MRI_UCHAR;
6899 else
6900 {
6901 errno = 0;
6902 ErrorReturn
6903 (NULL,
6904 (ERROR_BADPARM,
6905 "gdfRead(): unknown data type '%s'", data_type_string));
6906 }
6907
6908 /* --- orientation --- */
6909 or = strrchr(orientation_string, ' ');
6910 or = (or == NULL ? orientation_string : or+1);
6911 if(strncmp(or, "cor", 3) == 0)
6912 orientation = MRI_CORONAL;
6913 else if(strncmp(or, "sag", 3) == 0)
6914 orientation = MRI_SAGITTAL;
6915 else if(strncmp(or, "ax", 2) == 0 || strncmp(or, "hor", 3) == 0)
6916 orientation = MRI_HORIZONTAL;
6917 else if(!(x_ras_d && y_ras_d && z_ras_d))
6918 {
6919 errno = 0;
6920 ErrorReturn(NULL,
6921 (ERROR_BADPARM,
6922 "gdfRead(): can't determine orientation from string '%s'",
6923 os_orig));
6924 }
6925
6926 if(strcmp(units_string, "mm") == 0)
6927 units_factor = 1.0;
6928 else if(strcmp(units_string, "cm") == 0)
6929 units_factor = 1.0;
6930 else if(strcmp(units_string, "m") == 0)
6931 units_factor = 100.0;
6932 else
6933 {
6934 errno = 0;
6935 ErrorReturn
6936 (NULL,
6937 (ERROR_BADPARM, "gdfRead(): unknown units '%s'", units_string));
6938 }
6939
6940 ipr[0] /= units_factor;
6941 ipr[1] /= units_factor;
6942 st /= units_factor;
6943
6944 strcpy(file_path_1, file_path);
6945 c = strrchr(file_path_1, '*');
6946 if(c == NULL)
6947 {
6948 errno = 0;
6949 ErrorReturn(NULL,
6950 (ERROR_BADPARM,
6951 "gdfRead(): file path %s does not contain '*'\n",
6952 file_path));
6953 }
6954
6955 *c = '\0';
6956 c++;
6957 strcpy(file_path_2, c);
6958
6959 #if 0
6960
6961 /* cardviews takes IMAGE_FILE_PATH relative to the working */
6962 /* directory -- so we skip this step - ch */
6963
6964 /* ----- relative path -- go from directory with the .gdf file ----- */
6965 if(file_path_1[0] != '/')
6966 {
6967
6968 char gdf_path[STRLEN];
6969
6970 if(fname[0] == '/')
6971 sprintf(gdf_path, "%s", fname);
6972 else
6973 sprintf(gdf_path, "./%s", fname);
6974
6975 c = strrchr(gdf_path, '/');
6976 c[1] = '\0';
6977
6978 strcat(gdf_path, file_path_1);
6979 strcpy(file_path_1, gdf_path);
6980
6981 }
6982 #endif
6983
6984 pad_zeros_flag = FALSE;
6985
6986 n_files = 0;
6987 do
6988 {
6989 n_files++;
6990 sprintf(fname_use, "%s%d%s", file_path_1, n_files, file_path_2);
6991 } while(FileExists(fname_use));
6992
6993 /* ----- try padding the zeros if no files are found ----- */
6994 if(n_files == 1)
6995 {
6996
6997 pad_zeros_flag = TRUE;
6998
6999 n_files = 0;
7000 do
7001 {
7002 n_files++;
7003 sprintf(fname_use, "%s%03d%s", file_path_1, n_files, file_path_2);
7004 } while(FileExists(fname_use));
7005
7006 /* ----- still a problem? ----- */
7007 if(n_files == 1)
7008 {
7009 errno = 0;
7010 ErrorReturn(NULL, (ERROR_BADFILE,
7011 "gdfRead(): can't find file %s%d%s or %s\n",
7012 file_path_1, 1, file_path_2, fname_use));
7013 }
7014
7015 }
7016
7017 n_files--;
7018
7019 if(read_volume)
7020 mri = MRIallocSequence(size[0], size[1], n_files, data_type, 1);
7021 else
7022 mri = MRIallocHeader(size[0], size[1], n_files, data_type);
7023
7024 mri->xsize = ipr[0];
7025 mri->ysize = ipr[1];
7026 mri->zsize = st;
7027
7028 mri->xend = mri->width * mri->xsize / 2.0;
7029 mri->xstart = -mri->xend;
7030 mri->yend = mri->height * mri->ysize / 2.0;
7031 mri->ystart = -mri->yend;
7032 mri->zend = mri->depth * mri->zsize / 2.0;
7033 mri->zstart = -mri->zend;
7034
7035 strcpy(mri->fname, fname);
7036
7037 /* --- set volume orientation --- */
7038 if(x_ras_d && y_ras_d && z_ras_d)
7039 {
7040 mri->x_r = x_r; mri->x_a = x_a; mri->x_s = x_s;
7041 mri->y_r = y_r; mri->y_a = y_a; mri->y_s = y_s;
7042 mri->z_r = z_r; mri->z_a = z_a; mri->z_s = z_s;
7043 mri->ras_good_flag = TRUE;
7044 }
7045 else
7046 {
7047 /*
7048 direction cosine is not set. we pick a particular kind
7049 of direction cosine. If the volume is different you have
7050 to modify (how?)
7051 */
7052 if (setDirectionCosine(mri, orientation) != NO_ERROR)
7053 {
7054 MRIfree(&mri);
7055 return NULL;
7056 }
7057 printf("warning: gdf volume may be incorrectly oriented\n");
7058 }
7059
7060 /* --- set volume center --- */
7061 if(c_ras_d)
7062 {
7063 mri->c_r = c_r; mri->c_a = c_a; mri->c_s = c_s;
7064 }
7065 else
7066 {
7067 mri->c_r = mri->c_a = mri->c_s = 0.0;
7068 printf("warning: gdf volume may be incorrectly centered\n");
7069 }
7070
7071 if(!read_volume)
7072 return(mri);
7073
7074 if(mri->type == MRI_UCHAR)
7075 {
7076 ucbuf = (unsigned char *)malloc(mri->width);
7077 if(ucbuf == NULL)
7078 {
7079 MRIfree(&mri);
7080 errno = 0;
7081 ErrorReturn
7082 (NULL,
7083 (ERROR_NOMEMORY,
7084 "gdfRead(): error allocating %d bytes for read buffer",
7085 mri->width));
7086 }
7087 }
7088 else if(mri->type == MRI_SHORT)
7089 {
7090 sbuf = (short *)malloc(mri->width * sizeof(short));
7091 if(sbuf == NULL)
7092 {
7093 MRIfree(&mri);
7094 errno = 0;
7095 ErrorReturn
7096 (NULL,
7097 (ERROR_NOMEMORY,
7098 "gdfRead(): error allocating %d bytes for read buffer",
7099 mri->width * sizeof(short)));
7100 }
7101 }
7102 else if(mri->type == MRI_FLOAT)
7103 {
7104 fbuf = (float *)malloc(mri->width * sizeof(float));
7105 if(fbuf == NULL)
7106 {
7107 MRIfree(&mri);
7108 errno = 0;
7109 ErrorReturn
7110 (NULL,
7111 (ERROR_NOMEMORY,
7112 "gdfRead(): error allocating %d bytes for read buffer",
7113 mri->width * sizeof(float)));
7114 }
7115 }
7116 else
7117 {
7118 MRIfree(&mri);
7119 errno = 0;
7120 ErrorReturn(NULL, (ERROR_BADPARM,
7121 "gdfRead(): internal error; data type %d "
7122 "accepted but not supported in read",
7123 mri->type));
7124 }
7125
7126 for(i = 1;i <= n_files;i++)
7127 {
7128
7129 if(pad_zeros_flag)
7130 sprintf(fname_use, "%s%03d%s", file_path_1, i, file_path_2);
7131 else
7132 sprintf(fname_use, "%s%d%s", file_path_1, i, file_path_2);
7133
7134 fp = fopen(fname_use, "r");
7135 if(fp == NULL)
7136 {
7137 if(mri->type == MRI_UCHAR)
7138 free(ucbuf);
7139 if(mri->type == MRI_SHORT)
7140 free(sbuf);
7141 if(mri->type == MRI_FLOAT)
7142 free(fbuf);
7143 MRIfree(&mri);
7144 errno = 0;
7145 ErrorReturn
7146 (NULL,
7147 (ERROR_BADFILE,
7148 "gdfRead(): error opening file %s", fname_use));
7149 }
7150
7151 fseek(fp, file_offset, SEEK_SET);
7152
7153 if(mri->type == MRI_UCHAR)
7154 {
7155 for(j = 0;j < mri->height;j++)
7156 {
7157 if(fread(ucbuf, 1, mri->width, fp) != mri->width)
7158 {
7159 free(ucbuf);
7160 MRIfree(&mri);
7161 errno = 0;
7162 ErrorReturn(NULL, (ERROR_BADFILE,
7163 "gdfRead(): error reading from file %s",
7164 fname_use));
7165 }
7166 for(k = 0;k < mri->width;k++)
7167 MRIvox(mri, k, j, i-1) = ucbuf[k];
7168 }
7169 }
7170
7171 if(mri->type == MRI_SHORT)
7172 {
7173 for(j = 0;j < mri->height;j++)
7174 {
7175 if(fread(sbuf, sizeof(short), mri->width, fp) != mri->width)
7176 {
7177 free(sbuf);
7178 MRIfree(&mri);
7179 errno = 0;
7180 ErrorReturn(NULL, (ERROR_BADFILE,
7181 "gdfRead(): error reading from file %s",
7182 fname_use));
7183 }
7184 #if (BYTE_ORDER == LITTLE_ENDIAN)
7185 for(k = 0;k < mri->width;k++)
7186 MRISvox(mri, k, j, i-1) = orderShortBytes(sbuf[k]);
7187 #else
7188 for(k = 0;k < mri->width;k++)
7189 MRISvox(mri, k, j, i-1) = sbuf[k];
7190 #endif
7191 }
7192 }
7193
7194 if(mri->type == MRI_FLOAT)
7195 {
7196 for(j = 0;j < mri->height;j++)
7197 {
7198 if(fread(fbuf, sizeof(float), mri->width, fp) != mri->width)
7199 {
7200 free(fbuf);
7201 MRIfree(&mri);
7202 errno = 0;
7203 ErrorReturn
7204 (NULL,
7205 (ERROR_BADFILE,
7206 "gdfRead(): error reading from file %s", fname_use));
7207 }
7208 #if (BYTE_ORDER == LITTLE_ENDIAN)
7209 for(k = 0;k < mri->width;k++)
7210 MRIFvox(mri, k, j, i-1) = orderFloatBytes(fbuf[k]);
7211 #else
7212 for(k = 0;k < mri->width;k++)
7213 MRIFvox(mri, k, j, i-1) = fbuf[k];
7214 #endif
7215 }
7216 }
7217
7218 fclose(fp);
7219
7220 }
7221
7222 if(mri->type == MRI_UCHAR)
7223 free(ucbuf);
7224 if(mri->type == MRI_SHORT)
7225 free(sbuf);
7226 if(mri->type == MRI_FLOAT)
7227 free(fbuf);
7228
7229 return(mri);
7230
7231 } /* end gdfRead() */
7232
7233 static int gdfWrite(MRI *mri, char *fname)
7234 {
7235
7236 FILE *fp;
7237 int i, j;
7238 char im_fname[STRLEN];
7239 unsigned char *buf;
7240 int buf_size = 0;
7241
7242 if(strlen(mri->gdf_image_stem) == 0)
7243 {
7244 errno = 0;
7245 ErrorReturn
7246 (ERROR_BADPARM,
7247 (ERROR_BADPARM, "GDF write attempted without GDF image stem"));
7248 }
7249
7250 if(mri->nframes != 1)
7251 {
7252 errno = 0;
7253 ErrorReturn(ERROR_BADPARM, (ERROR_BADPARM,
7254 "GDF write attempted with %d frames "
7255 "(supported only for 1 frame)",
7256 mri->nframes));
7257 }
7258
7259 /* ----- type checks first ----- */
7260
7261 if(mri->type != MRI_UCHAR &&
7262 mri->type != MRI_FLOAT &&
7263 mri->type != MRI_SHORT)
7264 {
7265 errno = 0;
7266 ErrorReturn
7267 (ERROR_BADPARM,
7268 (ERROR_BADPARM,
7269 "gdfWrite(): bad data type (%d) for GDF write "
7270 "(only uchar, float, short supported)", mri->type));
7271 }
7272
7273 /* ----- then write the image files ----- */
7274
7275 printf("writing GDF image files...\n");
7276
7277 if(mri->type == MRI_UCHAR)
7278 buf_size = mri->width * sizeof(unsigned char);
7279 if(mri->type == MRI_FLOAT)
7280 buf_size = mri->width * sizeof(float);
7281 if(mri->type == MRI_SHORT)
7282 buf_size = mri->width * sizeof(short);
7283
7284 buf = (unsigned char *)malloc(buf_size);
7285 if(buf == NULL)
7286 {
7287 errno = 0;
7288 ErrorReturn
7289 (ERROR_NO_MEMORY,
7290 (ERROR_NO_MEMORY,
7291 "gdfWrite(): no memory for voxel write buffer"));
7292 }
7293
7294 for(i = 0;i < mri->depth;i++)
7295 {
7296
7297 sprintf(im_fname, "%s_%d.img", mri->gdf_image_stem, i+1);
7298 fp = fopen(im_fname, "w");
7299 if(fp == NULL)
7300 {
7301 free(buf);
7302 errno = 0;
7303 ErrorReturn
7304 (ERROR_BADFILE,
7305 (ERROR_BADFILE,
7306 "gdfWrite(): error opening file %s", im_fname));
7307 }
7308
7309 for(j = 0;j < mri->height;j++)
7310 {
7311 memcpy(buf, mri->slices[i][j], buf_size);
7312 #if (BYTE_ORDER == LITTLE_ENDIAN)
7313 if(mri->type == MRI_FLOAT)
7314 byteswapbuffloat(buf, buf_size);
7315 if(mri->type == MRI_SHORT)
7316 byteswapbufshort(buf, buf_size);
7317 #endif
7318 fwrite(buf, 1, buf_size, fp);
7319 }
7320
7321 fclose(fp);
7322
7323 }
7324
7325 free(buf);
7326
7327 /* ----- and finally the info file ----- */
7328
7329 printf("writing GDF info file...\n");
7330
7331 fp = fopen(fname, "w");
7332 if(fp == NULL)
7333 {
7334 errno = 0;
7335 ErrorReturn
7336 (ERROR_BADFILE,
7337 (ERROR_BADFILE, "gdfWrite(): error opening file %s", fname));
7338 }
7339
7340 fprintf(fp, "GDF FILE VERSION3\n");
7341 fprintf(fp, "START MAIN HEADER\n");
7342 fprintf(fp, "IMAGE_FILE_PATH %s_*.img\n", mri->gdf_image_stem);
7343 fprintf(fp, "SIZE %d %d\n", mri->width, mri->height);
7344 fprintf(fp, "IP_RES %g %g\n", mri->xsize, mri->ysize);
7345 fprintf(fp, "SL_THICK %g\n", mri->zsize);
7346 if(mri->ras_good_flag)
7347 {
7348 fprintf(fp, "FS_X_RAS %f %f %f\n", mri->x_r, mri->x_a, mri->x_s);
7349 fprintf(fp, "FS_Y_RAS %f %f %f\n", mri->y_r, mri->y_a, mri->y_s);
7350 fprintf(fp, "FS_Z_RAS %f %f %f\n", mri->z_r, mri->z_a, mri->z_s);
7351 fprintf(fp, "FS_C_RAS %f %f %f\n", mri->c_r, mri->c_a, mri->c_s);
7352 }
7353 fprintf(fp, "FILE_OFFSET 0\n");
7354 if(mri->type == MRI_UCHAR)
7355 fprintf(fp, "DATA_TYPE unsigned char\n");
7356 if(mri->type == MRI_FLOAT)
7357 fprintf(fp, "DATA_TYPE float\n");
7358 if(mri->type == MRI_SHORT)
7359 fprintf(fp, "DATA_TYPE short\n");
7360 fprintf(fp, "END MAIN HEADER\n");
7361
7362 fclose(fp);
7363
7364 return(NO_ERROR);
7365
7366 }
7367
7368 static int parc_fill(short label_value, short seed_x, short seed_y)
7369 {
7370
7371 if(seed_x < 0 || seed_x >= 512 || seed_y < 0 || seed_y >= 512)
7372 return(NO_ERROR);
7373
7374 if(cma_field[seed_x][seed_y] == label_value)
7375 return(NO_ERROR);
7376
7377 cma_field[seed_x][seed_y] = label_value;
7378
7379 parc_fill(label_value, seed_x + 1, seed_y );
7380 parc_fill(label_value, seed_x - 1, seed_y );
7381 parc_fill(label_value, seed_x , seed_y + 1);
7382 parc_fill(label_value, seed_x , seed_y - 1);
7383
7384 return(NO_ERROR);
7385
7386 } /* end parc_fill() */
7387
7388 static int register_unknown_label(char *label)
7389 {
7390
7391 int i;
7392
7393 if(n_unknown_labels == MAX_UNKNOWN_LABELS)
7394 return(NO_ERROR);
7395
7396 for(i = 0;i < n_unknown_labels;i++)
7397 {
7398 if(strcmp(unknown_labels[i], label) == 0)
7399 return(NO_ERROR);
7400 }
7401
7402 strcpy(unknown_labels[n_unknown_labels], label);
7403 n_unknown_labels++;
7404
7405 return(NO_ERROR);
7406
7407 } /* end register_unknown_label() */
7408
7409 static int clear_unknown_labels(void)
7410 {
7411
7412 n_unknown_labels = 0;
7413
7414 return(NO_ERROR);
7415
7416 } /* end clear_unknown_labels() */
7417
7418 static int print_unknown_labels(char *prefix)
7419 {
7420
7421 int i;
7422
7423 for(i = 0;i < n_unknown_labels;i++)
7424 printf("%s%s\n", prefix, unknown_labels[i]);
7425
7426 return(NO_ERROR);
7427
7428 } /* end print_unknown_labels() */
7429
7430 /* replaced 25 Feb 2003 ch */
7431 #if 0
7432 static int read_otl_file(FILE *fp,
7433 MRI *mri,
7434 int slice,
7435 mriColorLookupTableRef color_table,
7436 int fill_flag,
7437 int translate_label_flag,
7438 int zero_outlines_flag)
7439 {
7440 int n_outlines = -1;
7441 int n_rows, n_cols;
7442 char label[STRLEN], label_to_compare[STRLEN];
7443 int seed_x, seed_y;
7444 char line[STRLEN];
7445 int main_header_flag;
7446 int i, j;
7447 int gdf_header_flag;
7448 char type[STRLEN], global_type[STRLEN];
7449 char *c;
7450 short *points;
7451 int n_read;
7452 short label_value;
7453 float scale_x, scale_y;
7454 int source_x, source_y;
7455 char alt_compare[STRLEN];
7456 int empty_label_flag;
7457 int ascii_short_flag;
7458 int row;
7459 char *translate_start;
7460 int internal_structures_flag = FALSE;
7461
7462 for(i = 0;i < 512;i++)
7463 memset(cma_field[i], 0x00, 512 * 2);
7464
7465 fgets(line, STRLEN, fp);
7466 if(strncmp(line, "GDF FILE VERSION", 15) != 0)
7467 {
7468 errno = 0;
7469 ErrorReturn
7470 (ERROR_BADFILE,
7471 (ERROR_BADFILE,
7472 "otl slice %s does not appear to be a GDF file", slice));
7473 }
7474
7475 main_header_flag = FALSE;
7476 while(!main_header_flag)
7477 {
7478 if(feof(fp))
7479 {
7480 errno = 0;
7481 ErrorReturn
7482 (ERROR_BADFILE,
7483 (ERROR_BADFILE,
7484 "premature EOF () in otl file %d", slice));
7485 }
7486 fgets(line, STRLEN, fp);
7487 if(strncmp(line, "START MAIN HEADER", 17) == 0)
7488 main_header_flag = TRUE;
7489 }
7490
7491 n_cols = -1;
7492 type[0] = '\0';
7493 global_type[0] = '\0';
7494
7495 while(main_header_flag)
7496 {
7497 if(feof(fp))
7498 {
7499 errno = 0;
7500 ErrorReturn
7501 (ERROR_BADFILE,
7502 (ERROR_BADFILE,
7503 "premature EOF (in main header) in otl file %d", slice));
7504 }
7505 fgets(line, STRLEN, fp);
7506 if(strncmp(line, "END MAIN HEADER", 15) == 0)
7507 main_header_flag = FALSE;
7508 if(strncmp(line, "ONUM ", 5) == 0)
7509 sscanf(line, "%*s %d", &n_outlines);
7510 if(strncmp(line, "COL_NUM", 7) == 0)
7511 sscanf(line, "%*s %d", &n_cols);
7512 if(strncmp(line, "TYPE", 4) == 0)
7513 {
7514 strcpy(global_type, &(line[5]));
7515 c = strrchr(global_type, '\n');
7516 if(c != NULL)
7517 *c = '\0';
7518 }
7519 }
7520
7521 if(n_outlines == -1)
7522 {
7523 errno = 0;
7524 ErrorReturn
7525 (ERROR_BADPARM,
7526 (ERROR_BADPARM,
7527 "bad or undefined ONUM in otl file %d", slice));
7528 }
7529
7530 for(i = 0;i < n_outlines;i++)
7531 {
7532 if(feof(fp))
7533 {
7534 errno = 0;
7535 ErrorReturn
7536 (ERROR_BADFILE,
7537 (ERROR_BADFILE,
7538 "premature EOF (ready for next outline) in otl file %d",
7539 slice));
7540 }
7541
7542 gdf_header_flag = FALSE;
7543
7544 while(!gdf_header_flag)
7545 {
7546 if(feof(fp))
7547 {
7548 errno = 0;
7549 ErrorReturn
7550 (ERROR_BADFILE,
7551 (ERROR_BADFILE,
7552 "premature EOF (searching for gdf header) "
7553 "in otl file %d", slice));
7554 }
7555 fgets(line, STRLEN, fp);
7556 if(strncmp(line, "START GDF HEADER", 16) == 0)
7557 gdf_header_flag = TRUE;
7558 }
7559
7560 n_rows = -1;
7561 seed_x = seed_y = -1;
7562 label[0] = '\0';
7563 type[0] = '\0';
7564
7565 empty_label_flag = 0;
7566
7567 while(gdf_header_flag)
7568 {
7569
7570 if(feof(fp))
7571 {
7572 errno = 0;
7573 ErrorReturn
7574 (ERROR_BADFILE,
7575 (ERROR_BADFILE,
7576 "premature EOF (in gdf header) in otl file %d",
7577 slice));
7578 }
7579 fgets(line, STRLEN, fp);
7580 if(strncmp(line, "END GDF HEADER", 14) == 0)
7581 gdf_header_flag = FALSE;
7582 if(strncmp(line, "ROW_NUM", 7) == 0)
7583 sscanf(line, "%*s %d", &n_rows);
7584 if(strncmp(line, "COL_NUM", 7) == 0)
7585 sscanf(line, "%*s %d", &n_cols);
7586 if(strncmp(line, "TYPE", 4) == 0)
7587 {
7588 strcpy(type, &(line[5]));
7589 c = strrchr(type, '\n');
7590 if(c != NULL)
7591 *c = '\0';
7592 }
7593 if(strncmp(line, "SEED", 4) == 0)
7594 sscanf(line, "%*s %d %d", &seed_x, &seed_y);
7595 if(strncmp(line, "LABEL", 5) == 0)
7596 {
7597
7598 strcpy(label, &(line[6]));
7599 c = strrchr(label, '\n');
7600 if(c != NULL)
7601 *c = '\0';
7602
7603 /* exterior -> cortex, if desired */
7604 if(translate_label_flag)
7605 {
7606 translate_start = strstr(label, "Exterior");
7607 if(translate_start != NULL)
7608 sprintf(translate_start, "Cortex");
7609 else
7610 {
7611 translate_start = strstr(label, "exterior");
7612 if(translate_start != NULL)
7613 sprintf(translate_start, "cortex");
7614 }
7615 }
7616
7617 /* warning if there's an "exterior" or
7618 "cortex" after any other label */
7619 if(strstr(label, "Exterior") == 0 \
7620 || strstr(label, "exterior") == 0 \
7621 || strstr(label, "Cortex") == 0 \
7622 || strstr(label, "cortex") == 0)
7623 {
7624 if(internal_structures_flag)
7625 printf("WARNING: label \"%s\" following "
7626 "non-exterior labels in slice %d\n",
7627 label, slice);
7628 internal_structures_flag = FALSE;
7629 }
7630 else
7631 internal_structures_flag = TRUE;
7632
7633 }
7634
7635 }
7636
7637 if(n_rows < 0)
7638 {
7639 errno = 0;
7640 ErrorReturn(ERROR_BADPARM,
7641 (ERROR_BADPARM,
7642 "bad or undefined ROW_NUM in otl file %d", slice));
7643 }
7644
7645 if(n_cols != 2)
7646 {
7647 errno = 0;
7648 ErrorReturn(ERROR_BADPARM,
7649 (ERROR_BADPARM,
7650 "bad or undefined COL_NUM in otl file %d", slice));
7651 }
7652
7653 if(label[0] == '\0')
7654 {
7655 empty_label_flag = 1;
7656 errno = 0;
7657 ErrorPrintf
7658 (ERROR_BADPARM,
7659 "empty LABEL in otl file %d (outline %d)", slice, i);
7660 }
7661
7662 if(seed_x < 0 || seed_x >= 512 || seed_y < 0 || seed_y >= 512)
7663 {
7664 errno = 0;
7665 ErrorReturn(ERROR_BADPARM,
7666 (ERROR_BADPARM,
7667 "bad or undefined SEED in otl file %d", slice));
7668 }
7669
7670 if(type[0] == '\0')
7671 strcpy(type, global_type);
7672
7673 if(strcmp(type, "ascii short") == 0)
7674 ascii_short_flag = TRUE;
7675 else if(strcmp(type, "short") == 0)
7676 ascii_short_flag = FALSE;
7677 else if(type[0] == '\0')
7678 {
7679 errno = 0;
7680 ErrorReturn(ERROR_UNSUPPORTED,
7681 (ERROR_UNSUPPORTED,
7682 "undefined TYPE in otl file %d", slice));
7683 }
7684 else
7685 {
7686 errno = 0;
7687 ErrorReturn(ERROR_UNSUPPORTED,
7688 (ERROR_UNSUPPORTED,
7689 "unsupported TYPE \"%s\" in otl file %d", type, slice));
7690 }
7691
7692 do
7693 {
7694 fgets(line, STRLEN, fp);
7695 if(feof(fp))
7696 {
7697 errno = 0;
7698 ErrorReturn
7699 (ERROR_BADFILE,
7700 (ERROR_BADFILE,
7701 "premature EOF (searching for points) in otl file %d",
7702 slice));
7703 }
7704 } while(strncmp(line, "START POINTS", 12) != 0);
7705
7706 points = (short *)malloc(2 * n_rows * sizeof(short));
7707 if(points == NULL)
7708 {
7709 errno = 0;
7710 ErrorReturn
7711 (ERROR_NOMEMORY,
7712 (ERROR_NOMEMORY,
7713 "error allocating memory for points in otl file %d", slice));
7714 }
7715
7716 if(ascii_short_flag)
7717 {
7718 for(row = 0;row < n_rows;row++)
7719 {
7720 fgets(line, STRLEN, fp);
7721 if(feof(fp))
7722 {
7723 free(points);
7724 errno = 0;
7725 ErrorReturn
7726 (ERROR_BADFILE,
7727 (ERROR_BADFILE,
7728 "premature end of file while reading points "
7729 "from otl file %d",
7730 slice));
7731 }
7732 sscanf(line, "%hd %hd", &(points[2*row]), &(points[2*row+1]));
7733 }
7734 }
7735 else
7736 {
7737 n_read = fread(points, 2, n_rows * 2, fp);
7738 if(n_read != n_rows * 2)
7739 {
7740 free(points);
7741 errno = 0;
7742 ErrorReturn(ERROR_BADFILE,
7743 (ERROR_BADFILE,
7744 "error reading points from otl file %d", slice));
7745 }
7746 #if (BYTE_ORDER == LITTLE_ENDIAN)
7747 swab(points, points, 2 * n_rows * sizeof(short));
7748 #endif
7749 }
7750
7751 fgets(line, STRLEN, fp);
7752 if(strncmp(line, "END POINTS", 10) != 0)
7753 {
7754 free(points);
7755 errno = 0;
7756 ErrorReturn
7757 (ERROR_BADFILE,
7758 (ERROR_BADFILE,
7759 "error after points (\"END POINTS\" expected "
7760 "but not found) in otl file %d", slice));
7761 }
7762
7763 if(!empty_label_flag)
7764 {
7765 strcpy(label_to_compare, label);
7766 for(j = 0;label_to_compare[j] != '\0';j++)
7767 {
7768 if(label_to_compare[j] == '\n')
7769 label_to_compare[j] = '\0';
7770 if(label_to_compare[j] == ' ')
7771 label_to_compare[j] = '-';
7772 }
7773
7774 /* --- strip 'Left' and 'Right'; --- */
7775 strcpy(alt_compare, label_to_compare);
7776 StrLower(alt_compare);
7777 if(strncmp(alt_compare, "left-", 5) == 0)
7778 strcpy(alt_compare, &(label_to_compare[5]));
7779 else if(strncmp(alt_compare, "right-", 6) == 0)
7780 strcpy(alt_compare, &(label_to_compare[6]));
7781
7782 /* --- strip leading and trailing spaces (now dashes) --- */
7783
7784 /* leading */
7785 for(j = 0;label_to_compare[j] == '-';j++);
7786 if(label_to_compare[j] != '\0')
7787 {
7788 for(c = label_to_compare;*(c+j) != '\0';c++)
7789 *c = *(c+j);
7790 *c = *(c+j);
7791 }
7792
7793 /* trailing */
7794 for(j = strlen(label_to_compare) - 1;
7795 j >= 0 && label_to_compare[j] == '-';
7796 j--);
7797 if(j < 0) /* all dashes! */
7798 {
7799 /* for now, let this fall through to an unknown label */
7800 }
7801 else /* j is the index of the last non-dash character */
7802 {
7803 label_to_compare[j+1] = '\0';
7804 }
7805
7806
7807 label_value = -1;
7808 for(j = 0;j < color_table->mnNumEntries;j++)
7809 if(strcmp(color_table->maEntries[j].msLabel,
7810 label_to_compare) == 0 ||
7811 strcmp(color_table->maEntries[j].msLabel, alt_compare) == 0)
7812 label_value = j;
7813
7814 if(label_value == -1)
7815 {
7816 register_unknown_label(label);
7817 }
7818 else
7819 {
7820
7821 for(j = 0;j < n_rows;j++)
7822 cma_field[points[2*j]][points[2*j+1]] = label_value;
7823
7824 if(fill_flag && label_value != 0)
7825 parc_fill(label_value, seed_x, seed_y);
7826
7827 if(zero_outlines_flag)
7828 {
7829 for(j = 0;j < n_rows;j++)
7830 cma_field[points[2*j]][points[2*j+1]] = 0;
7831 }
7832
7833
7834 }
7835
7836 }
7837
7838 free(points);
7839
7840 }
7841
7842 scale_x = 512 / mri->width;
7843 scale_y = 512 / mri->height;
7844
7845 for(i = 0;i < mri->width;i++)
7846 for(j = 0;j < mri->height;j++)
7847 {
7848 source_x = (int)floor(scale_x * (float)i);
7849 source_y = (int)floor(scale_y * (float)j);
7850 if(source_x < 0)
7851 source_x = 0;
7852 if(source_x > 511)
7853 source_x = 511;
7854 if(source_y < 0)
7855 source_y = 0;
7856 if(source_y > 511)
7857 source_y = 511;
7858 MRISvox(mri, i, j, slice-1) = cma_field[source_x][source_y];
7859 }
7860
7861 return(NO_ERROR);
7862
7863 } /* end read_otl_file() */
7864 #endif
7865
7866 static int read_otl_file(FILE *fp,
7867 MRI *mri,
7868 int slice,
7869 mriColorLookupTableRef color_table,
7870 int fill_flag,
7871 int translate_label_flag,
7872 int zero_outlines_flag)
7873 {
7874
7875 int n_outlines = -1;
7876 int n_rows, n_cols;
7877 char label[STRLEN], label_to_compare[STRLEN];
7878 int seed_x, seed_y;
7879 char line[STRLEN];
7880 int main_header_flag;
7881 int i, j;
7882 int gdf_header_flag;
7883 char type[STRLEN], global_type[STRLEN];
7884 char *c;
7885 short *points;
7886 int n_read;
7887 short label_value;
7888 float scale_x, scale_y;
7889 int source_x, source_y;
7890 char alt_compare[STRLEN];
7891 int empty_label_flag;
7892 int ascii_short_flag;
7893 int row;
7894 char *translate_start;
7895 int internal_structures_flag = FALSE;
7896 CMAoutlineField *of;
7897
7898 fgets(line, STRLEN, fp);
7899 if(strncmp(line, "GDF FILE VERSION", 15) != 0)
7900 {
7901 errno = 0;
7902 ErrorReturn(ERROR_BADFILE,
7903 (ERROR_BADFILE,
7904 "otl slice %s does not appear to be a GDF file", slice));
7905 }
7906
7907 main_header_flag = FALSE;
7908 while(!main_header_flag)
7909 {
7910 if(feof(fp))
7911 {
7912 errno = 0;
7913 ErrorReturn
7914 (ERROR_BADFILE,
7915 (ERROR_BADFILE, "premature EOF () in otl file %d", slice));
7916 }
7917 fgets(line, STRLEN, fp);
7918 if(strncmp(line, "START MAIN HEADER", 17) == 0)
7919 main_header_flag = TRUE;
7920 }
7921
7922 n_cols = -1;
7923 type[0] = '\0';
7924 global_type[0] = '\0';
7925
7926 while(main_header_flag)
7927 {
7928 if(feof(fp))
7929 {
7930 errno = 0;
7931 ErrorReturn
7932 (ERROR_BADFILE,
7933 (ERROR_BADFILE,
7934 "premature EOF (in main header) in otl file %d", slice));
7935 }
7936 fgets(line, STRLEN, fp);
7937 if(strncmp(line, "END MAIN HEADER", 15) == 0)
7938 main_header_flag = FALSE;
7939 if(strncmp(line, "ONUM ", 5) == 0)
7940 sscanf(line, "%*s %d", &n_outlines);
7941 if(strncmp(line, "COL_NUM", 7) == 0)
7942 sscanf(line, "%*s %d", &n_cols);
7943 if(strncmp(line, "TYPE", 4) == 0)
7944 {
7945 strcpy(global_type, &(line[5]));
7946 c = strrchr(global_type, '\n');
7947 if(c != NULL)
7948 *c = '\0';
7949 }
7950 }
7951
7952 if(n_outlines == -1)
7953 {
7954 errno = 0;
7955 ErrorReturn
7956 (ERROR_BADPARM,
7957 (ERROR_BADPARM,
7958 "bad or undefined ONUM in otl file %d", slice));
7959 }
7960
7961 of = CMAoutlineFieldAlloc(2*mri->width, 2*mri->height);
7962 if(of == NULL)
7963 return(ERROR_NOMEMORY);
7964
7965 for(i = 0;i < n_outlines;i++)
7966 {
7967 if(feof(fp))
7968 {
7969 CMAfreeOutlineField(&of);
7970 errno = 0;
7971 ErrorReturn
7972 (ERROR_BADFILE,
7973 (ERROR_BADFILE,
7974 "premature EOF (ready for next outline) in otl file %d", slice));
7975 }
7976
7977 gdf_header_flag = FALSE;
7978
7979 while(!gdf_header_flag)
7980 {
7981 if(feof(fp))
7982 {
7983 CMAfreeOutlineField(&of);
7984 errno = 0;
7985 ErrorReturn
7986 (ERROR_BADFILE,
7987 (ERROR_BADFILE,
7988 "premature EOF (searching for gdf header) in otl file %d",
7989 slice));
7990 }
7991 fgets(line, STRLEN, fp);
7992 if(strncmp(line, "START GDF HEADER", 16) == 0)
7993 gdf_header_flag = TRUE;
7994 }
7995
7996 n_rows = -1;
7997 seed_x = seed_y = -1;
7998 label[0] = '\0';
7999 type[0] = '\0';
8000
8001 empty_label_flag = 0;
8002
8003 while(gdf_header_flag)
8004 {
8005
8006 if(feof(fp))
8007 {
8008 CMAfreeOutlineField(&of);
8009 errno = 0;
8010 ErrorReturn
8011 (ERROR_BADFILE,
8012 (ERROR_BADFILE,
8013 "premature EOF (in gdf header) in otl file %d", slice));
8014 }
8015 fgets(line, STRLEN, fp);
8016 if(strncmp(line, "END GDF HEADER", 14) == 0)
8017 gdf_header_flag = FALSE;
8018 // getting rows, cols, type
8019 if(strncmp(line, "ROW_NUM", 7) == 0)
8020 sscanf(line, "%*s %d", &n_rows);
8021 if(strncmp(line, "COL_NUM", 7) == 0)
8022 sscanf(line, "%*s %d", &n_cols);
8023 if(strncmp(line, "TYPE", 4) == 0)
8024 {
8025 strcpy(type, &(line[5]));
8026 c = strrchr(type, '\n');
8027 if(c != NULL)
8028 *c = '\0';
8029 }
8030 if(strncmp(line, "SEED", 4) == 0)
8031 sscanf(line, "%*s %d %d", &seed_x, &seed_y);
8032 if(strncmp(line, "LABEL", 5) == 0)
8033 {
8034
8035 strcpy(label, &(line[6]));
8036 c = strrchr(label, '\n');
8037 if(c != NULL)
8038 *c = '\0';
8039
8040 /* exterior -> cortex, if desired */
8041 if(translate_label_flag)
8042 {
8043 translate_start = strstr(label, "Exterior");
8044 if(translate_start != NULL)
8045 sprintf(translate_start, "Cortex");
8046 else
8047 {
8048 translate_start = strstr(label, "exterior");
8049 if(translate_start != NULL)
8050 sprintf(translate_start, "cortex");
8051 }
8052 }
8053
8054 /* warning if there's an "exterior" or
8055 "cortex" after any other label */
8056 if(strstr(label, "Exterior") == 0 \
8057 || strstr(label, "exterior") == 0 \
8058 || strstr(label, "Cortex") == 0 \
8059 || strstr(label, "cortex") == 0)
8060 {
8061 if(internal_structures_flag)
8062 printf("WARNING: label \"%s\" following "
8063 "non-exterior labels in slice %d\n",
8064 label, slice);
8065 internal_structures_flag = FALSE;
8066 }
8067 else
8068 internal_structures_flag = TRUE;
8069
8070 }
8071
8072 }
8073
8074 if(n_rows < 0)
8075 {
8076 CMAfreeOutlineField(&of);
8077 errno = 0;
8078 ErrorReturn(ERROR_BADPARM,
8079 (ERROR_BADPARM,
8080 "bad or undefined ROW_NUM in otl file %d", slice));
8081 }
8082
8083 if(n_cols != 2)
8084 {
8085 CMAfreeOutlineField(&of);
8086 errno = 0;
8087 ErrorReturn(ERROR_BADPARM,
8088 (ERROR_BADPARM,
8089 "bad or undefined COL_NUM in otl file %d", slice));
8090 }
8091
8092 if(label[0] == '\0')
8093 {
8094 empty_label_flag = 1;
8095 errno = 0;
8096 ErrorPrintf(ERROR_BADPARM,
8097 "empty LABEL in otl file %d (outline %d)", slice, i);
8098 }
8099
8100 if(seed_x < 0 || seed_x >= 512 || seed_y < 0 || seed_y >= 512)
8101 {
8102 CMAfreeOutlineField(&of);
8103 errno = 0;
8104 ErrorReturn(ERROR_BADPARM,
8105 (ERROR_BADPARM,
8106 "bad or undefined SEED in otl file %d", slice));
8107 }
8108
8109 if(type[0] == '\0')
8110 strcpy(type, global_type);
8111
8112 if(strcmp(type, "ascii short") == 0)
8113 ascii_short_flag = TRUE;
8114 else if(strcmp(type, "short") == 0)
8115 ascii_short_flag = FALSE;
8116 else if(type[0] == '\0')
8117 {
8118 CMAfreeOutlineField(&of);
8119 errno = 0;
8120 ErrorReturn(ERROR_UNSUPPORTED,
8121 (ERROR_UNSUPPORTED,
8122 "undefined TYPE in otl file %d", slice));
8123 }
8124 else
8125 {
8126 CMAfreeOutlineField(&of);
8127 errno = 0;
8128 ErrorReturn(ERROR_UNSUPPORTED,
8129 (ERROR_UNSUPPORTED,
8130 "unsupported TYPE \"%s\" in otl file %d", type, slice));
8131 }
8132
8133 do
8134 {
8135 fgets(line, STRLEN, fp);
8136 if(feof(fp))
8137 {
8138 CMAfreeOutlineField(&of);
8139 errno = 0;
8140 ErrorReturn
8141 (ERROR_BADFILE,
8142 (ERROR_BADFILE,
8143 "premature EOF (searching for points) in otl file %d",
8144 slice));
8145 }
8146 } while(strncmp(line, "START POINTS", 12) != 0);
8147
8148 points = (short *)malloc(2 * n_rows * sizeof(short));
8149 if(points == NULL)
8150 {
8151 CMAfreeOutlineField(&of);
8152 errno = 0;
8153 ErrorReturn
8154 (ERROR_NOMEMORY,
8155 (ERROR_NOMEMORY,
8156 "error allocating memory for points in otl file %d", slice));
8157 }
8158
8159 if(ascii_short_flag)
8160 {
8161 for(row = 0;row < n_rows;row++)
8162 {
8163 fgets(line, STRLEN, fp);
8164 if(feof(fp))
8165 {
8166 free(points);
8167 CMAfreeOutlineField(&of);
8168 errno = 0;
8169 ErrorReturn
8170 (ERROR_BADFILE,
8171 (ERROR_BADFILE,
8172 "premature end of file while reading "
8173 "points from otl file %d",
8174 slice));
8175 }
8176 sscanf(line, "%hd %hd", &(points[2*row]), &(points[2*row+1]));
8177 }
8178 }
8179 else
8180 {
8181 n_read = fread(points, 2, n_rows * 2, fp);
8182 if(n_read != n_rows * 2)
8183 {
8184 free(points);
8185 CMAfreeOutlineField(&of);
8186 errno = 0;
8187 ErrorReturn(ERROR_BADFILE,
8188 (ERROR_BADFILE,
8189 "error reading points from otl file %d", slice));
8190 }
8191 #if (BYTE_ORDER == LITTLE_ENDIAN)
8192 swab(points, points, 2 * n_rows * sizeof(short));
8193 #endif
8194 }
8195
8196 fgets(line, STRLEN, fp);
8197 if(strncmp(line, "END POINTS", 10) != 0)
8198 {
8199 free(points);
8200 CMAfreeOutlineField(&of);
8201 errno = 0;
8202 ErrorReturn
8203 (ERROR_BADFILE,
8204 (ERROR_BADFILE,
8205 "error after points (\"END POINTS\" expected "
8206 "but not found) in otl file %d", slice));
8207 }
8208
8209 if(!empty_label_flag)
8210 {
8211 strcpy(label_to_compare, label);
8212 for(j = 0;label_to_compare[j] != '\0';j++)
8213 {
8214 if(label_to_compare[j] == '\n')
8215 label_to_compare[j] = '\0';
8216 if(label_to_compare[j] == ' ')
8217 label_to_compare[j] = '-';
8218 }
8219
8220 /* --- strip 'Left' and 'Right'; --- */
8221 strcpy(alt_compare, label_to_compare);
8222 StrLower(alt_compare);
8223 if(strncmp(alt_compare, "left-", 5) == 0)
8224 strcpy(alt_compare, &(label_to_compare[5]));
8225 else if(strncmp(alt_compare, "right-", 6) == 0)
8226 strcpy(alt_compare, &(label_to_compare[6]));
8227
8228 /* --- strip leading and trailing spaces (now dashes) --- */
8229
8230 /* leading */
8231 for(j = 0;label_to_compare[j] == '-';j++);
8232 if(label_to_compare[j] != '\0')
8233 {
8234 for(c = label_to_compare;*(c+j) != '\0';c++)
8235 *c = *(c+j);
8236 *c = *(c+j);
8237 }
8238
8239 /* trailing */
8240 for(j = strlen(label_to_compare) - 1;
8241 j >= 0 && label_to_compare[j] == '-';
8242 j--);
8243 if(j < 0) /* all dashes! */
8244 {
8245 /* for now, let this fall through to an unknown label */
8246 }
8247 else /* j is the index of the last non-dash character */
8248 {
8249 label_to_compare[j+1] = '\0';
8250 }
8251
8252
8253 label_value = -1;
8254 for(j = 0;j < color_table->mnNumEntries;j++)
8255 if(strcmp(color_table->maEntries[j].msLabel,
8256 label_to_compare) == 0 ||
8257 strcmp(color_table->maEntries[j].msLabel, alt_compare) == 0)
8258 label_value = j;
8259
8260 if(label_value == -1)
8261 {
8262 register_unknown_label(label);
8263 }
8264 else
8265 {
8266
8267 for(j = 0;j < n_rows;j++)
8268 cma_field[points[2*j]][points[2*j+1]] = label_value;
8269
8270 CMAclaimPoints(of, label_value, points, n_rows, seed_x, seed_y);
8271
8272 }
8273
8274 }
8275
8276 free(points);
8277
8278 }
8279
8280 CMAassignLabels(of);
8281
8282 if(zero_outlines_flag)
8283 CMAzeroOutlines(of);
8284
8285 scale_x = 512 / mri->width;
8286 scale_y = 512 / mri->height;
8287
8288 for(i = 0;i < mri->width;i++)
8289 for(j = 0;j < mri->height;j++)
8290 {
8291 source_x = (int)floor(scale_x * (float)i);
8292 source_y = (int)floor(scale_y * (float)j);
8293 if(source_x < 0)
8294 source_x = 0;
8295 if(source_x > 511)
8296 source_x = 511;
8297 if(source_y < 0)
8298 source_y = 0;
8299 if(source_y > 511)
8300 source_y = 511;
8301 MRISvox(mri, i, j, slice-1) = of->fill_field[source_y][source_x];
8302 }
8303
8304 CMAfreeOutlineField(&of);
8305
8306 return(NO_ERROR);
8307
8308 } /* end read_otl_file() */
8309
8310 MRI *MRIreadOtl
8311 (char *fname, int width, int height, int slices,
8312 char *color_file_name, int flags)
8313 {
8314
8315 char stem[STRLEN];
8316 int i;
8317 MRI *mri;
8318 char *c;
8319 int one_file_exists;
8320 char first_name[STRLEN], last_name[STRLEN];
8321 FILE *fp;
8322 mriColorLookupTableRef color_table;
8323 int read_volume_flag, fill_flag, translate_labels_flag, zero_outlines_flag;
8324
8325 /* ----- set local flags ----- */
8326
8327 read_volume_flag = FALSE;
8328 fill_flag = FALSE;
8329 translate_labels_flag = FALSE;
8330 zero_outlines_flag = FALSE;
8331
8332 if(flags & READ_OTL_READ_VOLUME_FLAG)
8333 read_volume_flag = TRUE;
8334
8335 if(flags & READ_OTL_FILL_FLAG)
8336 fill_flag = TRUE;
8337
8338 if(flags & READ_OTL_TRANSLATE_LABELS_FLAG)
8339 translate_labels_flag = TRUE;
8340
8341 if(flags & READ_OTL_ZERO_OUTLINES_FLAG)
8342 zero_outlines_flag = TRUE;
8343
8344 /* ----- reset our unknown label list ----- */
8345
8346 clear_unknown_labels();
8347
8348 /* ----- defaults to width and height ----- */
8349 if(width <= 0)
8350 width = 512;
8351 if(height <= 0)
8352 height = 512;
8353
8354 /* ----- strip the stem of the otl file name ----- */
8355 strcpy(stem, fname);
8356 c = strrchr(stem, '.');
8357 if(c == NULL)
8358 {
8359 errno = 0;
8360 ErrorReturn
8361 (NULL, (ERROR_BADPARM, "MRIreadOtl(): bad file name: %s", fname));
8362 }
8363
8364 for(c--;c >= stem && isdigit(*c);c--);
8365
8366 if(c < stem)
8367 {
8368 errno = 0;
8369 ErrorReturn
8370 (NULL, (ERROR_BADPARM, "MRIreadOtl(): bad file name: %s", fname));
8371 }
8372
8373 c++;
8374
8375 one_file_exists = FALSE;
8376 for(i = 1;i <= slices;i++)
8377 {
8378 sprintf(c, "%d.otl", i);
8379 if(FileExists(stem))
8380 one_file_exists = TRUE;
8381 if(i == 1)
8382 strcpy(first_name, stem);
8383 }
8384
8385 strcpy(last_name, stem);
8386
8387 if(!one_file_exists)
8388 {
8389 errno = 0;
8390 ErrorReturn
8391 (NULL,
8392 (ERROR_BADPARM,
8393 "MRIreadOtl(): couldn't find any file between %s and %s",
8394 first_name, last_name));
8395 }
8396
8397 if(!read_volume_flag)
8398 {
8399 mri = MRIallocHeader(width, height, slices, MRI_SHORT);
8400 if(mri == NULL)
8401 {
8402 errno = 0;
8403 ErrorReturn
8404 (NULL,
8405 (ERROR_NOMEMORY,
8406 "MRIreadOtl(): error allocating MRI structure"));
8407 }
8408 return(mri);
8409 }
8410 mri = MRIalloc(width, height, slices, MRI_SHORT);
8411 if(mri == NULL)
8412 {
8413 errno = 0;
8414 ErrorReturn
8415 (NULL,
8416 (ERROR_NOMEMORY,
8417 "MRIreadOtl(): error allocating MRI structure"));
8418 }
8419
8420 if(CLUT_NewFromFile(&color_table, color_file_name) != CLUT_tErr_NoErr)
8421 {
8422 MRIfree(&mri);
8423 errno = 0;
8424 ErrorReturn
8425 (NULL,
8426 (ERROR_BADFILE,
8427 "MRIreadOtl(): error reading color file %s", color_file_name));
8428 }
8429
8430 one_file_exists = FALSE;
8431 for(i = 1;i <= slices;i++)
8432 {
8433 sprintf(c, "%d.otl", i);
8434 if((fp = fopen(stem, "r")) != NULL)
8435 {
8436 if(read_otl_file
8437 (fp, mri, i, color_table, fill_flag, \
8438 translate_labels_flag, zero_outlines_flag) != NO_ERROR)
8439 {
8440 MRIfree(&mri);
8441 return(NULL);
8442 }
8443 one_file_exists = TRUE;
8444 }
8445 }
8446
8447 CLUT_Delete(&color_table);
8448
8449 if(!one_file_exists)
8450 {
8451 MRIfree(&mri);
8452 errno = 0;
8453 ErrorReturn
8454 (NULL,
8455 (ERROR_BADFILE,
8456 "MRIreadOtl(): found at least one file "
8457 "between %s and %s but couldn't open it!", first_name, last_name));
8458 }
8459
8460 if(n_unknown_labels == 0)
8461 {
8462 printf("no unknown labels\n");
8463 }
8464 else
8465 {
8466 printf("unknown labels:\n");
8467 print_unknown_labels(" ");
8468 }
8469 clear_unknown_labels();
8470
8471 // default direction cosine set here to be CORONAL
8472 // no orientation info is given and thus set to coronal
8473 setDirectionCosine(mri, MRI_CORONAL);
8474
8475 return(mri);
8476
8477 } /* end MRIreadOtl() */
8478
8479 #define XIMG_PIXEL_DATA_OFFSET 8432
8480 #define XIMG_IMAGE_HEADER_OFFSET 2308
8481
8482 static MRI *ximgRead(char *fname, int read_volume)
8483 {
8484
8485 char fname_format[STRLEN];
8486 char fname_dir[STRLEN];
8487 char fname_base[STRLEN];
8488 char *c;
8489 MRI *mri = NULL;
8490 int im_init;
8491 int im_low, im_high;
8492 char fname_use[STRLEN];
8493 char temp_string[STRLEN];
8494 FILE *fp;
8495 int width, height;
8496 int pixel_data_offset;
8497 int image_header_offset;
8498 float tl_r, tl_a, tl_s;
8499 float tr_r, tr_a, tr_s;
8500 float br_r, br_a, br_s;
8501 float c_r, c_a, c_s;
8502 float n_r, n_a, n_s;
8503 float xlength, ylength, zlength;
8504 int i, y;
8505 MRI *header;
8506 float xfov, yfov, zfov;
8507 float nlength;
8508
8509 printf("XIMG: using XIMG header corrections\n");
8510
8511 /* ----- check the first (passed) file ----- */
8512 if(!FileExists(fname))
8513 {
8514 errno = 0;
8515 ErrorReturn
8516 (NULL,
8517 (ERROR_BADFILE, "genesisRead(): error opening file %s", fname));
8518 }
8519
8520 /* ----- split the file name into name and directory ----- */
8521 c = strrchr(fname, '/');
8522 if(c == NULL)
8523 {
8524 fname_dir[0] = '\0';
8525 strcpy(fname_base, fname);
8526 }
8527 else
8528 {
8529 strncpy(fname_dir, fname, (c - fname + 1));
8530 fname_dir[c-fname+1] = '\0';
8531 strcpy(fname_base, c+1);
8532 }
8533
8534 /* ----- derive the file name format (for sprintf) ----- */
8535 if(strncmp(fname_base, "I.", 2) == 0)
8536 {
8537 im_init = atoi(&fname_base[2]);
8538 sprintf(fname_format, "I.%%03d");
8539 }
8540 else if(strlen(fname_base) >= 3) /* avoid core dumps below... */
8541 {
8542 c = &fname_base[strlen(fname_base)-3];
8543 if(strcmp(c, ".MR") == 0)
8544 {
8545 *c = '\0';
8546 for(c--;isdigit(*c) && c >= fname_base;c--);
8547 c++;
8548 im_init = atoi(c);
8549 *c = '\0';
8550 sprintf(fname_format, "%s%%d.MR", fname_base);
8551 }
8552 else
8553 {
8554 errno = 0;
8555 ErrorReturn
8556 (NULL,
8557 (ERROR_BADPARM,
8558 "genesisRead(): can't determine file name format for %s",
8559 fname));
8560 }
8561 }
8562 else
8563 {
8564 errno = 0;
8565 ErrorReturn
8566 (NULL,
8567 (ERROR_BADPARM,
8568 "genesisRead(): can't determine file name format for %s", fname));
8569 }
8570
8571 strcpy(temp_string, fname_format);
8572 sprintf(fname_format, "%s%s", fname_dir, temp_string);
8573
8574 /* ----- find the low and high files ----- */
8575 im_low = im_init;
8576 do
8577 {
8578 im_low--;
8579 sprintf(fname_use, fname_format, im_low);
8580 } while(FileExists(fname_use));
8581 im_low++;
8582
8583 im_high = im_init;
8584 do
8585 {
8586 im_high++;
8587 sprintf(fname_use, fname_format, im_high);
8588 } while(FileExists(fname_use));
8589 im_high--;
8590
8591 /* ----- allocate the mri structure ----- */
8592 header = MRIallocHeader(1, 1, 1, MRI_SHORT);
8593
8594 header->depth = im_high - im_low + 1;
8595 header->imnr0 = 1;
8596 header->imnr1 = header->depth;
8597
8598 /* ----- get the header information from the first file ----- */
8599 sprintf(fname_use, fname_format, im_low);
8600 if((fp = fopen(fname_use, "r")) == NULL)
8601 {
8602 MRIfree(&header);
8603 errno = 0;
8604 ErrorReturn
8605 (NULL,
8606 (ERROR_BADFILE, "genesisRead(): error opening file %s\n", fname_use));
8607 }
8608
8609 fseek(fp, 4, SEEK_SET);
8610 fread(&pixel_data_offset, 4, 1, fp);
8611 pixel_data_offset = orderIntBytes(pixel_data_offset);
8612 printf("XIMG: pixel data offset is %d, ", pixel_data_offset);
8613 if(pixel_data_offset != XIMG_PIXEL_DATA_OFFSET)
8614 pixel_data_offset = XIMG_PIXEL_DATA_OFFSET;
8615 printf("using offset %d\n", pixel_data_offset);
8616
8617 fseek(fp, 8, SEEK_SET);
8618 fread(&width, 4, 1, fp); width = orderIntBytes(width);
8619 fread(&height, 4, 1, fp); height = orderIntBytes(height);
8620
8621 fseek(fp, 148, SEEK_SET);
8622 fread(&image_header_offset, 4, 1, fp);
8623 image_header_offset = orderIntBytes(image_header_offset);
8624 printf("XIMG: image header offset is %d, ", image_header_offset);
8625 if(image_header_offset != XIMG_IMAGE_HEADER_OFFSET)
8626 image_header_offset = XIMG_IMAGE_HEADER_OFFSET;
8627 printf("using offset %d\n", image_header_offset);
8628
8629 header->width = width;
8630 header->height = height;
8631
8632 strcpy(header->fname, fname);
8633
8634 fseek(fp, image_header_offset + 26 + 2, SEEK_SET);
8635 fread(&(header->thick), 4, 1, fp);
8636 header->thick = orderFloatBytes(header->thick);
8637 header->zsize = header->thick;
8638
8639 fseek(fp, image_header_offset + 50 + 2, SEEK_SET);
8640 fread(&(header->xsize), 4, 1, fp);
8641 header->xsize = orderFloatBytes(header->xsize);
8642 fread(&(header->ysize), 4, 1, fp);
8643 header->ysize = orderFloatBytes(header->ysize);
8644 header->ps = header->xsize;
8645
8646 /* all in micro-seconds */
8647 #define MICROSECONDS_PER_MILLISECOND 1e3
8648 fseek(fp, image_header_offset + 194 + 6, SEEK_SET);
8649 header->tr = freadInt(fp)/MICROSECONDS_PER_MILLISECOND ;
8650 fseek(fp, image_header_offset + 198, SEEK_SET);
8651 header->ti = freadInt(fp)/MICROSECONDS_PER_MILLISECOND ;
8652 fseek(fp, image_header_offset + 202, SEEK_SET);
8653 header->te = freadInt(fp)/MICROSECONDS_PER_MILLISECOND ;
8654 fseek(fp, image_header_offset + 254, SEEK_SET);
8655 header->flip_angle = RADIANS(freadShort(fp)) ; /* was in degrees */
8656
8657 fseek(fp, image_header_offset + 130 + 6, SEEK_SET);
8658 fread(&c_r, 4, 1, fp); c_r = orderFloatBytes(c_r);
8659 fread(&c_a, 4, 1, fp); c_a = orderFloatBytes(c_a);
8660 fread(&c_s, 4, 1, fp); c_s = orderFloatBytes(c_s);
8661 fread(&n_r, 4, 1, fp); n_r = orderFloatBytes(n_r);
8662 fread(&n_a, 4, 1, fp); n_a = orderFloatBytes(n_a);
8663 fread(&n_s, 4, 1, fp); n_s = orderFloatBytes(n_s);
8664 fread(&tl_r, 4, 1, fp); tl_r = orderFloatBytes(tl_r);
8665 fread(&tl_a, 4, 1, fp); tl_a = orderFloatBytes(tl_a);
8666 fread(&tl_s, 4, 1, fp); tl_s = orderFloatBytes(tl_s);
8667 fread(&tr_r, 4, 1, fp); tr_r = orderFloatBytes(tr_r);
8668 fread(&tr_a, 4, 1, fp); tr_a = orderFloatBytes(tr_a);
8669 fread(&tr_s, 4, 1, fp); tr_s = orderFloatBytes(tr_s);
8670 fread(&br_r, 4, 1, fp); br_r = orderFloatBytes(br_r);
8671 fread(&br_a, 4, 1, fp); br_a = orderFloatBytes(br_a);
8672 fread(&br_s, 4, 1, fp); br_s = orderFloatBytes(br_s);
8673
8674 nlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
8675 n_r = n_r / nlength;
8676 n_a = n_a / nlength;
8677 n_s = n_s / nlength;
8678
8679 if (getenv("KILLIANY_SWAP") != NULL)
8680 {
8681 printf("WARNING - swapping normal direction!\n") ;
8682 n_a *= -1 ;
8683 }
8684
8685 header->x_r = (tr_r - tl_r);
8686 header->x_a = (tr_a - tl_a);
8687 header->x_s = (tr_s - tl_s);
8688 header->y_r = (br_r - tr_r);
8689 header->y_a = (br_a - tr_a);
8690 header->y_s = (br_s - tr_s);
8691
8692 /* --- normalize -- the normal vector from the file
8693 should have length 1, but just in case... --- */
8694 xlength = sqrt(header->x_r*header->x_r +
8695 header->x_a*header->x_a +
8696 header->x_s*header->x_s);
8697 ylength = sqrt(header->y_r*header->y_r +
8698 header->y_a*header->y_a +
8699 header->y_s*header->y_s);
8700 zlength = sqrt(n_r*n_r + n_a*n_a + n_s*n_s);
8701
8702 header->x_r = header->x_r / xlength;
8703 header->x_a = header->x_a / xlength;
8704 header->x_s = header->x_s / xlength;
8705 header->y_r = header->y_r / ylength;
8706 header->y_a = header->y_a / ylength;
8707 header->y_s = header->y_s / ylength;
8708 header->z_r = n_r / zlength;
8709 header->z_a = n_a / zlength;
8710 header->z_s = n_s / zlength;
8711
8712 header->c_r = (tl_r + br_r) / 2.0 + n_r * header->zsize *
8713 (header->depth - 1.0) / 2.0;
8714 header->c_a = (tl_a + br_a) / 2.0 + n_a * header->zsize *
8715 (header->depth - 1.0) / 2.0;
8716 header->c_s = (tl_s + br_s) / 2.0 + n_s * header->zsize *
8717 (header->depth - 1.0) / 2.0;
8718
8719 header->ras_good_flag = 1;
8720
8721 header->xend = header->xsize * header->width / 2;
8722 header->xstart = -header->xend;
8723 header->yend = header->ysize * header->height / 2;
8724 header->ystart = -header->yend;
8725 header->zend = header->zsize * header->depth / 2;
8726 header->zstart = -header->zend;
8727
8728 xfov = header->xend - header->xstart;
8729 yfov = header->yend - header->ystart;
8730 zfov = header->zend - header->zstart;
8731
8732 header->fov =
8733 (xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
8734
8735 fclose(fp);
8736
8737 if(read_volume)
8738 mri = MRIalloc
8739 (header->width, header->height, header->depth, header->type);
8740 else
8741 mri = MRIallocHeader
8742 (header->width, header->height, header->depth, header->type);
8743
8744 MRIcopyHeader(header, mri);
8745 MRIfree(&header);
8746
8747 /* ----- read the volume if required ----- */
8748 if(read_volume)
8749 {
8750
8751 for(i = im_low;i <= im_high;i++)
8752 {
8753
8754 sprintf(fname_use, fname_format, i);
8755 if((fp = fopen(fname_use, "r")) == NULL)
8756 {
8757 MRIfree(&mri);
8758 errno = 0;
8759 ErrorReturn
8760 (NULL,
8761 (ERROR_BADFILE,
8762 "genesisRead(): error opening file %s", fname_use));
8763 }
8764
8765 /*
8766 fseek(fp, 4, SEEK_SET);
8767 fread(&pixel_data_offset, 4, 1, fp);
8768 pixel_data_offset = orderIntBytes(pixel_data_offset);
8769 */
8770 pixel_data_offset = XIMG_PIXEL_DATA_OFFSET;
8771 fseek(fp, pixel_data_offset, SEEK_SET);
8772
8773 for(y = 0;y < mri->height;y++)
8774 {
8775 if(fread(mri->slices[i-im_low][y], 2, mri->width, fp) !=
8776 mri->width)
8777 {
8778 fclose(fp);
8779 MRIfree(&mri);
8780 errno = 0;
8781 ErrorReturn
8782 (NULL,
8783 (ERROR_BADFILE,
8784 "genesisRead(): error reading from file file %s",
8785 fname_use));
8786 }
8787 #if (BYTE_ORDER == LITTLE_ENDIAN)
8788 swab(mri->slices[i-im_low][y],
8789 mri->slices[i-im_low][y], 2 * mri->width);
8790 #endif
8791 }
8792
8793 fclose(fp);
8794
8795 }
8796
8797 }
8798
8799 return(mri);
8800
8801 } /* end ximgRead() */
8802
8803 /*-----------------------------------------------------------
8804 MRISreadCurvAsMRI() - reads freesurfer surface curv format
8805 as an MRI.
8806 -----------------------------------------------------------*/
8807 static MRI *MRISreadCurvAsMRI(char *curvfile, int read_volume)
8808 {
8809 int magno,k,vnum,fnum, vals_per_vertex ;
8810 float curv;
8811 FILE *fp;
8812 MRI *curvmri;
8813
8814 if(!IDisCurv(curvfile)) return(NULL);
8815
8816 fp = fopen(curvfile,"r");
8817 fread3(&magno,fp);
8818
8819 vnum = freadInt(fp);
8820 fnum = freadInt(fp);
8821 vals_per_vertex = freadInt(fp) ;
8822 if (vals_per_vertex != 1){
8823 fclose(fp) ;
8824 printf("ERROR: MRISreadCurvAsMRI: %s, vals/vertex %d unsupported\n",
8825 curvfile,vals_per_vertex);
8826 return(NULL);
8827 }
8828
8829 if(!read_volume){
8830 curvmri = MRIallocHeader(vnum, 1,1,MRI_FLOAT);
8831 curvmri->nframes = 1;
8832 return(curvmri);
8833 }
8834
8835 curvmri = MRIalloc(vnum,1,1,MRI_FLOAT);
8836 for (k=0;k<vnum;k++){
8837 curv = freadFloat(fp) ;
8838 MRIsetVoxVal(curvmri,k,0,0,0,curv);
8839 }
8840 fclose(fp);
8841
8842 return(curvmri) ;
8843 }
8844
8845 /*------------------------------------------------------------------
8846 nifti1Read() - note: there is also an niiRead(). Make sure to
8847 edit both. NIFTI1 is defined to be the two-file NIFTI standard, ie,
8848 there must be a .img and .hdr file. (see is_nifti1(char *fname))
8849 -----------------------------------------------------------------*/
8850 static MRI *nifti1Read(char *fname, int read_volume)
8851 {
8852
8853 char hdr_fname[STRLEN];
8854 char img_fname[STRLEN];
8855 char fname_stem[STRLEN];
8856 char *dot;
8857 FILE *fp;
8858 MRI *mri;
8859 struct nifti_1_header hdr;
8860 int nslices;
8861 int fs_type;
8862 float time_units_factor, space_units_factor;
8863 int swapped_flag;
8864 int n_read, i, j, k, t;
8865 int bytes_per_voxel, time_units, space_units;
8866
8867 strcpy(fname_stem, fname);
8868 dot = strrchr(fname_stem, '.');
8869 if(dot != NULL)
8870 if(strcmp(dot, ".img") == 0 || strcmp(dot, ".hdr") == 0)
8871 *dot = '\0';
8872
8873 sprintf(hdr_fname, "%s.hdr", fname_stem);
8874 sprintf(img_fname, "%s.img", fname_stem);
8875
8876 fp = fopen(hdr_fname, "r");
8877 if(fp == NULL)
8878 {
8879 errno = 0;
8880 ErrorReturn
8881 (NULL,
8882 (ERROR_BADFILE, "nifti1Read(): error opening file %s", hdr_fname));
8883 }
8884
8885 if(fread(&hdr, sizeof(hdr), 1, fp) != 1)
8886 {
8887 fclose(fp);
8888 errno = 0;
8889 ErrorReturn
8890 (NULL,
8891 (ERROR_BADFILE,
8892 "nifti1Read(): error reading header from %s", hdr_fname));
8893 }
8894
8895 fclose(fp);
8896
8897 swapped_flag = FALSE;
8898 if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
8899 swapped_flag = TRUE;
8900 swap_nifti_1_header(&hdr);
8901 if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
8902 ErrorReturn
8903 (NULL,
8904 (ERROR_BADFILE,
8905 "nifti1Read(): bad number of dimensions (%hd) in %s",
8906 hdr.dim[0], hdr_fname));
8907 }
8908 }
8909
8910 if(memcmp(hdr.magic, NIFTI1_MAGIC, 4) != 0)
8911 ErrorReturn
8912 (NULL,
8913 (ERROR_BADFILE,
8914 "nifti1Read(): bad magic number in %s", hdr_fname));
8915
8916 if(hdr.dim[0] != 3 && hdr.dim[0] != 4)
8917 ErrorReturn
8918 (NULL,
8919 (ERROR_UNSUPPORTED,
8920 "nifti1Read(): %hd dimensions in %s; unsupported",
8921 hdr.dim[0], hdr_fname));
8922
8923 if(hdr.datatype == DT_NONE || hdr.datatype == DT_UNKNOWN)
8924 ErrorReturn
8925 (NULL,
8926 (ERROR_UNSUPPORTED,
8927 "nifti1Read(): unknown or no data type in %s; bailing out",
8928 hdr_fname));
8929
8930 space_units = XYZT_TO_SPACE(hdr.xyzt_units) ;
8931 if(space_units ==NIFTI_UNITS_METER) space_units_factor = 1000.0;
8932 else if(space_units ==NIFTI_UNITS_MM) space_units_factor = 1.0;
8933 else if(space_units ==NIFTI_UNITS_MICRON) space_units_factor = 0.001;
8934 else
8935 {
8936 ErrorReturn
8937 (NULL,
8938 (ERROR_BADFILE,
8939 "nifti1Read(): unknown space units %d in %s",
8940 space_units,hdr_fname));
8941 }
8942
8943 time_units = XYZT_TO_TIME (hdr.xyzt_units) ;
8944 if(time_units == NIFTI_UNITS_SEC) time_units_factor = 1000.0;
8945 else if(time_units == NIFTI_UNITS_MSEC) time_units_factor = 1.0;
8946 else if(time_units == NIFTI_UNITS_USEC) time_units_factor = 0.001;
8947 else {
8948 if(hdr.dim[4] > 1){
8949 ErrorReturn
8950 (NULL,
8951 (ERROR_BADFILE,
8952 "nifti1Read(): unknown time units %d in %s",
8953 time_units,hdr_fname));
8954 }
8955 else time_units_factor = 0;
8956 }
8957
8958 /*
8959 nifti1.h says: slice_code = If this is nonzero, AND
8960 if slice_dim is nonzero, AND
8961 if slice_duration is positive, indicates the timing
8962 pattern of the slice acquisition.
8963 not yet supported here
8964 */
8965
8966 if(hdr.slice_code != 0 &&
8967 DIM_INFO_TO_SLICE_DIM(hdr.dim_info) != 0 &&
8968 hdr.slice_duration > 0.0)
8969 ErrorReturn
8970 (NULL,
8971 (ERROR_UNSUPPORTED,
8972 "nifti1Read(): unsupported timing pattern in %s", hdr_fname));
8973
8974 if(hdr.dim[0] == 3) nslices = 1;
8975 else nslices = hdr.dim[4];
8976
8977 if(hdr.scl_slope == 0)
8978 // voxel values are unscaled -- we use the file's data type
8979 {
8980
8981 if(hdr.datatype == DT_UNSIGNED_CHAR)
8982 {
8983 fs_type = MRI_UCHAR;
8984 bytes_per_voxel = 1;
8985 }
8986 else if(hdr.datatype == DT_SIGNED_SHORT)
8987 {
8988 fs_type = MRI_SHORT;
8989 bytes_per_voxel = 2;
8990 }
8991 else if(hdr.datatype == DT_SIGNED_INT)
8992 {
8993 fs_type = MRI_INT;
8994 bytes_per_voxel = 4;
8995 }
8996 else if(hdr.datatype == DT_FLOAT)
8997 {
8998 fs_type = MRI_FLOAT;
8999 bytes_per_voxel = 4;
9000 }
9001 else
9002 {
9003 ErrorReturn
9004 (NULL,
9005 (ERROR_UNSUPPORTED,
9006 "nifti1Read(): unsupported datatype %d "
9007 "(with scl_slope = 0) in %s",
9008 hdr.datatype, hdr_fname));
9009 }
9010 }
9011 else // we must scale the voxel values
9012 {
9013 if( hdr.datatype != DT_UNSIGNED_CHAR
9014 && hdr.datatype != DT_SIGNED_SHORT
9015 && hdr.datatype != DT_SIGNED_INT
9016 && hdr.datatype != DT_FLOAT
9017 && hdr.datatype != DT_DOUBLE
9018 && hdr.datatype != DT_INT8
9019 && hdr.datatype != DT_UINT16
9020 && hdr.datatype != DT_UINT32)
9021 {
9022 ErrorReturn
9023 (NULL,
9024 (ERROR_UNSUPPORTED,
9025 "nifti1Read(): unsupported datatype %d "
9026 "(with scl_slope != 0) in %s",
9027 hdr.datatype, hdr_fname));
9028 }
9029 fs_type = MRI_FLOAT;
9030 bytes_per_voxel = 0; /* set below -- this line is to
9031 avoid the compiler warning */
9032 }
9033
9034 if(read_volume)
9035 mri = MRIallocSequence
9036 (hdr.dim[1], hdr.dim[2], hdr.dim[3], fs_type, nslices);
9037 else
9038 {
9039 mri = MRIallocHeader(hdr.dim[1], hdr.dim[2], hdr.dim[3], fs_type);
9040 mri->nframes = nslices;
9041 }
9042
9043 if(mri == NULL)
9044 return(NULL);
9045
9046 mri->xsize = hdr.pixdim[1];
9047 mri->ysize = hdr.pixdim[2];
9048 mri->zsize = hdr.pixdim[3];
9049 // Keep in msec as NIFTI_UNITS_MSEC is specified
9050 if(hdr.dim[0] == 4) mri->tr = hdr.pixdim[4];
9051
9052 if(hdr.qform_code == 0){
9053 printf("WARNING: missing NIfTI-1 orientation (qform_code = 0)\n");
9054 printf("WARNING: your volume will probably be incorrectly oriented\n");
9055 mri->x_r = 1.0; mri->x_a = 0.0; mri->x_s = 0.0;
9056 mri->y_r = 0.0; mri->y_a = 1.0; mri->y_s = 0.0;
9057 mri->z_r = 0.0; mri->z_a = 0.0; mri->z_s = 1.0;
9058 mri->c_r = mri->xsize * mri->width / 2.0;
9059 mri->c_a = mri->ysize * mri->height / 2.0;
9060 mri->c_s = mri->zsize * mri->depth / 2.0;
9061 }
9062 else if(hdr.sform_code <= 0){
9063 if(niftiQformToMri(mri, &hdr) != NO_ERROR){
9064 MRIfree(&mri);
9065 return(NULL);
9066 }
9067 }
9068 else{
9069 if(niftiSformToMri(mri, &hdr) != NO_ERROR){
9070 MRIfree(&mri);
9071 return(NULL);
9072 }
9073 }
9074
9075 mri->xsize = mri->xsize * space_units_factor;
9076 mri->ysize = mri->ysize * space_units_factor;
9077 mri->zsize = mri->zsize * space_units_factor;
9078 mri->c_r = mri->c_r * space_units_factor;
9079 mri->c_a = mri->c_a * space_units_factor;
9080 mri->c_s = mri->c_s * space_units_factor;
9081 if(hdr.dim[0] == 4)
9082 mri->tr = mri->tr * time_units_factor;
9083
9084 if(!read_volume)
9085 return(mri);
9086
9087 fp = fopen(img_fname, "r");
9088 if(fp == NULL){
9089 MRIfree(&mri);
9090 errno = 0;
9091 ErrorReturn
9092 (NULL,
9093 (ERROR_BADFILE, "nifti1Read(): error opening file %s", img_fname));
9094 }
9095
9096 if(hdr.scl_slope == 0) // no voxel value scaling needed
9097 {
9098
9099 void *buf;
9100
9101 for(t = 0;t < mri->nframes;t++)
9102 for(k = 0;k < mri->depth;k++)
9103 for(j = 0;j < mri->height;j++)
9104 {
9105
9106 buf = &MRIseq_vox(mri, 0, j, k, t);
9107
9108 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9109 if(n_read != mri->width)
9110 {
9111 fclose(fp);
9112 MRIfree(&mri);
9113 errno = 0;
9114 ErrorReturn
9115 (NULL,
9116 (ERROR_BADFILE,
9117 "nifti1Read(): error reading from %s", img_fname));
9118 }
9119
9120 if(swapped_flag)
9121 {
9122 if(bytes_per_voxel == 2)
9123 byteswapbufshort(buf, bytes_per_voxel * mri->width);
9124 if(bytes_per_voxel == 4)
9125 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9126 }
9127
9128 }
9129
9130 }
9131 else // voxel value scaling needed
9132 {
9133
9134 if(hdr.datatype == DT_UNSIGNED_CHAR)
9135 {
9136 unsigned char *buf;
9137 bytes_per_voxel = 1;
9138 buf = (unsigned char *)malloc(mri->width * bytes_per_voxel);
9139 for(t = 0;t < mri->nframes;t++)
9140 for(k = 0;k < mri->depth;k++)
9141 for(j = 0;j < mri->height;j++)
9142 {
9143 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9144 if(n_read != mri->width)
9145 {
9146 free(buf);
9147 fclose(fp);
9148 MRIfree(&mri);
9149 errno = 0;
9150 ErrorReturn
9151 (NULL,
9152 (ERROR_BADFILE,
9153 "nifti1Read(): error reading from %s", img_fname));
9154 }
9155 for(i = 0;i < mri->width;i++)
9156 MRIFseq_vox(mri, i, j, k, t) =
9157 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9158 }
9159 free(buf);
9160 }
9161
9162 if(hdr.datatype == DT_SIGNED_SHORT)
9163 {
9164 short *buf;
9165 bytes_per_voxel = 2;
9166 buf = (short *)malloc(mri->width * bytes_per_voxel);
9167 for(t = 0;t < mri->nframes;t++)
9168 for(k = 0;k < mri->depth;k++)
9169 for(j = 0;j < mri->height;j++)
9170 {
9171 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9172 if(n_read != mri->width)
9173 {
9174 free(buf);
9175 fclose(fp);
9176 MRIfree(&mri);
9177 errno = 0;
9178 ErrorReturn
9179 (NULL,
9180 (ERROR_BADFILE,
9181 "nifti1Read(): error reading from %s", img_fname));
9182 }
9183 if(swapped_flag)
9184 byteswapbufshort(buf, bytes_per_voxel * mri->width);
9185 for(i = 0;i < mri->width;i++)
9186 MRIFseq_vox(mri, i, j, k, t) =
9187 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9188 }
9189 free(buf);
9190 }
9191
9192 if(hdr.datatype == DT_SIGNED_INT)
9193 {
9194 int *buf;
9195 bytes_per_voxel = 4;
9196 buf = (int *)malloc(mri->width * bytes_per_voxel);
9197 for(t = 0;t < mri->nframes;t++)
9198 for(k = 0;k < mri->depth;k++)
9199 for(j = 0;j < mri->height;j++)
9200 {
9201 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9202 if(n_read != mri->width)
9203 {
9204 free(buf);
9205 fclose(fp);
9206 MRIfree(&mri);
9207 errno = 0;
9208 ErrorReturn
9209 (NULL,
9210 (ERROR_BADFILE,
9211 "nifti1Read(): error reading from %s", img_fname));
9212 }
9213 if(swapped_flag)
9214 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9215 for(i = 0;i < mri->width;i++)
9216 MRIFseq_vox(mri, i, j, k, t) =
9217 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9218 }
9219 free(buf);
9220 }
9221
9222 if(hdr.datatype == DT_FLOAT)
9223 {
9224 float *buf;
9225 bytes_per_voxel = 4;
9226 buf = (float *)malloc(mri->width * bytes_per_voxel);
9227 for(t = 0;t < mri->nframes;t++)
9228 for(k = 0;k < mri->depth;k++)
9229 for(j = 0;j < mri->height;j++)
9230 {
9231 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9232 if(n_read != mri->width)
9233 {
9234 free(buf);
9235 fclose(fp);
9236 MRIfree(&mri);
9237 errno = 0;
9238 ErrorReturn
9239 (NULL,
9240 (ERROR_BADFILE,
9241 "nifti1Read(): error reading from %s", img_fname));
9242 }
9243 if(swapped_flag)
9244 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9245 for(i = 0;i < mri->width;i++)
9246 MRIFseq_vox(mri, i, j, k, t) =
9247 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9248 }
9249 free(buf);
9250 }
9251
9252 if(hdr.datatype == DT_DOUBLE)
9253 {
9254 double *buf;
9255 unsigned char *cbuf, ccbuf[8];
9256 bytes_per_voxel = 8;
9257 buf = (double *)malloc(mri->width * bytes_per_voxel);
9258 for(t = 0;t < mri->nframes;t++)
9259 for(k = 0;k < mri->depth;k++)
9260 for(j = 0;j < mri->height;j++)
9261 {
9262 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9263 if(n_read != mri->width)
9264 {
9265 free(buf);
9266 fclose(fp);
9267 MRIfree(&mri);
9268 errno = 0;
9269 ErrorReturn
9270 (NULL,
9271 (ERROR_BADFILE,
9272 "nifti1Read(): error reading from %s", img_fname));
9273 }
9274 if(swapped_flag)
9275 {
9276 for(i = 0;i < mri->width;i++)
9277 {
9278 cbuf = (unsigned char *)&buf[i];
9279 memcpy(ccbuf, cbuf, 8);
9280 cbuf[0] = ccbuf[7];
9281 cbuf[1] = ccbuf[6];
9282 cbuf[2] = ccbuf[5];
9283 cbuf[3] = ccbuf[4];
9284 cbuf[4] = ccbuf[3];
9285 cbuf[5] = ccbuf[2];
9286 cbuf[6] = ccbuf[1];
9287 cbuf[7] = ccbuf[0];
9288 }
9289 }
9290 for(i = 0;i < mri->width;i++)
9291 MRIFseq_vox(mri, i, j, k, t) =
9292 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9293 }
9294 free(buf);
9295 }
9296
9297 if(hdr.datatype == DT_INT8)
9298 {
9299 char *buf;
9300 bytes_per_voxel = 1;
9301 buf = (char *)malloc(mri->width * bytes_per_voxel);
9302 for(t = 0;t < mri->nframes;t++)
9303 for(k = 0;k < mri->depth;k++)
9304 for(j = 0;j < mri->height;j++)
9305 {
9306 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9307 if(n_read != mri->width)
9308 {
9309 free(buf);
9310 fclose(fp);
9311 MRIfree(&mri);
9312 errno = 0;
9313 ErrorReturn
9314 (NULL,
9315 (ERROR_BADFILE,
9316 "nifti1Read(): error reading from %s",
9317 img_fname));
9318 }
9319 for(i = 0;i < mri->width;i++)
9320 MRIFseq_vox(mri, i, j, k, t) =
9321 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9322 }
9323 free(buf);
9324 }
9325
9326 if(hdr.datatype == DT_UINT16)
9327 {
9328 unsigned short *buf;
9329 bytes_per_voxel = 2;
9330 buf = (unsigned short *)malloc(mri->width * bytes_per_voxel);
9331 for(t = 0;t < mri->nframes;t++)
9332 for(k = 0;k < mri->depth;k++)
9333 for(j = 0;j < mri->height;j++)
9334 {
9335 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9336 if(n_read != mri->width)
9337 {
9338 free(buf);
9339 fclose(fp);
9340 MRIfree(&mri);
9341 errno = 0;
9342 ErrorReturn
9343 (NULL,
9344 (ERROR_BADFILE,
9345 "nifti1Read(): error reading from %s",
9346 img_fname));
9347 }
9348 if(swapped_flag)
9349 byteswapbufshort(buf, bytes_per_voxel * mri->width);
9350 for(i = 0;i < mri->width;i++)
9351 MRIFseq_vox(mri, i, j, k, t) =
9352 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9353 }
9354 free(buf);
9355 }
9356
9357 if(hdr.datatype == DT_UINT32)
9358 {
9359 unsigned int *buf;
9360 bytes_per_voxel = 4;
9361 buf = (unsigned int *)malloc(mri->width * bytes_per_voxel);
9362 for(t = 0;t < mri->nframes;t++)
9363 for(k = 0;k < mri->depth;k++)
9364 for(j = 0;j < mri->height;j++)
9365 {
9366 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
9367 if(n_read != mri->width)
9368 {
9369 free(buf);
9370 fclose(fp);
9371 MRIfree(&mri);
9372 errno = 0;
9373 ErrorReturn
9374 (NULL,
9375 (ERROR_BADFILE,
9376 "nifti1Read(): error reading from %s",
9377 img_fname));
9378 }
9379 if(swapped_flag)
9380 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9381 for(i = 0;i < mri->width;i++)
9382 MRIFseq_vox(mri, i, j, k, t) =
9383 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9384 }
9385 free(buf);
9386 }
9387
9388 }
9389
9390 fclose(fp);
9391
9392 return(mri);
9393
9394 } /* end nifti1Read() */
9395
9396
9397 /*------------------------------------------------------------------
9398 nifti1Write() - note: there is also an niiWrite(). Make sure to
9399 edit both.
9400 -----------------------------------------------------------------*/
9401 static int nifti1Write(MRI *mri, char *fname)
9402 {
9403
9404 FILE *fp;
9405 int j, k, t;
9406 BUFTYPE *buf;
9407 struct nifti_1_header hdr;
9408 char fname_stem[STRLEN];
9409 char hdr_fname[STRLEN];
9410 char img_fname[STRLEN];
9411 char *dot;
9412 int error;
9413
9414 memset(&hdr, 0x00, sizeof(hdr));
9415
9416 hdr.sizeof_hdr = 348;
9417 hdr.dim_info = 0;
9418
9419 if(mri->nframes == 1){
9420 hdr.dim[0] = 3;
9421 hdr.dim[1] = mri->width;
9422 hdr.dim[2] = mri->height;
9423 hdr.dim[3] = mri->depth;
9424 hdr.pixdim[1] = mri->xsize;
9425 hdr.pixdim[2] = mri->ysize;
9426 hdr.pixdim[3] = mri->zsize;
9427 }
9428 else{
9429 hdr.dim[0] = 4;
9430 hdr.dim[1] = mri->width;
9431 hdr.dim[2] = mri->height;
9432 hdr.dim[3] = mri->depth;
9433 hdr.dim[4] = mri->nframes;
9434 hdr.pixdim[1] = mri->xsize;
9435 hdr.pixdim[2] = mri->ysize;
9436 hdr.pixdim[3] = mri->zsize;
9437 hdr.pixdim[4] = mri->tr/1000.0; // sec, see also xyzt_units
9438 }
9439
9440 if(mri->type == MRI_UCHAR){
9441 hdr.datatype = DT_UNSIGNED_CHAR;
9442 hdr.bitpix = 8;
9443 }
9444 else if(mri->type == MRI_INT)
9445 {
9446 hdr.datatype = DT_SIGNED_INT;
9447 hdr.bitpix = 32;
9448 }
9449 else if(mri->type == MRI_LONG)
9450 {
9451 hdr.datatype = DT_SIGNED_INT;
9452 hdr.bitpix = 32;
9453 }
9454 else if(mri->type == MRI_FLOAT)
9455 {
9456 hdr.datatype = DT_FLOAT;
9457 hdr.bitpix = 32;
9458 }
9459 else if(mri->type == MRI_SHORT)
9460 {
9461 hdr.datatype = DT_SIGNED_SHORT;
9462 hdr.bitpix = 16;
9463 }
9464 else if(mri->type == MRI_BITMAP)
9465 {
9466 ErrorReturn(ERROR_UNSUPPORTED,
9467 (ERROR_UNSUPPORTED,
9468 "nifti1Write(): data type MRI_BITMAP unsupported"));
9469 }
9470 else if(mri->type == MRI_TENSOR)
9471 {
9472 ErrorReturn(ERROR_UNSUPPORTED,
9473 (ERROR_UNSUPPORTED,
9474 "nifti1Write(): data type MRI_TENSOR unsupported"));
9475 }
9476 else
9477 {
9478 ErrorReturn(ERROR_BADPARM,
9479 (ERROR_BADPARM,
9480 "nifti1Write(): unknown data type %d", mri->type));
9481 }
9482
9483 hdr.intent_code = NIFTI_INTENT_NONE;
9484 hdr.intent_name[0] = '\0';
9485 hdr.vox_offset = 0;
9486 hdr.scl_slope = 0.0;
9487 hdr.slice_code = 0;
9488 hdr.xyzt_units = NIFTI_UNITS_MM | NIFTI_UNITS_SEC; // This may be wrong
9489 hdr.cal_max = 0.0;
9490 hdr.cal_min = 0.0;
9491 hdr.toffset = 0;
9492
9493 /* set the nifti header qform values */
9494 error = mriToNiftiQform(mri, &hdr);
9495 if(error != NO_ERROR) return(error);
9496
9497 memcpy(hdr.magic, NIFTI1_MAGIC, 4);
9498
9499 strcpy(fname_stem, fname);
9500 dot = strrchr(fname_stem, '.');
9501 if(dot != NULL)
9502 if(strcmp(dot, ".img") == 0 || strcmp(dot, ".hdr") == 0)
9503 *dot = '\0';
9504
9505 sprintf(hdr_fname, "%s.hdr", fname_stem);
9506 sprintf(img_fname, "%s.img", fname_stem);
9507
9508 fp = fopen(hdr_fname, "w");
9509 if(fp == NULL)
9510 {
9511 errno = 0;
9512 ErrorReturn(ERROR_BADFILE,
9513 (ERROR_BADFILE,
9514 "nifti1Write(): error opening file %s", hdr_fname));
9515 }
9516
9517 if(fwrite(&hdr, sizeof(hdr), 1, fp) != 1)
9518 {
9519 fclose(fp);
9520 errno = 0;
9521 ErrorReturn(ERROR_BADFILE,
9522 (ERROR_BADFILE,
9523 "nifti1Write(): error writing header to %s", hdr_fname));
9524 }
9525
9526 fclose(fp);
9527
9528 fp = fopen(img_fname, "w");
9529 if(fp == NULL)
9530 {
9531 errno = 0;
9532 ErrorReturn(ERROR_BADFILE,
9533 (ERROR_BADFILE,
9534 "nifti1Write(): error opening file %s", img_fname));
9535 }
9536
9537 for(t = 0;t < mri->nframes;t++)
9538 for(k = 0;k < mri->depth;k++)
9539 for(j = 0;j < mri->height;j++)
9540 {
9541 buf = &MRIseq_vox(mri, 0, j, k, t);
9542 if(fwrite(buf, hdr.bitpix/8, mri->width, fp) != mri->width)
9543 {
9544 fclose(fp);
9545 errno = 0;
9546 ErrorReturn
9547 (ERROR_BADFILE,
9548 (ERROR_BADFILE,
9549 "nifti1Write(): error writing data to %s", img_fname));
9550 }
9551 }
9552
9553 fclose(fp);
9554
9555 return(NO_ERROR);
9556
9557 } /* end nifti1Write() */
9558
9559 /*------------------------------------------------------------------
9560 niiRead() - note: there is also an nifti1Read(). Make sure to
9561 edit both.
9562 -----------------------------------------------------------------*/
9563 static MRI *niiRead(char *fname, int read_volume)
9564 {
9565
9566 znzFile fp;
9567 MRI *mri;
9568 struct nifti_1_header hdr;
9569 int nslices;
9570 int fs_type;
9571 float time_units_factor, space_units_factor;
9572 int swapped_flag;
9573 int n_read, i, j, k, t;
9574 int bytes_per_voxel,time_units,space_units ;
9575
9576 fp = znzopen(fname, "r", 1);
9577 if(fp == NULL){
9578 errno = 0;
9579 ErrorReturn(NULL, (ERROR_BADFILE,
9580 "niiRead(): error opening file %s", fname));
9581 }
9582
9583 if(znzread(&hdr, sizeof(hdr), 1, fp) != 1){
9584 znzclose(fp);
9585 errno = 0;
9586 ErrorReturn(NULL, (ERROR_BADFILE,
9587 "niiRead(): error reading header from %s", fname));
9588 }
9589
9590 znzclose(fp);
9591
9592 swapped_flag = FALSE;
9593 if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
9594 swapped_flag = TRUE;
9595 swap_nifti_1_header(&hdr);
9596 if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
9597 ErrorReturn(NULL, (ERROR_BADFILE,
9598 "niiRead(): bad number of dimensions (%hd) in %s",
9599 hdr.dim[0], fname));
9600 }
9601 }
9602
9603 if(memcmp(hdr.magic, NII_MAGIC, 4) != 0){
9604 ErrorReturn(NULL, (ERROR_BADFILE, "niiRead(): bad magic number in %s",
9605 fname));
9606 }
9607
9608 if(hdr.dim[0] != 3 && hdr.dim[0] != 4){
9609 ErrorReturn(NULL,
9610 (ERROR_UNSUPPORTED,
9611 "niiRead(): %hd dimensions in %s; unsupported",
9612 hdr.dim[0], fname));
9613 }
9614
9615 if(hdr.datatype == DT_NONE || hdr.datatype == DT_UNKNOWN){
9616 ErrorReturn(NULL,
9617 (ERROR_UNSUPPORTED,
9618 "niiRead(): unknown or no data type in %s; bailing out",
9619 fname));
9620 }
9621
9622 space_units = XYZT_TO_SPACE(hdr.xyzt_units) ;
9623 if(space_units == NIFTI_UNITS_METER) space_units_factor = 1000.0;
9624 else if(space_units == NIFTI_UNITS_MM) space_units_factor = 1.0;
9625 else if(space_units == NIFTI_UNITS_MICRON) space_units_factor = 0.001;
9626 else
9627 ErrorReturn
9628 (NULL,
9629 (ERROR_BADFILE,
9630 "niiRead(): unknown space units %d in %s", space_units,
9631 fname));
9632
9633 time_units = XYZT_TO_TIME (hdr.xyzt_units) ;
9634 if(time_units == NIFTI_UNITS_SEC) time_units_factor = 1000.0;
9635 else if(time_units == NIFTI_UNITS_MSEC) time_units_factor = 1.0;
9636 else if(time_units == NIFTI_UNITS_USEC) time_units_factor = 0.001;
9637 else{
9638 if(hdr.dim[4] > 1){
9639 ErrorReturn
9640 (NULL,
9641 (ERROR_BADFILE,
9642 "niiRead(): unknown time units %d in %s",
9643 time_units,fname));
9644 }
9645 else time_units_factor = 0;
9646 }
9647 //printf("hdr.xyzt_units = %d, time_units = %d, %g, %g\n",
9648 // hdr.xyzt_units,time_units,hdr.pixdim[4],time_units_factor);
9649
9650 /*
9651 nifti1.h says: slice_code = If this is nonzero, AND
9652 if slice_dim is nonzero, AND
9653 if slice_duration is positive, indicates the timing
9654 pattern of the slice acquisition.
9655 not yet supported here
9656 */
9657
9658 if(hdr.slice_code != 0 && DIM_INFO_TO_SLICE_DIM(hdr.dim_info) != 0
9659 && hdr.slice_duration > 0.0){
9660 ErrorReturn(NULL,
9661 (ERROR_UNSUPPORTED,
9662 "niiRead(): unsupported timing pattern in %s", fname));
9663 }
9664
9665 if(hdr.dim[0] == 3) nslices = 1;
9666 else nslices = hdr.dim[4];
9667
9668 if(hdr.scl_slope == 0){
9669 // voxel values are unscaled -- we use the file's data type
9670 if(hdr.datatype == DT_UNSIGNED_CHAR){
9671 fs_type = MRI_UCHAR;
9672 bytes_per_voxel = 1;
9673 }
9674 else if(hdr.datatype == DT_SIGNED_SHORT){
9675 fs_type = MRI_SHORT;
9676 bytes_per_voxel = 2;
9677 }
9678 else if(hdr.datatype == DT_SIGNED_INT){
9679 fs_type = MRI_INT;
9680 bytes_per_voxel = 4;
9681 }
9682 else if(hdr.datatype == DT_FLOAT){
9683 fs_type = MRI_FLOAT;
9684 bytes_per_voxel = 4;
9685 }
9686 else{
9687 ErrorReturn
9688 (NULL,
9689 (ERROR_UNSUPPORTED,
9690 "niiRead(): unsupported datatype %d (with scl_slope = 0) in %s",
9691 hdr.datatype, fname));
9692 }
9693 }
9694 else{
9695 // we must scale the voxel values
9696 if( hdr.datatype != DT_UNSIGNED_CHAR
9697 && hdr.datatype != DT_SIGNED_SHORT
9698 && hdr.datatype != DT_SIGNED_INT
9699 && hdr.datatype != DT_FLOAT
9700 && hdr.datatype != DT_DOUBLE
9701 && hdr.datatype != DT_INT8
9702 && hdr.datatype != DT_UINT16
9703 && hdr.datatype != DT_UINT32){
9704 ErrorReturn
9705 (NULL,
9706 (ERROR_UNSUPPORTED,
9707 "niiRead(): unsupported datatype %d (with scl_slope != 0) in %s",
9708 hdr.datatype, fname));
9709 }
9710 fs_type = MRI_FLOAT;
9711 bytes_per_voxel = 0; /* set below -- avoid the compiler warning */
9712 }
9713
9714 if(read_volume)
9715 mri = MRIallocSequence(hdr.dim[1],hdr.dim[2],hdr.dim[3],fs_type,nslices);
9716 else{
9717 mri = MRIallocHeader(hdr.dim[1], hdr.dim[2], hdr.dim[3], fs_type);
9718 mri->nframes = nslices;
9719 }
9720
9721 if(mri == NULL) return(NULL);
9722
9723 mri->xsize = hdr.pixdim[1];
9724 mri->ysize = hdr.pixdim[2];
9725 mri->zsize = hdr.pixdim[3];
9726 if(hdr.dim[0] == 4) mri->tr = hdr.pixdim[4];
9727
9728 if(hdr.qform_code == 0){
9729 printf("WARNING: missing NIfTI-1 orientation (qform_code = 0)\n");
9730 printf("WARNING: your volume will probably be incorrectly oriented\n");
9731 mri->x_r = 1.0; mri->x_a = 0.0; mri->x_s = 0.0;
9732 mri->y_r = 0.0; mri->y_a = 1.0; mri->y_s = 0.0;
9733 mri->z_r = 0.0; mri->z_a = 0.0; mri->z_s = 1.0;
9734 mri->c_r = mri->xsize * mri->width / 2.0;
9735 mri->c_a = mri->ysize * mri->height / 2.0;
9736 mri->c_s = mri->zsize * mri->depth / 2.0;
9737 }
9738 else if(hdr.sform_code <= 0){
9739 if(niftiQformToMri(mri, &hdr) != NO_ERROR){
9740 MRIfree(&mri);
9741 return(NULL);
9742 }
9743 }
9744 else{
9745 if(niftiSformToMri(mri, &hdr) != NO_ERROR){
9746 MRIfree(&mri);
9747 return(NULL);
9748 }
9749 }
9750
9751 mri->xsize = mri->xsize * space_units_factor;
9752 mri->ysize = mri->ysize * space_units_factor;
9753 mri->zsize = mri->zsize * space_units_factor;
9754 mri->c_r = mri->c_r * space_units_factor;
9755 mri->c_a = mri->c_a * space_units_factor;
9756 mri->c_s = mri->c_s * space_units_factor;
9757 if(hdr.dim[0] == 4) mri->tr = mri->tr * time_units_factor;
9758
9759 if(!read_volume) return(mri);
9760
9761 fp = znzopen(fname, "r", 1);
9762 if(fp == NULL) {
9763 MRIfree(&mri);
9764 errno = 0;
9765 ErrorReturn(NULL, (ERROR_BADFILE,
9766 "niiRead(): error opening file %s", fname));
9767 }
9768
9769 if(znzseek(fp, (long)(hdr.vox_offset), SEEK_SET) == -1){
9770 znzclose(fp);
9771 MRIfree(&mri);
9772 errno = 0;
9773 ErrorReturn(NULL, (ERROR_BADFILE,
9774 "niiRead(): error finding voxel data in %s", fname));
9775 }
9776
9777 if(hdr.scl_slope == 0){
9778 // no voxel value scaling needed
9779 void *buf;
9780
9781 for(t = 0;t < mri->nframes;t++)
9782 for(k = 0;k < mri->depth;k++)
9783 for(j = 0;j < mri->height;j++) {
9784 buf = &MRIseq_vox(mri, 0, j, k, t);
9785
9786 n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9787 if(n_read != mri->width) {
9788 znzclose(fp);
9789 MRIfree(&mri);
9790 errno = 0;
9791 ErrorReturn(NULL, (ERROR_BADFILE,
9792 "niiRead(): error reading from %s", fname));
9793 }
9794
9795 if(swapped_flag) {
9796 if(bytes_per_voxel == 2)
9797 byteswapbufshort(buf, bytes_per_voxel * mri->width);
9798 if(bytes_per_voxel == 4)
9799 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9800 }
9801
9802 }
9803
9804 }
9805 else{
9806 // voxel value scaling needed
9807 if(hdr.datatype == DT_UNSIGNED_CHAR) {
9808 unsigned char *buf;
9809 bytes_per_voxel = 1;
9810 buf = (unsigned char *)malloc(mri->width * bytes_per_voxel);
9811 for(t = 0;t < mri->nframes;t++)
9812 for(k = 0;k < mri->depth;k++)
9813 for(j = 0;j < mri->height;j++) {
9814 n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9815 if(n_read != mri->width) {
9816 free(buf);
9817 znzclose(fp);
9818 MRIfree(&mri);
9819 errno = 0;
9820 ErrorReturn(NULL,
9821 (ERROR_BADFILE,
9822 "niiRead(): error reading from %s", fname));
9823 }
9824 for(i = 0;i < mri->width;i++)
9825 MRIFseq_vox(mri, i, j, k, t) =
9826 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9827 }
9828 free(buf);
9829 }
9830
9831 if(hdr.datatype == DT_SIGNED_SHORT){
9832 short *buf;
9833 bytes_per_voxel = 2;
9834 buf = (short *)malloc(mri->width * bytes_per_voxel);
9835 for(t = 0;t < mri->nframes;t++)
9836 for(k = 0;k < mri->depth;k++)
9837 for(j = 0;j < mri->height;j++) {
9838 n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9839 if(n_read != mri->width) {
9840 free(buf);
9841 znzclose(fp);
9842 MRIfree(&mri);
9843 errno = 0;
9844 ErrorReturn(NULL,
9845 (ERROR_BADFILE,
9846 "niiRead(): error reading from %s", fname));
9847 }
9848 if(swapped_flag)
9849 byteswapbufshort(buf, bytes_per_voxel * mri->width);
9850 for(i = 0;i < mri->width;i++)
9851 MRIFseq_vox(mri, i, j, k, t) =
9852 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9853 }
9854 free(buf);
9855 }
9856
9857 if(hdr.datatype == DT_SIGNED_INT) {
9858 int *buf;
9859 bytes_per_voxel = 4;
9860 buf = (int *)malloc(mri->width * bytes_per_voxel);
9861 for(t = 0;t < mri->nframes;t++)
9862 for(k = 0;k < mri->depth;k++)
9863 for(j = 0;j < mri->height;j++) {
9864 n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9865 if(n_read != mri->width){
9866 free(buf);
9867 znzclose(fp);
9868 MRIfree(&mri);
9869 errno = 0;
9870 ErrorReturn(NULL,
9871 (ERROR_BADFILE,
9872 "niiRead(): error reading from %s", fname));
9873 }
9874 if(swapped_flag)
9875 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9876 for(i = 0;i < mri->width;i++)
9877 MRIFseq_vox(mri, i, j, k, t) =
9878 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9879 }
9880 free(buf);
9881 }
9882
9883 if(hdr.datatype == DT_FLOAT) {
9884 float *buf;
9885 bytes_per_voxel = 4;
9886 buf = (float *)malloc(mri->width * bytes_per_voxel);
9887 for(t = 0;t < mri->nframes;t++)
9888 for(k = 0;k < mri->depth;k++)
9889 for(j = 0;j < mri->height;j++) {
9890 n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9891 if(n_read != mri->width) {
9892 free(buf);
9893 znzclose(fp);
9894 MRIfree(&mri);
9895 errno = 0;
9896 ErrorReturn(NULL,
9897 (ERROR_BADFILE,
9898 "niiRead(): error reading from %s", fname));
9899 }
9900 if(swapped_flag)
9901 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
9902 for(i = 0;i < mri->width;i++)
9903 MRIFseq_vox(mri, i, j, k, t) =
9904 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9905 }
9906 free(buf);
9907 }
9908
9909 if(hdr.datatype == DT_DOUBLE) {
9910 double *buf;
9911 unsigned char *cbuf, ccbuf[8];
9912 bytes_per_voxel = 8;
9913 buf = (double *)malloc(mri->width * bytes_per_voxel);
9914 for(t = 0;t < mri->nframes;t++)
9915 for(k = 0;k < mri->depth;k++)
9916 for(j = 0;j < mri->height;j++) {
9917 n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9918 if(n_read != mri->width) {
9919 free(buf);
9920 znzclose(fp);
9921 MRIfree(&mri);
9922 errno = 0;
9923 ErrorReturn(NULL,
9924 (ERROR_BADFILE,
9925 "niiRead(): error reading from %s", fname));
9926 }
9927 if(swapped_flag) {
9928 for(i = 0;i < mri->width;i++)
9929 {
9930 cbuf = (unsigned char *)&buf[i];
9931 memcpy(ccbuf, cbuf, 8);
9932 cbuf[0] = ccbuf[7];
9933 cbuf[1] = ccbuf[6];
9934 cbuf[2] = ccbuf[5];
9935 cbuf[3] = ccbuf[4];
9936 cbuf[4] = ccbuf[3];
9937 cbuf[5] = ccbuf[2];
9938 cbuf[6] = ccbuf[1];
9939 cbuf[7] = ccbuf[0];
9940 }
9941 }
9942 for(i = 0;i < mri->width;i++)
9943 MRIFseq_vox(mri, i, j, k, t) =
9944 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9945 }
9946 free(buf);
9947 }
9948
9949 if(hdr.datatype == DT_INT8) {
9950 char *buf;
9951 bytes_per_voxel = 1;
9952 buf = (char *)malloc(mri->width * bytes_per_voxel);
9953 for(t = 0;t < mri->nframes;t++)
9954 for(k = 0;k < mri->depth;k++)
9955 for(j = 0;j < mri->height;j++){
9956 n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9957 if(n_read != mri->width) {
9958 free(buf);
9959 znzclose(fp);
9960 MRIfree(&mri);
9961 errno = 0;
9962 ErrorReturn(NULL,
9963 (ERROR_BADFILE,
9964 "niiRead(): error reading from %s", fname));
9965 }
9966 for(i = 0;i < mri->width;i++)
9967 MRIFseq_vox(mri, i, j, k, t) =
9968 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9969 }
9970 free(buf);
9971 }
9972
9973 if(hdr.datatype == DT_UINT16) {
9974 unsigned short *buf;
9975 bytes_per_voxel = 2;
9976 buf = (unsigned short *)malloc(mri->width * bytes_per_voxel);
9977 for(t = 0;t < mri->nframes;t++)
9978 for(k = 0;k < mri->depth;k++)
9979 for(j = 0;j < mri->height;j++) {
9980 n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
9981 if(n_read != mri->width){
9982 free(buf);
9983 znzclose(fp);
9984 MRIfree(&mri);
9985 errno = 0;
9986 ErrorReturn(NULL,
9987 (ERROR_BADFILE,
9988 "niiRead(): error reading from %s", fname));
9989 }
9990 if(swapped_flag)
9991 byteswapbufshort(buf, bytes_per_voxel * mri->width);
9992 for(i = 0;i < mri->width;i++)
9993 MRIFseq_vox(mri, i, j, k, t) =
9994 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
9995 }
9996 free(buf);
9997 }
9998
9999 if(hdr.datatype == DT_UINT32) {
10000 unsigned int *buf;
10001 bytes_per_voxel = 4;
10002 buf = (unsigned int *)malloc(mri->width * bytes_per_voxel);
10003 for(t = 0;t < mri->nframes;t++)
10004 for(k = 0;k < mri->depth;k++)
10005 for(j = 0;j < mri->height;j++)
10006 {
10007 n_read = znzread(buf, bytes_per_voxel, mri->width, fp);
10008 if(n_read != mri->width)
10009 {
10010 free(buf);
10011 znzclose(fp);
10012 MRIfree(&mri);
10013 errno = 0;
10014 ErrorReturn(NULL,
10015 (ERROR_BADFILE,
10016 "niiRead(): error reading from %s", fname));
10017 }
10018 if(swapped_flag)
10019 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
10020 for(i = 0;i < mri->width;i++)
10021 MRIFseq_vox(mri, i, j, k, t) =
10022 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
10023 }
10024 free(buf);
10025 }
10026 }
10027 znzclose(fp);
10028
10029 return(mri);
10030
10031 } /* end niiRead() */
10032
10033 /*------------------------------------------------------------------
10034 niiWrite() - note: there is also an nifti1Write(). Make sure to
10035 edit both.
10036 -----------------------------------------------------------------*/
10037 static int niiWrite(MRI *mri, char *fname)
10038 {
10039
10040 znzFile fp;
10041 int j, k, t;
10042 BUFTYPE *buf;
10043 struct nifti_1_header hdr;
10044 int error;
10045
10046 memset(&hdr, 0x00, sizeof(hdr));
10047
10048 hdr.sizeof_hdr = 348;
10049 hdr.dim_info = 0;
10050
10051 if(mri->nframes == 1){
10052 hdr.dim[0] = 3;
10053 hdr.dim[1] = mri->width;
10054 hdr.dim[2] = mri->height;
10055 hdr.dim[3] = mri->depth;
10056 hdr.pixdim[1] = mri->xsize;
10057 hdr.pixdim[2] = mri->ysize;
10058 hdr.pixdim[3] = mri->zsize;
10059 }
10060 else{
10061 hdr.dim[0] = 4;
10062 hdr.dim[1] = mri->width;
10063 hdr.dim[2] = mri->height;
10064 hdr.dim[3] = mri->depth;
10065 hdr.dim[4] = mri->nframes;
10066 hdr.pixdim[1] = mri->xsize;
10067 hdr.pixdim[2] = mri->ysize;
10068 hdr.pixdim[3] = mri->zsize;
10069 hdr.pixdim[4] = mri->tr/1000.0; // see also xyzt_units
10070 }
10071
10072 if(mri->type == MRI_UCHAR){
10073 hdr.datatype = DT_UNSIGNED_CHAR;
10074 hdr.bitpix = 8;
10075 }
10076 else if(mri->type == MRI_INT){
10077 hdr.datatype = DT_SIGNED_INT;
10078 hdr.bitpix = 32;
10079 }
10080 else if(mri->type == MRI_LONG){
10081 hdr.datatype = DT_SIGNED_INT;
10082 hdr.bitpix = 32;
10083 }
10084 else if(mri->type == MRI_FLOAT){
10085 hdr.datatype = DT_FLOAT;
10086 hdr.bitpix = 32;
10087 }
10088 else if(mri->type == MRI_SHORT){
10089 hdr.datatype = DT_SIGNED_SHORT;
10090 hdr.bitpix = 16;
10091 }
10092 else if(mri->type == MRI_BITMAP){
10093 ErrorReturn(ERROR_UNSUPPORTED,
10094 (ERROR_UNSUPPORTED,
10095 "niiWrite(): data type MRI_BITMAP unsupported"));
10096 }
10097 else if(mri->type == MRI_TENSOR){
10098 ErrorReturn(ERROR_UNSUPPORTED,
10099 (ERROR_UNSUPPORTED,
10100 "niiWrite(): data type MRI_TENSOR unsupported"));
10101 }
10102 else{
10103 ErrorReturn(ERROR_BADPARM,
10104 (ERROR_BADPARM,
10105 "niiWrite(): unknown data type %d", mri->type));
10106 }
10107
10108 hdr.intent_code = NIFTI_INTENT_NONE;
10109 hdr.intent_name[0] = '\0';
10110 hdr.vox_offset = sizeof(hdr);
10111 hdr.scl_slope = 0.0;
10112 hdr.slice_code = 0;
10113 hdr.xyzt_units = NIFTI_UNITS_MM | NIFTI_UNITS_SEC;
10114 hdr.cal_max = 0.0;
10115 hdr.cal_min = 0.0;
10116 hdr.toffset = 0;
10117
10118 /* set the nifti header qform values */
10119 error = mriToNiftiQform(mri, &hdr);
10120 if(error != NO_ERROR)
10121 return(error);
10122
10123 memcpy(hdr.magic, NII_MAGIC, 4);
10124
10125 fp = znzopen(fname, "w", 1);
10126 if(fp == NULL){
10127 errno = 0;
10128 ErrorReturn(ERROR_BADFILE,
10129 (ERROR_BADFILE,
10130 "niiWrite(): error opening file %s", fname));
10131 }
10132
10133 if(znzwrite(&hdr, sizeof(hdr), 1, fp) != 1) {
10134 znzclose(fp);
10135 errno = 0;
10136 ErrorReturn(ERROR_BADFILE,
10137 (ERROR_BADFILE,
10138 "niiWrite(): error writing header to %s", fname));
10139 }
10140
10141 for(t = 0;t < mri->nframes;t++)
10142 for(k = 0;k < mri->depth;k++)
10143 for(j = 0;j < mri->height;j++){
10144 buf = &MRIseq_vox(mri, 0, j, k, t);
10145 if(znzwrite(buf, hdr.bitpix/8, mri->width, fp) != mri->width){
10146 znzclose(fp);
10147 errno = 0;
10148 ErrorReturn(ERROR_BADFILE,
10149 (ERROR_BADFILE,
10150 "niiWrite(): error writing data to %s", fname));
10151 }
10152 }
10153
10154 znzclose(fp);
10155
10156 return(NO_ERROR);
10157
10158 } /* end niiWrite() */
10159
10160 static int niftiSformToMri(MRI *mri, struct nifti_1_header *hdr)
10161 {
10162
10163 /*
10164
10165 x = srow_x[0] * i + srow_x[1] * j + srow_x[2] * k + srow_x[3]
10166 y = srow_y[0] * i + srow_y[1] * j + srow_y[2] * k + srow_y[3]
10167 z = srow_z[0] * i + srow_z[1] * j + srow_z[2] * k + srow_z[3]
10168
10169
10170 [ r ] [ mri->xsize * mri->x_r
10171 mri->ysize * mri->y_r mri->zsize * mri->z_r r_offset ] [ i ]
10172 [ a ] = [ mri->xsize * mri->x_a
10173 mri->ysize * mri->y_a mri->zsize * mri->z_a a_offset ] * [ j ]
10174 [ s ] [ mri->xsize * mri->x_s
10175 mri->ysize * mri->y_s mri->zsize * mri->z_s s_offset ] [ k ]
10176 [ 1 ] [ 0
10177 0 0 1 ] [ 1 ]
10178
10179
10180
10181 */
10182
10183 mri->xsize = sqrt(hdr->srow_x[0]*hdr->srow_x[0] \
10184 + hdr->srow_y[0]*hdr->srow_y[0] \
10185 + hdr->srow_z[0]*hdr->srow_z[0]);
10186 mri->x_r = hdr->srow_x[0] / mri->xsize;
10187 mri->x_a = hdr->srow_y[0] / mri->ysize;
10188 mri->x_s = hdr->srow_z[0] / mri->zsize;
10189
10190 mri->ysize = sqrt(hdr->srow_x[1]*hdr->srow_x[1] \
10191 + hdr->srow_y[1]*hdr->srow_y[1] \
10192 + hdr->srow_z[1]*hdr->srow_z[1]);
10193 mri->y_r = hdr->srow_x[1] / mri->ysize;
10194 mri->y_a = hdr->srow_y[1] / mri->ysize;
10195 mri->y_s = hdr->srow_z[1] / mri->ysize;
10196
10197 mri->zsize = sqrt(hdr->srow_x[2]*hdr->srow_x[2] \
10198 + hdr->srow_y[2]*hdr->srow_y[2] \
10199 + hdr->srow_z[2]*hdr->srow_z[2]);
10200 mri->z_r = hdr->srow_x[2] / mri->zsize;
10201 mri->z_a = hdr->srow_y[2] / mri->zsize;
10202 mri->z_s = hdr->srow_z[2] / mri->zsize;
10203
10204 mri->c_r = hdr->srow_x[0] * mri->width / 2.0
10205 + hdr->srow_x[1] * mri->height / 2.0
10206 + hdr->srow_x[2] * mri->depth / 2.0
10207 + hdr->srow_x[3];
10208
10209 mri->c_a = hdr->srow_y[0] * mri->width / 2.0
10210 + hdr->srow_y[1] * mri->height / 2.0
10211 + hdr->srow_y[2] * mri->depth / 2.0
10212 + hdr->srow_y[3];
10213
10214 mri->c_r = hdr->srow_z[0] * mri->width / 2.0
10215 + hdr->srow_z[1] * mri->height / 2.0
10216 + hdr->srow_z[2] * mri->depth / 2.0
10217 + hdr->srow_z[3];
10218
10219 return(NO_ERROR);
10220
10221 } /* end niftiSformToMri() */
10222
10223 static int niftiQformToMri(MRI *mri, struct nifti_1_header *hdr)
10224 {
10225
10226 float a, b, c, d;
10227 float r11, r12, r13;
10228 float r21, r22, r23;
10229 float r31, r32, r33;
10230
10231 b = hdr->quatern_b;
10232 c = hdr->quatern_c;
10233 d = hdr->quatern_d;
10234
10235 /* following quatern_to_mat44() */
10236
10237 a = 1.0 - (b*b + c*c + d*d);
10238 if(a < 1.0e-7)
10239 {
10240 a = 1.0 / sqrt(b*b + c*c + d*d);
10241 b *= a;
10242 c *= a;
10243 d *= a;
10244 a = 0.0;
10245 }
10246 else
10247 a = sqrt(a);
10248
10249 r11 = a*a + b*b - c*c - d*d;
10250 r12 = 2.0*b*c - 2.0*a*d;
10251 r13 = 2.0*b*d + 2.0*a*c;
10252 r21 = 2.0*b*c + 2.0*a*d;
10253 r22 = a*a + c*c - b*b - d*d;
10254 r23 = 2.0*c*d - 2.0*a*b;
10255 r31 = 2.0*b*d - 2*a*c;
10256 r32 = 2.0*c*d + 2*a*b;
10257 r33 = a*a + d*d - c*c - b*b;
10258
10259 if(hdr->pixdim[0] < 0.0)
10260 {
10261 r13 = -r13;
10262 r23 = -r23;
10263 r33 = -r33;
10264 }
10265
10266 mri->x_r = r11;
10267 mri->y_r = r12;
10268 mri->z_r = r13;
10269 mri->x_a = r21;
10270 mri->y_a = r22;
10271 mri->z_a = r23;
10272 mri->x_s = r31;
10273 mri->y_s = r32;
10274 mri->z_s = r33;
10275
10276
10277 /**/
10278 /* c_ras */
10279 /*
10280
10281 [ r ] [ mri->xsize * mri->x_r
10282 mri->ysize * mri->y_r mri->zsize * mri->z_r r_offset ] [ i ]
10283 [ a ] = [ mri->xsize * mri->x_a
10284 mri->ysize * mri->y_a mri->zsize * mri->z_a a_offset ] * [ j ]
10285 [ s ] [ mri->xsize * mri->x_s
10286 mri->ysize * mri->y_s mri->zsize * mri->z_s s_offset ] [ k ]
10287 [ 1 ] [ 0
10288 0 0 1 ] [ 1 ]
10289
10290
10291 */
10292
10293 mri->c_r = (mri->xsize * mri->x_r) * (mri->width / 2.0)
10294 + (mri->ysize * mri->y_r) * (mri->height / 2.0)
10295 + (mri->zsize * mri->z_r) * (mri->depth / 2.0)
10296 + hdr->qoffset_x;
10297
10298 mri->c_a = (mri->xsize * mri->x_a) * (mri->width / 2.0)
10299 + (mri->ysize * mri->y_a) * (mri->height / 2.0)
10300 + (mri->zsize * mri->z_a) * (mri->depth / 2.0)
10301 + hdr->qoffset_y;
10302
10303 mri->c_s = (mri->xsize * mri->x_s) * (mri->width / 2.0)
10304 + (mri->ysize * mri->y_s) * (mri->height / 2.0)
10305 + (mri->zsize * mri->z_s) * (mri->depth / 2.0)
10306 + hdr->qoffset_z;
10307
10308
10309 return(NO_ERROR);
10310
10311 } /* end niftiQformToMri() */
10312
10313 static int mriToNiftiQform(MRI *mri, struct nifti_1_header *hdr)
10314 {
10315
10316 MATRIX *i_to_r;
10317 float r11, r12, r13;
10318 float r21, r22, r23;
10319 float r31, r32, r33;
10320 float qfac;
10321 float a, b, c, d;
10322 float xd, yd, zd;
10323 float r_det;
10324
10325 /*
10326
10327 nifti1.h (x, y, z are r, a, s, respectively):
10328
10329 [ x ] [ R11 R12 R13 ] [ pixdim[1] * i ] [ qoffset_x ]
10330 [ y ] = [ R21 R22 R23 ] [ pixdim[2] * j ] + [ qoffset_y ]
10331 [ z ] [ R31 R32 R33 ] [ qfac * pixdim[3] * k ] [ qoffset_z ]
10332
10333 mri.c extract_r_to_i():
10334
10335 [ r ] [ mri->xsize * mri->x_r
10336 mri->ysize * mri->y_r mri->zsize * mri->z_r r_offset ] [ i ]
10337 [ a ] = [ mri->xsize * mri->x_a
10338 mri->ysize * mri->y_a mri->zsize * mri->z_a a_offset ] * [ j ]
10339 [ s ] [ mri->xsize * mri->x_s
10340 mri->ysize * mri->y_s mri->zsize * mri->z_s s_offset ] [ k ]
10341 [ 1 ] [ 0
10342 0 0 1 ] [ 1 ]
10343
10344 where [ras]_offset are calculated by satisfying (r, a, s)
10345 = (mri->c_r, mri->c_a, mri->c_s)
10346 when (i, j, k) = (mri->width/2, mri->height/2, mri->depth/2)
10347
10348 so our mapping is simple:
10349
10350 (done outside this function)
10351 pixdim[1] mri->xsize
10352 pixdim[2] mri->ysize
10353 pixdim[3] mri->zsize
10354
10355 R11 = mri->x_r R12 = mri->y_r R13 = mri->z_r
10356 R21 = mri->x_a R22 = mri->y_a R23 = mri->z_a
10357 R31 = mri->x_s R32 = mri->y_s R33 = mri->z_s
10358
10359 qoffset_x = r_offset
10360 qoffset_y = a_offset
10361 qoffset_z = s_offset
10362
10363 qfac (pixdim[0]) = 1
10364
10365 unless det(R) == -1, in which case we substitute:
10366
10367 R13 = -mri->z_r
10368 R23 = -mri->z_a
10369 R33 = -mri->z_s
10370
10371 qfac (pixdim[0]) = -1
10372
10373 we follow mat44_to_quatern() from nifti1_io.c
10374
10375 for now, assume orthonormality in mri->[xyz]_[ras]
10376
10377 */
10378
10379
10380 r11 = mri->x_r; r12 = mri->y_r; r13 = mri->z_r;
10381 r21 = mri->x_a; r22 = mri->y_a; r23 = mri->z_a;
10382 r31 = mri->x_s; r32 = mri->y_s; r33 = mri->z_s;
10383
10384 r_det = + r11 * (r22*r33 - r32*r23)
10385 - r12 * (r21*r33 - r31*r23)
10386 + r13 * (r21*r32 - r31*r22);
10387
10388 if(r_det == 0.0)
10389 {
10390 ErrorReturn(ERROR_BADFILE,
10391 (ERROR_BADFILE,
10392 "bad orientation matrix (determinant = 0) in nifti1 file"));
10393 }
10394 else if(r_det > 0.0)
10395 qfac = 1.0;
10396 else
10397 {
10398 r13 = -r13;
10399 r23 = -r23;
10400 r33 = -r33;
10401 qfac = -1.0;
10402 }
10403
10404 /* following mat44_to_quatern() */
10405
10406 a = r11 + r22 + r33 + 1.0;
10407
10408 if(a > 0.5)
10409 {
10410 a = 0.5 * sqrt(a);
10411 b = 0.25 * (r32-r23) / a;
10412 c = 0.25 * (r13-r31) / a;
10413 d = 0.25 * (r21-r12) / a;
10414 }
10415 else
10416 {
10417
10418 xd = 1.0 + r11 - (r22+r33);
10419 yd = 1.0 + r22 - (r11+r33);
10420 zd = 1.0 + r33 - (r11+r22);
10421
10422 if(xd > 1.0)
10423 {
10424 b = 0.5 * sqrt(xd);
10425 c = 0.25 * (r12+r21) / b;
10426 d = 0.25 * (r13+r31) / b;
10427 a = 0.25 * (r32-r23) / b;
10428 }
10429 else if( yd > 1.0 )
10430 {
10431 c = 0.5 * sqrt(yd);
10432 b = 0.25 * (r12+r21) / c;
10433 d = 0.25 * (r23+r32) / c;
10434 a = 0.25 * (r13-r31) / c;
10435 }
10436 else
10437 {
10438 d = 0.5 * sqrt(zd);
10439 b = 0.25 * (r13+r31) / d;
10440 c = 0.25 * (r23+r32) / d;
10441 a = 0.25 * (r21-r12) / d;
10442 }
10443
10444 if(a < 0.0)
10445 {
10446 a = -a;
10447 b = -b;
10448 c = -c;
10449 d = -d;
10450 }
10451
10452 }
10453
10454 hdr->qform_code = NIFTI_XFORM_SCANNER_ANAT;
10455
10456 hdr->pixdim[0] = qfac;
10457
10458 hdr->quatern_b = b;
10459 hdr->quatern_c = c;
10460 hdr->quatern_d = d;
10461
10462 i_to_r = extract_i_to_r(mri);
10463 if(i_to_r == NULL)
10464 return(ERROR_BADPARM);
10465
10466 hdr->qoffset_x = *MATRIX_RELT(i_to_r, 1, 4);
10467 hdr->qoffset_y = *MATRIX_RELT(i_to_r, 2, 4);
10468 hdr->qoffset_z = *MATRIX_RELT(i_to_r, 3, 4);
10469
10470 MatrixFree(&i_to_r);
10471
10472 return(NO_ERROR);
10473
10474 } /* end mriToNiftiQform() */
10475
10476 static void swap_nifti_1_header(struct nifti_1_header *hdr)
10477 {
10478
10479 int i;
10480
10481 hdr->sizeof_hdr = swapInt(hdr->sizeof_hdr);
10482
10483 for(i = 0;i < 8;i++)
10484 hdr->dim[i] = swapShort(hdr->dim[i]);
10485
10486 hdr->intent_p1 = swapFloat(hdr->intent_p1);
10487 hdr->intent_p2 = swapFloat(hdr->intent_p2);
10488 hdr->intent_p3 = swapFloat(hdr->intent_p3);
10489 hdr->intent_code = swapShort(hdr->intent_code);
10490 hdr->datatype = swapShort(hdr->datatype);
10491 hdr->bitpix = swapShort(hdr->bitpix);
10492 hdr->slice_start = swapShort(hdr->slice_start);
10493
10494 for(i = 0;i < 8;i++)
10495 hdr->pixdim[i] = swapFloat(hdr->pixdim[i]);
10496
10497 hdr->vox_offset = swapFloat(hdr->vox_offset);
10498 hdr->scl_slope = swapFloat(hdr->scl_slope);
10499 hdr->scl_inter = swapFloat(hdr->scl_inter);
10500 hdr->slice_end = swapShort(hdr->slice_end);
10501 hdr->cal_max = swapFloat(hdr->cal_max);
10502 hdr->cal_min = swapFloat(hdr->cal_min);
10503 hdr->slice_duration = swapFloat(hdr->slice_duration);
10504 hdr->toffset = swapFloat(hdr->toffset);
10505 hdr->qform_code = swapShort(hdr->qform_code);
10506 hdr->sform_code = swapShort(hdr->sform_code);
10507 hdr->quatern_b = swapFloat(hdr->quatern_b);
10508 hdr->quatern_c = swapFloat(hdr->quatern_c);
10509 hdr->quatern_d = swapFloat(hdr->quatern_d);
10510 hdr->qoffset_x = swapFloat(hdr->qoffset_x);
10511 hdr->qoffset_y = swapFloat(hdr->qoffset_y);
10512 hdr->qoffset_z = swapFloat(hdr->qoffset_z);
10513
10514 for(i = 0;i < 4;i++)
10515 hdr->srow_x[i] = swapFloat(hdr->srow_x[i]);
10516
10517 for(i = 0;i < 4;i++)
10518 hdr->srow_y[i] = swapFloat(hdr->srow_y[i]);
10519
10520 for(i = 0;i < 4;i++)
10521 hdr->srow_z[i] = swapFloat(hdr->srow_z[i]);
10522
10523 return;
10524
10525 } /* end swap_nifti_1_header */
10526
10527 MRI *MRIreadGeRoi(char *fname, int n_slices)
10528 {
10529
10530 MRI *mri;
10531 int i;
10532 char prefix[STRLEN], postfix[STRLEN];
10533 int n_digits;
10534 FILE *fp;
10535 int width, height;
10536 char fname_use[STRLEN];
10537 int read_one_flag;
10538 int pixel_data_offset;
10539 int y;
10540
10541 if((fp = fopen(fname, "r")) == NULL)
10542 {
10543 errno = 0;
10544 ErrorReturn
10545 (NULL,
10546 (ERROR_BADFILE, "MRIreadGeRoi(): error opening file %s", fname));
10547 }
10548
10549 fseek(fp, 8, SEEK_SET);
10550 fread(&width, 4, 1, fp); width = orderIntBytes(width);
10551 fread(&height, 4, 1, fp); height = orderIntBytes(height);
10552
10553 fclose(fp);
10554
10555 for(i = strlen(fname);i >= 0 && fname[i] != '/';i--);
10556 i++;
10557
10558 n_digits = 0;
10559 for(;fname[i] != '\0' && n_digits < 3;i++)
10560 {
10561 if(isdigit(fname[i]))
10562 n_digits++;
10563 else
10564 n_digits = 0;
10565 }
10566
10567 if(n_digits < 3)
10568 {
10569 errno = 0;
10570 ErrorReturn(NULL, (ERROR_BADPARM,
10571 "MRIreadGeRoi(): bad GE file name (couldn't find "
10572 "three consecutive digits in the base file name)"));
10573 }
10574
10575 strcpy(prefix, fname);
10576 prefix[i-3] = '\0';
10577
10578 strcpy(postfix, &(fname[i]));
10579
10580 printf("%s---%s\n", prefix, postfix);
10581
10582 mri = MRIalloc(width, height, n_slices, MRI_SHORT);
10583
10584 if(mri == NULL)
10585 {
10586 errno = 0;
10587 ErrorReturn
10588 (NULL,
10589 (ERROR_NOMEMORY, "MRIreadGeRoi(): couldn't allocate MRI structure"));
10590 }
10591
10592 MRIclear(mri);
10593
10594 read_one_flag = FALSE;
10595
10596 for(i = 0;i < n_slices;i++)
10597 {
10598
10599 sprintf(fname_use, "%s%03d%s", prefix, i, postfix);
10600 if((fp = fopen(fname_use, "r")) != NULL)
10601 {
10602
10603 fseek(fp, 4, SEEK_SET);
10604 fread(&pixel_data_offset, 4, 1, fp);
10605 pixel_data_offset = orderIntBytes(pixel_data_offset);
10606 fseek(fp, pixel_data_offset, SEEK_SET);
10607
10608 for(y = 0;y < mri->height;y++)
10609 {
10610 if(fread(mri->slices[i][y], 2, mri->width, fp) != mri->width)
10611 {
10612 fclose(fp);
10613 MRIfree(&mri);
10614 errno = 0;
10615 ErrorReturn
10616 (NULL,
10617 (ERROR_BADFILE,
10618 "MRIreadGeRoi(): error reading from file file %s",
10619 fname_use));
10620 }
10621 #if (BYTE_ORDER == LITTLE_ENDIAN)
10622 swab(mri->slices[i][y], mri->slices[i][y], 2 * mri->width);
10623 #endif
10624 }
10625
10626 fclose(fp);
10627 read_one_flag = TRUE;
10628
10629 }
10630 }
10631
10632 if(!read_one_flag)
10633 {
10634 MRIfree(&mri);
10635 errno = 0;
10636 ErrorReturn
10637 (NULL, (ERROR_BADFILE, "MRIreadGeRoi(): didn't read any ROI files"));
10638 }
10639
10640 return(mri);
10641
10642 } /* end MRIreadGeRoi() */
10643
10644 /*******************************************************************/
10645 /*******************************************************************/
10646 /*******************************************************************/
10647
10648 static int data_size[] = { 1, 4, 4, 4, 2 };
10649
10650 static MRI *sdtRead(char *fname, int read_volume)
10651 {
10652
10653 char header_fname[STR_LEN];
10654 char line[STR_LEN];
10655 char *colon, *dot;
10656 FILE *fp;
10657 MRI *mri;
10658 int ndim = -1, data_type = -1;
10659 int dim[4];
10660 float xsize = 1.0, ysize = 1.0, zsize = 1.0, dummy_size;
10661 int orientation = MRI_CORONAL;
10662
10663 dim[0] = -1;
10664 dim[1] = -1;
10665 dim[2] = -1;
10666 dim[3] = -1;
10667
10668 /* form the header file name */
10669 strcpy(header_fname, fname);
10670 if((dot = strrchr(header_fname, '.')))
10671 sprintf(dot+1, "spr");
10672 else
10673 strcat(header_fname, ".spr");
10674
10675 /* open the header */
10676 if((fp = fopen(header_fname, "r")) == NULL)
10677 {
10678 errno = 0;
10679 ErrorReturn
10680 (NULL,
10681 (ERROR_BADFILE,
10682 "sdtRead(%s): could not open header file %s\n",
10683 fname, header_fname));
10684 }
10685
10686 while(1) // !feof(fp))
10687 {
10688 fgets(line, STR_LEN, fp);
10689 if (feof(fp)) // wow. we read too many. get out
10690 break;
10691
10692 if((colon = strchr(line, ':')))
10693 {
10694 *colon = '\0';
10695 colon++;
10696 if(strcmp(line, "numDim") == 0)
10697 {
10698 sscanf(colon, "%d", &ndim);
10699 if(ndim < 3 || ndim > 4)
10700 {
10701 fclose(fp);
10702 errno = 0;
10703 ErrorReturn
10704 (NULL,
10705 (ERROR_UNSUPPORTED,
10706 "sdtRead(%s): only 3 or 4 dimensions "
10707 "supported (numDim = %d)\n",
10708 fname, ndim));
10709 }
10710 }
10711 else if(strcmp(line, "dim") == 0)
10712 {
10713 if(ndim == -1)
10714 {
10715 fclose(fp);
10716 errno = 0;
10717 ErrorReturn
10718 (NULL,
10719 (ERROR_BADFILE,
10720 "sdtRead(%s): 'dim' before 'numDim' in header file %s\n",
10721 fname, header_fname));
10722 }
10723 if(ndim == 3)
10724 {
10725 sscanf(colon, "%d %d %d", &dim[0], &dim[1], &dim[2]);
10726 dim[3] = 1;
10727 }
10728 else
10729 {
10730 sscanf(colon, "%d %d %d %d",
10731 &dim[0], &dim[1], &dim[2], &dim[3]);
10732 if(dim[3] != 1)
10733 {
10734 fclose(fp);
10735 errno = 0;
10736 ErrorReturn
10737 (NULL,
10738 (ERROR_UNSUPPORTED,
10739 "sdtRead(%s): nframes != 1 unsupported "
10740 "for sdt (dim(4) = %d)\n",
10741 fname, dim[3]));
10742 }
10743 }
10744 }
10745 else if(strcmp(line, "dataType") == 0)
10746 {
10747 while(isspace((int)*colon))
10748 colon++;
10749 if(strncmp(colon, "BYTE", 4) == 0)
10750 data_type = MRI_UCHAR;
10751 else if(strncmp(colon, "WORD", 4) == 0)
10752 data_type = MRI_SHORT;
10753 else if(strncmp(colon, "LWORD", 5) == 0)
10754 data_type = MRI_INT;
10755 else if(strncmp(colon, "REAL", 4) == 0)
10756 data_type = MRI_FLOAT;
10757 else if(strncmp(colon, "COMPLEX", 7) == 0)
10758 {
10759 fclose(fp);
10760 errno = 0;
10761 ErrorReturn
10762 (NULL,
10763 (ERROR_UNSUPPORTED,
10764 "sdtRead(%s): unsupported data type '%s'\n",
10765 fname, colon));
10766 }
10767 else
10768 {
10769 fclose(fp);
10770 errno = 0;
10771 ErrorReturn
10772 (NULL,
10773 (ERROR_BADFILE,
10774 "sdtRead(%s): unknown data type '%s'\n", fname, colon));
10775 }
10776 }
10777 else if(strcmp(line, "interval") == 0)
10778 {
10779 if(ndim == 3)
10780 sscanf(colon, "%f %f %f", &xsize, &ysize, &zsize);
10781 else
10782 sscanf(colon, "%f %f %f %f",
10783 &xsize, &ysize, &zsize, &dummy_size);
10784 xsize *= 10.0;
10785 ysize *= 10.0;
10786 zsize *= 10.0;
10787 }
10788 else if(strcmp(line, "sdtOrient") == 0)
10789 {
10790 while(isspace((int)*colon))
10791 colon++;
10792 if(strncmp(colon, "sag", 3) == 0)
10793 orientation = MRI_SAGITTAL;
10794 else if(strncmp(colon, "ax", 2) == 0)
10795 orientation = MRI_HORIZONTAL;
10796 else if(strncmp(colon, "cor", 3) == 0)
10797 orientation = MRI_CORONAL;
10798 else
10799 {
10800 fclose(fp);
10801 errno = 0;
10802 ErrorReturn
10803 (NULL,
10804 (ERROR_BADFILE,
10805 "sdtRead(%s): unknown orientation %s\n", fname, colon));
10806 }
10807 }
10808 else
10809 {
10810 }
10811 }
10812 }
10813
10814 fclose(fp);
10815
10816 if(data_type == -1)
10817 {
10818 errno = 0;
10819 ErrorReturn
10820 (NULL, (ERROR_BADFILE, "sdtRead(%s): data type undefined\n", fname));
10821 }
10822 if(dim[0] == -1 || dim[1] == -1 || dim[2] == -1)
10823 {
10824 errno = 0;
10825 ErrorReturn
10826 (NULL,
10827 (ERROR_BADFILE,
10828 "sdtRead(%s): one or more dimensions undefined\n", fname));
10829 }
10830
10831 if(read_volume)
10832 {
10833 if((fp = fopen(fname, "r")) == NULL)
10834 {
10835 errno = 0;
10836 ErrorReturn
10837 (NULL,
10838 (ERROR_BADFILE,
10839 "sdtRead(%s): error opening data file %s\n", fname, fname));
10840 }
10841
10842 mri = MRIreadRaw(fp, dim[0], dim[1], dim[2], data_type);
10843
10844 if(mri == NULL)
10845 return(NULL);
10846
10847 fclose(fp);
10848
10849 }
10850 else
10851 {
10852 mri = MRIallocHeader(dim[0], dim[1], dim[2], data_type);
10853 if(mri == NULL)
10854 return(NULL);
10855 }
10856
10857 mri->xsize = xsize;
10858 mri->ysize = ysize;
10859 mri->zsize = zsize;
10860
10861 setDirectionCosine(mri, orientation);
10862
10863 mri->thick = mri->zsize;
10864 mri->xend = mri->xsize * mri->width / 2.;
10865 mri->yend = mri->ysize * mri->height / 2.;
10866 mri->zend = mri->zsize * mri->depth / 2.;
10867 mri->xstart = -mri->xend;
10868 mri->ystart = -mri->yend;
10869 mri->zstart = -mri->zend;
10870
10871 mri->imnr0 = 1;
10872 mri->imnr1 = dim[2];
10873
10874 mri->ps = 1.0 /*0.001*/;
10875 mri->tr = 0 ;
10876 mri->te = 0 ;
10877 mri->ti = 0 ;
10878
10879 strcpy(mri->fname, fname) ;
10880
10881 return(mri);
10882
10883 } /* end sdtRead() */
10884
10885 MRI *MRIreadRaw(FILE *fp, int width, int height, int depth, int type)
10886 {
10887 MRI *mri ;
10888 BUFTYPE *buf ;
10889 int slice, pixels ;
10890 int i;
10891
10892 mri = MRIalloc(width, height, depth, type) ;
10893 if (!mri)
10894 return(NULL) ;
10895
10896 pixels = width*height ;
10897 buf = (BUFTYPE *)calloc(pixels, data_size[type]) ;
10898
10899 /* every width x height pixels should be another slice */
10900 for (slice = 0 ; slice < depth ; slice++)
10901 {
10902 if (fread(buf, data_size[type], pixels, fp) != pixels)
10903 {
10904 errno = 0;
10905 ErrorReturn(NULL,
10906 (ERROR_BADFILE, "%s: could not read %dth slice (%d)",
10907 Progname, slice, pixels)) ;
10908 }
10909 if(type == 0)
10910 local_buffer_to_image(buf, mri, slice, 0) ;
10911 if(type == 1)
10912 {
10913 for(i = 0;i < pixels;i++)
10914 ((int *)buf)[i] = orderIntBytes(((int *)buf)[i]);
10915 int_local_buffer_to_image((int *)buf, mri, slice, 0);
10916 }
10917 if(type == 2)
10918 {
10919 for(i = 0;i < pixels;i++)
10920 ((long32 *)buf)[i] = orderLong32Bytes(((long32 *)buf)[i]);
10921 long32_local_buffer_to_image((long32 *)buf, mri, slice, 0);
10922 }
10923 if(type == 3)
10924 {
10925 for(i = 0;i < pixels;i++)
10926 ((float *)buf)[i] = orderFloatBytes(((float *)buf)[i]);
10927 float_local_buffer_to_image((float *)buf, mri, slice, 0);
10928 }
10929 if(type == 4)
10930 {
10931 for(i = 0;i < pixels;i++)
10932 ((short *)buf)[i] = orderShortBytes(((short *)buf)[i]);
10933 short_local_buffer_to_image((short *)buf, mri, slice, 0);
10934 }
10935 }
10936
10937 MRIinitHeader(mri) ;
10938 free(buf) ;
10939 return(mri) ;
10940 }
10941
10942 static void
10943 int_local_buffer_to_image(int *buf, MRI *mri, int slice, int frame)
10944 {
10945 int y, width, height ;
10946 int *pslice ;
10947
10948 width = mri->width ;
10949 height = mri->height ;
10950 for (y = 0 ; y < height ; y++)
10951 {
10952 pslice = &MRIIseq_vox(mri, 0, y, slice, frame) ;
10953 memcpy(pslice, buf, width*sizeof(int)) ;
10954 buf += width ;
10955 }
10956 }
10957
10958 #if 0
10959 static void
10960 image_to_int_buffer(int *buf, MRI *mri, int slice)
10961 {
10962 int y, x, width, height, depth ;
10963
10964 width = mri->width ;
10965 height = mri->height ;
10966 depth = mri->depth;
10967 for (y=0; y < height ; y++)
10968 {
10969 if(mri->type == MRI_UCHAR)
10970 {
10971 for(x = 0;x < depth;x++)
10972 buf[x] = (int)MRIvox(mri, x, y, slice);
10973 }
10974 else if(mri->type == MRI_SHORT)
10975 {
10976 for(x = 0;x < depth;x++)
10977 buf[x] = (int)MRISvox(mri, x, y, slice);
10978 }
10979 else if(mri->type == MRI_LONG)
10980 {
10981 for(x = 0;x < depth;x++)
10982 buf[x] = (int)MRILvox(mri, x, y, slice);
10983 }
10984 else if(mri->type == MRI_FLOAT)
10985 {
10986 for(x = 0;x < depth;x++)
10987 buf[x] = (int)MRIFvox(mri, x, y, slice);
10988 }
10989 else
10990 {
10991 memcpy(buf, mri->slices[slice][y], width*sizeof(int)) ;
10992 }
10993
10994 buf += width ;
10995 }
10996 }
10997 static void
10998 image_to_long_buffer(long *buf, MRI *mri, int slice)
10999 {
11000 int y, x, width, height, depth ;
11001
11002 width = mri->width ;
11003 height = mri->height ;
11004 depth = mri->depth;
11005 for (y=0; y < height ; y++)
11006 {
11007 if(mri->type == MRI_UCHAR)
11008 {
11009 for(x = 0;x < depth;x++)
11010 buf[x] = (long)MRIvox(mri, x, y, slice);
11011 }
11012 else if(mri->type == MRI_INT)
11013 {
11014 for(x = 0;x < depth;x++)
11015 buf[x] = (long)MRIIvox(mri, x, y, slice);
11016 }
11017 else if(mri->type == MRI_SHORT)
11018 {
11019 for(x = 0;x < depth;x++)
11020 buf[x] = (long)MRISvox(mri, x, y, slice);
11021 }
11022 else if(mri->type == MRI_FLOAT)
11023 {
11024 for(x = 0;x < depth;x++)
11025 buf[x] = (long)MRIFvox(mri, x, y, slice);
11026 }
11027 else
11028 {
11029 memcpy(buf, mri->slices[slice][y], width*sizeof(long)) ;
11030 }
11031
11032 buf += width ;
11033 }
11034 }
11035 static void
11036 image_to_float_buffer(float *buf, MRI *mri, int slice)
11037 {
11038 int y, x, width, height, depth ;
11039
11040 width = mri->width ;
11041 height = mri->height ;
11042 depth = mri->depth;
11043 for (y=0; y < height ; y++)
11044 {
11045 if(mri->type == MRI_UCHAR)
11046 {
11047 for(x = 0;x < depth;x++)
11048 buf[x] = (float)MRIvox(mri, x, y, slice);
11049 }
11050 else if(mri->type == MRI_INT)
11051 {
11052 for(x = 0;x < depth;x++)
11053 buf[x] = (float)MRIIvox(mri, x, y, slice);
11054 }
11055 else if(mri->type == MRI_LONG)
11056 {
11057 for(x = 0;x < depth;x++)
11058 buf[x] = (float)MRILvox(mri, x, y, slice);
11059 }
11060 else if(mri->type == MRI_SHORT)
11061 {
11062 for(x = 0;x < depth;x++)
11063 buf[x] = (float)MRISvox(mri, x, y, slice);
11064 }
11065 else
11066 {
11067 memcpy(buf, mri->slices[slice][y], width*sizeof(float)) ;
11068 }
11069
11070 buf += width ;
11071 }
11072 }
11073 #endif
11074
11075 static void
11076 long32_local_buffer_to_image(long32 *buf, MRI *mri, int slice, int frame)
11077 {
11078 int y, width, height ;
11079 long32 *pslice ;
11080
11081 width = mri->width ;
11082 height = mri->height ;
11083 for (y = 0 ; y < height ; y++)
11084 {
11085 pslice = &MRILseq_vox(mri, 0, y, slice, frame) ;
11086 memcpy(pslice, buf, width*sizeof(long)) ;
11087 buf += width ;
11088 }
11089 }
11090
11091
11092 static void
11093 float_local_buffer_to_image(float *buf, MRI *mri, int slice, int frame)
11094 {
11095 int y, width, height ;
11096 float *pslice ;
11097
11098 width = mri->width ;
11099 height = mri->height ;
11100 for (y = 0 ; y < height ; y++)
11101 {
11102 pslice = &MRIFseq_vox(mri, 0, y, slice, frame) ;
11103 memcpy(pslice, buf, width*sizeof(float)) ;
11104 buf += width ;
11105 }
11106 }
11107
11108 static void
11109 short_local_buffer_to_image(short *buf, MRI *mri, int slice, int frame)
11110 {
11111 int y, width, height ;
11112 short *pslice ;
11113
11114 width = mri->width ;
11115 height = mri->height ;
11116 for (y = 0 ; y < height ; y++)
11117 {
11118 pslice = &MRISseq_vox(mri, 0, y, slice, frame) ;
11119 memcpy(pslice, buf, width*sizeof(short)) ;
11120 buf += width ;
11121 }
11122 }
11123
11124 static void
11125 local_buffer_to_image(BUFTYPE *buf, MRI *mri, int slice, int frame)
11126 {
11127 int y, width, height ;
11128 BUFTYPE *pslice ;
11129
11130 width = mri->width ;
11131 height = mri->height ;
11132 for (y = 0 ; y < height ; y++)
11133 {
11134 pslice = &MRIseq_vox(mri, 0, y, slice, frame) ;
11135 memcpy(pslice, buf, width*sizeof(BUFTYPE)) ;
11136 buf += width ;
11137 }
11138 }
11139
11140 #define UNUSED_SPACE_SIZE 256
11141 #define USED_SPACE_SIZE (3*sizeof(float)+4*3*sizeof(float))
11142
11143 #define MGH_VERSION 1
11144
11145 // declare function pointer
11146 static int (*myclose)(FILE *stream);
11147
11148 static MRI *
11149 mghRead(char *fname, int read_volume, int frame)
11150 {
11151 MRI *mri ;
11152 FILE *fp = 0;
11153 int start_frame, end_frame, width, height, depth, nframes, type, x, y, z,
11154 bpv, dof, bytes, version, ival, unused_space_size, good_ras_flag, i ;
11155 BUFTYPE *buf ;
11156 char unused_buf[UNUSED_SPACE_SIZE+1] ;
11157 float fval, xsize, ysize, zsize, x_r, x_a, x_s, y_r, y_a, y_s,
11158 z_r, z_a, z_s, c_r, c_a, c_s ;
11159 short sval ;
11160 // int tag_data_size;
11161 char *ext;
11162 int gzipped=0;
11163 char command[STRLEN];
11164 int nread;
11165 int tag;
11166
11167 ext = strrchr(fname, '.') ;
11168 if (ext){
11169 ++ext;
11170 // if mgz, then it is compressed
11171 if (!stricmp(ext, "mgz") || strstr(fname, "mgh.gz")){
11172 gzipped = 1;
11173 myclose = pclose; // assign function pointer for closing
11174 #ifdef Darwin
11175 // zcat on Max OS always appends and assumes a .Z extention,
11176 // whereas we want .m3z
11177 strcpy(command, "gunzip -c ");
11178 #else
11179 strcpy(command, "zcat ");
11180 #endif
11181 strcat(command, fname);
11182
11183 errno = 0;
11184 fp = popen(command, "r");
11185 if (!fp){
11186 errno = 0;
11187 ErrorReturn(NULL, (ERROR_BADPARM,
11188 "mghRead: encountered error executing: '%s'"
11189 ",frame %d",
11190 command,frame)) ;
11191 }
11192 if (errno){
11193 pclose(fp);
11194 errno = 0;
11195 ErrorReturn(NULL, (ERROR_BADPARM,
11196 "mghRead: encountered error executing: '%s'"
11197 ",frame %d",
11198 command,frame)) ;
11199 }
11200 }
11201 else if (!stricmp(ext, "mgh")){
11202 myclose = fclose; // assign function pointer for closing
11203 fp = fopen(fname, "rb") ;
11204 if (!fp)
11205 {
11206 errno = 0;
11207 ErrorReturn
11208 (NULL,
11209 (ERROR_BADPARM,
11210 "mghRead(%s, %d): could not open file",
11211 fname, frame)) ;
11212 }
11213 }
11214 }
11215
11216 /* keep the compiler quiet */
11217 xsize = ysize = zsize = 0;
11218 x_r = x_a = x_s = 0;
11219 y_r = y_a = y_s = 0;
11220 z_r = z_a = z_s = 0;
11221 c_r = c_a = c_s = 0;
11222
11223 nread = freadIntEx(&version, fp) ;
11224 if (!nread)
11225 ErrorReturn(NULL, (ERROR_BADPARM,"mghRead(%s, %d): read error",
11226 fname, frame)) ;
11227
11228 width = freadInt(fp) ;
11229 height = freadInt(fp) ;
11230 depth = freadInt(fp) ;
11231 nframes = freadInt(fp) ;
11232 type = freadInt(fp) ;
11233 dof = freadInt(fp) ;
11234
11235 unused_space_size = UNUSED_SPACE_SIZE-sizeof(short) ;
11236
11237 good_ras_flag = freadShort(fp) ;
11238 if (good_ras_flag > 0){ /* has RAS and voxel size info */
11239 unused_space_size -= USED_SPACE_SIZE ;
11240 xsize = freadFloat(fp) ;
11241 ysize = freadFloat(fp) ;
11242 zsize = freadFloat(fp) ;
11243
11244 x_r = freadFloat(fp) ; x_a = freadFloat(fp) ; x_s = freadFloat(fp) ;
11245 y_r = freadFloat(fp) ; y_a = freadFloat(fp) ; y_s = freadFloat(fp) ;
11246
11247 z_r = freadFloat(fp) ; z_a = freadFloat(fp) ; z_s = freadFloat(fp) ;
11248 c_r = freadFloat(fp) ; c_a = freadFloat(fp) ; c_s = freadFloat(fp) ;
11249 }
11250 /* so stuff can be added to the header in the future */
11251 fread(unused_buf, sizeof(char), unused_space_size, fp) ;
11252
11253 switch (type){
11254 default:
11255 case MRI_FLOAT: bpv = sizeof(float) ; break ;
11256 case MRI_UCHAR: bpv = sizeof(char) ; break ;
11257 case MRI_SHORT: bpv = sizeof(short) ; break ;
11258 case MRI_INT: bpv = sizeof(int) ; break ;
11259 case MRI_TENSOR: bpv = sizeof(float) ; nframes = 9 ; break ;
11260 }
11261 bytes = width * height * bpv ; /* bytes per slice */
11262 if(!read_volume){
11263 mri = MRIallocHeader(width, height, depth, type) ;
11264 mri->dof = dof ; mri->nframes = nframes ;
11265 if(gzipped){ // pipe cannot seek
11266 int count;
11267 for (count=0; count < mri->nframes*width*height*depth*bpv; count++)
11268 fgetc(fp);
11269 }
11270 else
11271 fseek(fp, mri->nframes*width*height*depth*bpv, SEEK_CUR) ;
11272 }
11273 else{
11274 if (frame >= 0) {
11275 start_frame = end_frame = frame ;
11276 if (gzipped){ // pipe cannot seek
11277 int count;
11278 for (count=0; count < frame*width*height*depth*bpv; count++)
11279 fgetc(fp);
11280 }
11281 else
11282 fseek(fp, frame*width*height*depth*bpv, SEEK_CUR) ;
11283 nframes = 1 ;
11284 }
11285 else{ /* hack - # of frames < -1 means to only read in that
11286 many frames. Otherwise I would have had to change the whole
11287 MRIread interface and that was too much of a pain. Sorry.
11288 */
11289 if (frame < -1)
11290 nframes = frame*-1 ;
11291
11292 start_frame = 0 ; end_frame = nframes-1 ;
11293 if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON)
11294 fprintf(stderr, "read %d frames\n", nframes);
11295 }
11296 buf = (BUFTYPE *)calloc(bytes, sizeof(BUFTYPE)) ;
11297 mri = MRIallocSequence(width, height, depth, type, nframes) ;
11298 mri->dof = dof ;
11299 for (frame = start_frame ; frame <= end_frame ; frame++){
11300 for (z = 0 ; z < depth ; z++){
11301 if (fread(buf, sizeof(char), bytes, fp) != bytes){
11302 // fclose(fp) ;
11303 myclose(fp);
11304 free(buf) ;
11305 ErrorReturn
11306 (NULL,
11307 (ERROR_BADFILE,
11308 "mghRead(%s): could not read %d bytes at slice %d",
11309 fname, bytes, z)) ;
11310 }
11311 switch (type)
11312 {
11313 case MRI_INT:
11314 for (i = y = 0 ; y < height ; y++)
11315 {
11316 for (x = 0 ; x < width ; x++, i++)
11317 {
11318 ival = orderIntBytes(((int *)buf)[i]) ;
11319 MRIIseq_vox(mri,x,y,z,frame-start_frame) = ival ;
11320 }
11321 }
11322 break ;
11323 case MRI_SHORT:
11324 for (i = y = 0 ; y < height ; y++)
11325 {
11326 for (x = 0 ; x < width ; x++, i++)
11327 {
11328 sval = orderShortBytes(((short *)buf)[i]) ;
11329 MRISseq_vox(mri,x,y,z,frame-start_frame) = sval ;
11330 }
11331 }
11332 break ;
11333 case MRI_TENSOR:
11334 case MRI_FLOAT:
11335 for (i = y = 0 ; y < height ; y++)
11336 {
11337 for (x = 0 ; x < width ; x++, i++)
11338 {
11339 fval = orderFloatBytes(((float *)buf)[i]) ;
11340 MRIFseq_vox(mri,x,y,z,frame-start_frame) = fval ;
11341 }
11342 }
11343 break ;
11344 case MRI_UCHAR:
11345 local_buffer_to_image(buf, mri, z, frame-start_frame) ;
11346 break ;
11347 default:
11348 errno = 0;
11349 ErrorReturn(NULL,
11350 (ERROR_UNSUPPORTED, "mghRead: unsupported type %d",
11351 mri->type)) ;
11352 break ;
11353 }
11354 }
11355 }
11356 if (buf) free(buf) ;
11357 }
11358
11359 if(good_ras_flag > 0){
11360 mri->xsize = xsize ;
11361 mri->ysize = ysize ;
11362 mri->zsize = zsize ;
11363
11364 mri->x_r = x_r ;
11365 mri->x_a = x_a ;
11366 mri->x_s = x_s ;
11367
11368 mri->y_r = y_r ;
11369 mri->y_a = y_a ;
11370 mri->y_s = y_s ;
11371
11372 mri->z_r = z_r ;
11373 mri->z_a = z_a ;
11374 mri->z_s = z_s ;
11375
11376 mri->c_r = c_r ;
11377 mri->c_a = c_a ;
11378 mri->c_s = c_s ;
11379 if (good_ras_flag > 0)
11380 mri->ras_good_flag = 1 ;
11381 }
11382 else{
11383 fprintf
11384 (stderr,
11385 "-----------------------------------------------------------------\n"
11386 "Could not find the direction cosine information.\n"
11387 "Will use the CORONAL orientation.\n"
11388 "If not suitable, please provide the information in %s.\n"
11389 "-----------------------------------------------------------------\n",
11390 fname
11391 );
11392 setDirectionCosine(mri, MRI_CORONAL);
11393 }
11394 // read TR, Flip, TE, TI, FOV
11395 if (freadFloatEx(&(mri->tr), fp)){
11396 if (freadFloatEx(&fval, fp))
11397 {
11398 mri->flip_angle = fval;
11399 // flip_angle is double. I cannot use the same trick.
11400 if (freadFloatEx(&(mri->te), fp))
11401 if (freadFloatEx(&(mri->ti), fp))
11402 if (freadFloatEx(&(mri->fov), fp))
11403 ;
11404 }
11405 }
11406 // tag reading
11407 {
11408 long long len ;
11409 char *fnamedir;
11410
11411 while ((tag = TAGreadStart(fp, &len)) != 0){
11412 switch (tag){
11413 case TAG_OLD_MGH_XFORM:
11414 case TAG_MGH_XFORM:
11415 fgets(mri->transform_fname, len+1, fp);
11416 // if this file exists then read the transform
11417 if(!FileExists(mri->transform_fname)){
11418 printf(" Talairach transform %s does not exist ...\n",
11419 mri->transform_fname);
11420 fnamedir = fio_dirname(fname);
11421 sprintf(mri->transform_fname,"%s/transforms/talairach.xfm",fnamedir);
11422 printf(" ... trying %s ...",mri->transform_fname);
11423 if(FileExists(mri->transform_fname)) printf("which does exist ");
11424 else printf("which does not exist ");
11425 printf("\n");
11426 free(fnamedir);
11427 }
11428 if(FileExists(mri->transform_fname)){
11429 // copied from corRead()
11430 if(input_transform_file
11431 (mri->transform_fname, &(mri->transform)) == NO_ERROR){
11432 mri->linear_transform = get_linear_transform_ptr(&mri->transform);
11433 mri->inverse_linear_transform =
11434 get_inverse_linear_transform_ptr(&mri->transform);
11435 mri->free_transform = 1;
11436 if (DIAG_VERBOSE_ON)
11437 fprintf
11438 (stderr,
11439 "INFO: loaded talairach xform : %s\n", mri->transform_fname);
11440 }
11441 else{
11442 errno = 0;
11443 ErrorPrintf
11444 (ERROR_BAD_FILE,
11445 "error loading transform from %s",mri->transform_fname);
11446 mri->linear_transform = NULL;
11447 mri->inverse_linear_transform = NULL;
11448 mri->free_transform = 1;
11449 (mri->transform_fname)[0] = '\0';
11450 }
11451 }
11452 else{
11453 fprintf(stderr,
11454 "Can't find the talairach xform '%s'\n",
11455 mri->transform_fname);
11456 fprintf(stderr, "Transform is not loaded into mri\n");
11457 }
11458 break ;
11459 case TAG_CMDLINE:
11460 if (mri->ncmds > MAX_CMDS)
11461 ErrorExit(ERROR_NOMEMORY,
11462 "mghRead(%s): too many commands (%d) in file",
11463 fname,mri->ncmds);
11464 mri->cmdlines[mri->ncmds] = calloc(len+1, sizeof(char)) ;
11465 fread(mri->cmdlines[mri->ncmds], sizeof(char), len, fp) ;
11466 mri->cmdlines[mri->ncmds][len] = 0 ;
11467 mri->ncmds++ ;
11468 break ;
11469 default:
11470 TAGskip(fp, tag, (long long)len) ;
11471 break ;
11472 }
11473 }
11474 }
11475
11476
11477 // fclose(fp) ;
11478 myclose(fp);
11479
11480 // xstart, xend, ystart, yend, zstart, zend are not stored
11481 mri->xstart = - mri->width/2.*mri->xsize;
11482 mri->xend = mri->width/2. * mri->xsize;
11483 mri->ystart = - mri->height/2.*mri->ysize;
11484 mri->yend = mri->height/2.*mri->ysize;
11485 mri->zstart = - mri->depth/2.*mri->zsize;
11486 mri->zend = mri->depth/2.*mri->zsize;
11487 strcpy(mri->fname, fname);
11488 return(mri) ;
11489 }
11490
11491 static int
11492 mghWrite(MRI *mri, char *fname, int frame)
11493 {
11494 FILE *fp =0;
11495 int ival, start_frame, end_frame, x, y, z, width, height, depth,
11496 unused_space_size, flen ;
11497 char buf[UNUSED_SPACE_SIZE+1] ;
11498 float fval ;
11499 short sval ;
11500 int gzipped = 0;
11501 char *ext;
11502
11503 if (frame >= 0)
11504 start_frame = end_frame = frame ;
11505 else
11506 {
11507 start_frame = 0 ; end_frame = mri->nframes-1 ;
11508 }
11509 ////////////////////////////////////////////////////////////
11510 ext = strrchr(fname, '.') ;
11511 if (ext)
11512 {
11513 char command[STRLEN];
11514 ++ext;
11515 // if mgz, then it is compressed
11516 if (!stricmp(ext, "mgz") || strstr(fname, "mgh.gz"))
11517 {
11518 // route stdout to a file
11519 gzipped = 1;
11520 myclose = pclose; // assign function pointer for closing
11521 // pipe writeto "gzip" open
11522 // pipe can executed under shell and thus understands >
11523 strcpy(command, "gzip -f -c > ");
11524 strcat(command, fname);
11525 errno = 0;
11526 fp = popen(command, "w");
11527 if (!fp)
11528 {
11529 errno = 0;
11530 ErrorReturn
11531 (ERROR_BADPARM,
11532 (ERROR_BADPARM,"mghWrite(%s, %d): could not open file",
11533 fname, frame)) ;
11534 }
11535 if (errno)
11536 {
11537 pclose(fp);
11538 errno = 0;
11539 ErrorReturn
11540 (ERROR_BADPARM,
11541 (ERROR_BADPARM,"mghWrite(%s, %d): gzip had error",
11542 fname, frame)) ;
11543 }
11544 }
11545 else if (!stricmp(ext, "mgh"))
11546 {
11547 fp = fopen(fname, "wb") ;
11548 myclose = fclose; // assign function pointer for closing
11549 if (!fp)
11550 {
11551 errno = 0;
11552 ErrorReturn
11553 (ERROR_BADPARM,
11554 (ERROR_BADPARM,"mghWrite(%s, %d): could not open file",
11555 fname, frame)) ;
11556 }
11557 }
11558 }
11559 else
11560 {
11561 errno = 0;
11562 ErrorReturn(ERROR_BADPARM,
11563 (ERROR_BADPARM,"mghWrite: filename '%s' "
11564 "needs to have an extension of .mgh or .mgz",
11565 fname)) ;
11566 }
11567
11568 // sanity-check: make sure a file pointer was assigned
11569 if (fp==0)
11570 {
11571 errno = 0;
11572 ErrorReturn
11573 (ERROR_BADPARM,
11574 (ERROR_BADPARM,"mghWrite(%s, %d): could not open file: fp==0",
11575 fname, frame)) ;
11576 }
11577
11578 /* WARNING - adding or removing anything before nframes will
11579 cause mghAppend to fail.
11580 */
11581 width = mri->width ; height = mri->height ; depth = mri->depth ;
11582 fwriteInt(MGH_VERSION, fp) ;
11583 fwriteInt(mri->width, fp) ;
11584 fwriteInt(mri->height, fp) ;
11585 fwriteInt(mri->depth, fp) ;
11586 fwriteInt(mri->nframes, fp) ;
11587 fwriteInt(mri->type, fp) ;
11588 fwriteInt(mri->dof, fp) ;
11589
11590 unused_space_size = UNUSED_SPACE_SIZE - USED_SPACE_SIZE - sizeof(short) ;
11591
11592 /* write RAS and voxel size info */
11593 fwriteShort(mri->ras_good_flag ? 1 : -1, fp) ;
11594 fwriteFloat(mri->xsize, fp) ;
11595 fwriteFloat(mri->ysize, fp) ;
11596 fwriteFloat(mri->zsize, fp) ;
11597
11598 fwriteFloat(mri->x_r, fp) ;
11599 fwriteFloat(mri->x_a, fp) ;
11600 fwriteFloat(mri->x_s, fp) ;
11601
11602 fwriteFloat(mri->y_r, fp) ;
11603 fwriteFloat(mri->y_a, fp) ;
11604 fwriteFloat(mri->y_s, fp) ;
11605
11606 fwriteFloat(mri->z_r, fp) ;
11607 fwriteFloat(mri->z_a, fp) ;
11608 fwriteFloat(mri->z_s, fp) ;
11609
11610 fwriteFloat(mri->c_r, fp) ;
11611 fwriteFloat(mri->c_a, fp) ;
11612 fwriteFloat(mri->c_s, fp) ;
11613
11614 /* so stuff can be added to the header in the future */
11615 memset(buf, 0, UNUSED_SPACE_SIZE*sizeof(char)) ;
11616 fwrite(buf, sizeof(char), unused_space_size, fp) ;
11617
11618 for (frame = start_frame ; frame <= end_frame ; frame++)
11619 {
11620 for (z = 0 ; z < depth ; z++)
11621 {
11622 for (y = 0 ; y < height ; y++)
11623 {
11624 switch (mri->type)
11625 {
11626 case MRI_SHORT:
11627 for (x = 0 ; x < width ; x++)
11628 {
11629 if (z == 74 && y == 16 && x == 53)
11630 DiagBreak() ;
11631 sval = MRISseq_vox(mri,x,y,z,frame) ;
11632 fwriteShort(sval, fp) ;
11633 }
11634 break ;
11635 case MRI_INT:
11636 for (x = 0 ; x < width ; x++)
11637 {
11638 if (z == 74 && y == 16 && x == 53)
11639 DiagBreak() ;
11640 ival = MRIIseq_vox(mri,x,y,z,frame) ;
11641 fwriteInt(ival, fp) ;
11642 }
11643 break ;
11644 case MRI_FLOAT:
11645 for (x = 0 ; x < width ; x++)
11646 {
11647 if (z == 74 && y == 16 && x == 53)
11648 DiagBreak() ;
11649 fval = MRIFseq_vox(mri,x,y,z,frame) ;
11650 //if(x==10 && y == 0 && z == 0 && frame == 67)
11651 // printf("MRIIO: %g\n",fval);
11652 fwriteFloat(fval, fp) ;
11653 }
11654 break ;
11655 case MRI_UCHAR:
11656 if (fwrite(&MRIseq_vox(mri,0,y,z,frame),
11657 sizeof(BUFTYPE), width, fp)
11658 != width)
11659 {
11660 errno = 0;
11661 ErrorReturn
11662 (ERROR_BADFILE,
11663 (ERROR_BADFILE,
11664 "mghWrite: could not write %d bytes to %s",
11665 width, fname)) ;
11666 }
11667 break ;
11668 default:
11669 errno = 0;
11670 ErrorReturn
11671 (ERROR_UNSUPPORTED,
11672 (ERROR_UNSUPPORTED, "mghWrite: unsupported type %d",
11673 mri->type)) ;
11674 break ;
11675 }
11676 }
11677 }
11678 }
11679
11680 fwriteFloat(mri->tr, fp) ;
11681 fwriteFloat(mri->flip_angle, fp) ;
11682 fwriteFloat(mri->te, fp) ;
11683 fwriteFloat(mri->ti, fp) ;
11684 fwriteFloat(mri->fov, fp); // somebody forgot this
11685
11686 // if mri->transform_fname has non-zero length
11687 // I write a tag with strlength and write it
11688 // I increase the tag_datasize with this amount
11689 if ((flen=strlen(mri->transform_fname))> 0)
11690 {
11691 #if 0
11692 fwriteInt(TAG_MGH_XFORM, fp);
11693 fwriteInt(flen+1, fp); // write the size + 1 (for null) of string
11694 fputs(mri->transform_fname, fp);
11695 #else
11696 TAGwrite(fp, TAG_MGH_XFORM, mri->transform_fname, flen+1) ;
11697 #endif
11698 }
11699 // If we have any saved tag data, write it.
11700 if( NULL != mri->tag_data ) {
11701 // Int is 32 bit on 32 bit and 64 bit os and thus it is safer
11702 fwriteInt(mri->tag_data_size, fp);
11703 fwrite( mri->tag_data, mri->tag_data_size, 1, fp );
11704 }
11705
11706
11707 // write other tags
11708 {
11709 int i ;
11710
11711 for (i = 0 ; i < mri->ncmds ; i++)
11712 TAGwrite(fp, TAG_CMDLINE, mri->cmdlines[i], strlen(mri->cmdlines[i])+1) ;
11713 }
11714
11715
11716 // fclose(fp) ;
11717 myclose(fp);
11718
11719 return(NO_ERROR) ;
11720 }
11721
11722
11723 MRI *
11724 MRIreorder(MRI *mri_src, MRI *mri_dst, int xdim, int ydim, int zdim)
11725 {
11726 // note that allowed xdim, ydim, zdim values are only +/- 1,2,3 only
11727 // xdim tells the original x-axis goes to which axis of the new, etc.
11728 int width, height, depth, xs, ys, zs, xd, yd, zd, x, y, z, f ;
11729 float ras_sign;
11730
11731 width = mri_src->width ; height = mri_src->height ; depth = mri_src->depth;
11732 if (!mri_dst)
11733 mri_dst = MRIclone(mri_src, NULL) ;
11734
11735 /* check that the source ras coordinates are good and
11736 that each direction is used once and only once */
11737 if(mri_src->ras_good_flag)
11738 if(abs(xdim) * abs(ydim) * abs(zdim) != 6 ||
11739 abs(xdim) + abs(ydim) + abs(zdim) != 6)
11740 mri_dst->ras_good_flag = 0;
11741
11742 xd = yd = zd = 0 ;
11743
11744 ras_sign = (xdim < 0 ? -1.0 : 1.0);
11745 // check xdim direction size (XDIM=1, YDIM=2, ZDIM=3)
11746 // xdim tells original x-axis goes to where
11747 switch (abs(xdim))
11748 {
11749 default:
11750 case XDIM:
11751 if (mri_dst->width != width)
11752 {
11753 errno = 0;
11754 ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst width"));
11755 }
11756 break ;
11757 case YDIM:
11758 if (mri_dst->height != width)
11759 {
11760 errno = 0;
11761 ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst width"));
11762 }
11763 break ;
11764 case ZDIM:
11765 if (mri_dst->depth != width)
11766 {
11767 errno = 0;
11768 ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst width"));
11769 }
11770 break ;
11771 }
11772 ras_sign = (ydim < 0 ? -1.0 : 1.0);
11773 // check ydim
11774 // ydim tells original y-axis goes to where
11775 switch (abs(ydim))
11776 {
11777 default:
11778 case XDIM:
11779 if (mri_dst->width != height)
11780 {
11781 errno = 0;
11782 ErrorReturn
11783 (NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst height"));
11784 }
11785 break ;
11786 case YDIM:
11787 if (mri_dst->height != height)
11788 {
11789 errno = 0;
11790 ErrorReturn
11791 (NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst height"));
11792 }
11793 break ;
11794 case ZDIM:
11795 if (mri_dst->depth != height)
11796 {
11797 errno = 0;
11798 ErrorReturn
11799 (NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst height"));
11800 }
11801 break ;
11802 }
11803 ras_sign = (zdim < 0 ? -1.0 : 1.0);
11804 // check zdim
11805 // zdim tells original z-axis goes to where
11806 switch (abs(zdim))
11807 {
11808 default:
11809 case XDIM:
11810 if (mri_dst->width != depth)
11811 {
11812 errno = 0;
11813 ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst depth"));
11814 }
11815 break ;
11816 case YDIM:
11817 if (mri_dst->height != depth)
11818 {
11819 errno = 0;
11820 ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst depth"));
11821 }
11822 break ;
11823 case ZDIM:
11824 if (mri_dst->depth != depth)
11825 {
11826 errno = 0;
11827 ErrorReturn(NULL,(ERROR_BADPARM, "MRIreorder: incorrect dst depth"));
11828 }
11829 break ;
11830 }
11831
11832 for(f = 0; f < mri_src->nframes; f++){
11833 for (zs = 0 ; zs < depth ; zs++)
11834 {
11835 if (zdim < 0) z = depth - zs - 1 ;
11836 else z = zs ;
11837 switch (abs(zdim))
11838 {
11839 case XDIM: xd = z ; break ;
11840 case YDIM: yd = z ; break ;
11841 case ZDIM:
11842 default: zd = z ; break ;
11843 }
11844 for (ys = 0 ; ys < height ; ys++)
11845 {
11846 if (ydim < 0) y = height - ys - 1 ;
11847 else y = ys ;
11848 switch (abs(ydim))
11849 {
11850 case XDIM: xd = y ; break ;
11851 case YDIM: yd = y ; break ;
11852 case ZDIM:
11853 default: zd = y ; break ;
11854 }
11855 for (xs = 0 ; xs < width ; xs++)
11856 {
11857 if (xdim < 0) x = width - xs - 1 ;
11858 else x = xs ;
11859 switch (abs(xdim))
11860 {
11861 case XDIM: xd = x ; break ;
11862 case YDIM: yd = x ; break ;
11863 case ZDIM:
11864 default: zd = x ; break ;
11865 }
11866 switch (mri_src->type)
11867 {
11868 case MRI_SHORT:
11869 MRISseq_vox(mri_dst,xd,yd,zd,f) =
11870 MRISseq_vox(mri_src,xs,ys,zs,f) ;
11871 break ;
11872 case MRI_FLOAT:
11873 MRIFseq_vox(mri_dst,xd,yd,zd,f) =
11874 MRIFseq_vox(mri_src,xs,ys,zs,f);
11875 break ;
11876 case MRI_INT:
11877 MRIIseq_vox(mri_dst,xd,yd,zd,f) =
11878 MRIIseq_vox(mri_src,xs,ys,zs,f);
11879 break ;
11880 case MRI_UCHAR:
11881 MRIseq_vox(mri_dst,xd,yd,zd,f) =
11882 MRIseq_vox(mri_src,xs,ys,zs,f);
11883 break ;
11884 default:
11885 errno = 0;
11886 ErrorReturn
11887 (NULL,(ERROR_UNSUPPORTED,
11888 "MRIreorder: unsupported voxel format %d",
11889 mri_src->type)) ;
11890 break ;
11891 }
11892 }
11893 }
11894 }
11895 }/* end loop over frames */
11896 return(mri_dst) ;
11897 }
11898
11899 /*-----------------------------------------------------
11900 Parameters:
11901
11902 Returns value:
11903
11904 Description
11905 Write the MRI header information to the file
11906 COR-.info in the directory specified by 'fpref'
11907 ------------------------------------------------------*/
11908 int
11909 MRIwriteInfo(MRI *mri, char *fpref)
11910 {
11911 FILE *fp;
11912 char fname[STRLEN];
11913 int slice_direction;
11914 sprintf(fname,"%s/%s",fpref, INFO_FNAME);
11915 fp = fopen(fname,"w");
11916 if (fp == NULL)
11917 {
11918 errno = 0;
11919 ErrorReturn(ERROR_NO_FILE,
11920 (ERROR_NO_FILE,
11921 "MRIwriteInfo(%s): could not open %s.\n", fpref, fname)) ;
11922 }
11923
11924 fprintf(fp, "%s %d\n", "imnr0", mri->imnr0);
11925 fprintf(fp, "%s %d\n", "imnr1", mri->imnr1);
11926 slice_direction = getSliceDirection(mri);
11927 fprintf(fp, "%s %d\n", "ptype",
11928 slice_direction == MRI_CORONAL ? 2 :
11929 slice_direction == MRI_HORIZONTAL ? 0 : 1) ;
11930 fprintf(fp, "%s %d\n", "x", mri->width);
11931 fprintf(fp, "%s %d\n", "y", mri->height);
11932 fprintf(fp, "%s %f\n", "fov", mri->fov/MM_PER_METER);
11933 fprintf(fp, "%s %f\n", "thick", mri->ps/MM_PER_METER);
11934 fprintf(fp, "%s %f\n", "psiz", mri->ps/MM_PER_METER);
11935 fprintf(fp, "%s %f\n", "locatn", mri->location); /* locatn */
11936 fprintf(fp, "%s %f\n", "strtx", mri->xstart/MM_PER_METER); /* strtx */
11937 fprintf(fp, "%s %f\n", "endx", mri->xend/MM_PER_METER); /* endx */
11938 fprintf(fp, "%s %f\n", "strty", mri->ystart/MM_PER_METER); /* strty */
11939 fprintf(fp, "%s %f\n", "endy", mri->yend/MM_PER_METER); /* endy */
11940 fprintf(fp, "%s %f\n", "strtz", mri->zstart/MM_PER_METER); /* strtz */
11941 fprintf(fp, "%s %f\n", "endz", mri->zend/MM_PER_METER); /* endz */
11942 fprintf(fp, "%s %f\n", "tr", mri->tr) ;
11943 fprintf(fp, "%s %f\n", "te", mri->te) ;
11944 fprintf(fp, "%s %f\n", "ti", mri->ti) ;
11945 if (mri->linear_transform)
11946 {
11947 char fname[STRLEN] ;
11948
11949 /*
11950 this won't work for relative paths which are not the same for the
11951 destination directory as for the the source directory.
11952 */
11953 sprintf(fname,"%s", mri->transform_fname);
11954 fprintf(fp, "xform %s\n", fname) ;
11955
11956 #if 0
11957 /* doesn't work - I don't know why */
11958 if (output_transform_file(fname, "talairach xfm", &mri->transform) != OK)
11959 {
11960 errno = 0;
11961 ErrorPrintf
11962 (ERROR_BADFILE, "MRIwriteInfo(%s): xform write failed",fpref);
11963 }
11964 #endif
11965
11966 }
11967
11968 fprintf(fp, "%s %d\n", "ras_good_flag", mri->ras_good_flag);
11969 fprintf(fp, "%s %f %f %f\n", "x_ras", mri->x_r, mri->x_a, mri->x_s);
11970 fprintf(fp, "%s %f %f %f\n", "y_ras", mri->y_r, mri->y_a, mri->y_s);
11971 fprintf(fp, "%s %f %f %f\n", "z_ras", mri->z_r, mri->z_a, mri->z_s);
11972 fprintf(fp, "%s %f %f %f\n", "c_ras", mri->c_r, mri->c_a, mri->c_s);
11973
11974 fclose(fp);
11975
11976 return(NO_ERROR) ;
11977 }
11978
11979 /*-----------------------------------------------------
11980 Parameters:
11981
11982 Returns value:
11983
11984 Description
11985 Write an MRI header and a set of data files to
11986 the directory specified by 'fpref'
11987 ------------------------------------------------------*/
11988 int
11989 MRIappend(MRI *mri, char *fpref)
11990 {
11991 int type, frame ;
11992 char fname[STRLEN] ;
11993
11994 MRIunpackFileName(fpref, &frame, &type, fname) ;
11995 if (type == MRI_MGH_FILE)
11996 return(mghAppend(mri, fname, frame)) ;
11997 else
11998 {
11999 errno = 0;
12000 ErrorReturn(ERROR_UNSUPPORTED,
12001 (ERROR_UNSUPPORTED, "MRIappend(%s): file type not supported",
12002 fname)) ;
12003 }
12004
12005 return(NO_ERROR) ;
12006 }
12007
12008 static int
12009 mghAppend(MRI *mri, char *fname, int frame)
12010 {
12011 FILE *fp ;
12012 int start_frame, end_frame, x, y, z, width, height, depth, nframes ;
12013
12014 if (frame >= 0)
12015 start_frame = end_frame = frame ;
12016 else
12017 {
12018 start_frame = 0 ; end_frame = mri->nframes-1 ;
12019 }
12020 fp = fopen(fname, "rb") ;
12021 if (!fp) /* doesn't exist */
12022 return(mghWrite(mri, fname, frame)) ;
12023 fclose(fp) ;
12024 fp = fopen(fname, "r+b") ;
12025 if (!fp)
12026 {
12027 errno = 0;
12028 ErrorReturn(ERROR_BADPARM,
12029 (ERROR_BADPARM,"mghAppend(%s, %d): could not open file",
12030 fname, frame)) ;
12031 }
12032
12033 /* WARNING - this is dependent on the order of writing in mghWrite */
12034 width = mri->width ; height = mri->height ; depth = mri->depth ;
12035 fseek(fp, 4*sizeof(int), SEEK_SET) ;
12036 nframes = freadInt(fp) ;
12037 fseek(fp, 4*sizeof(int), SEEK_SET) ;
12038 fwriteInt(nframes+end_frame-start_frame+1, fp) ;
12039 fseek(fp, 0, SEEK_END) ;
12040
12041 for (frame = start_frame ; frame <= end_frame ; frame++)
12042 {
12043 for (z = 0 ; z < depth ; z++)
12044 {
12045 for (y = 0 ; y < height ; y++)
12046 {
12047 switch (mri->type)
12048 {
12049 case MRI_FLOAT:
12050 for (x = 0 ; x < width ; x++)
12051 {
12052 fwriteFloat(MRIFseq_vox(mri,x,y,z,frame), fp) ;
12053 }
12054 break ;
12055 case MRI_UCHAR:
12056 if (fwrite(&MRIseq_vox(mri,0,y,z,frame),
12057 sizeof(BUFTYPE), width, fp)
12058 != width)
12059 {
12060 errno = 0;
12061 ErrorReturn
12062 (ERROR_BADFILE,
12063 (ERROR_BADFILE,
12064 "mghAppend: could not write %d bytes to %s",
12065 width, fname)) ;
12066 }
12067 break ;
12068 default:
12069 errno = 0;
12070 ErrorReturn
12071 (ERROR_UNSUPPORTED,
12072 (ERROR_UNSUPPORTED, "mghAppend: unsupported type %d",
12073 mri->type)) ;
12074 break ;
12075 }
12076 }
12077 }
12078 }
12079
12080 fclose(fp) ;
12081 return(NO_ERROR) ;
12082 }
12083
12084 /*-----------------------------------------------------
12085 Parameters:
12086
12087 Returns value:
12088
12089 Description
12090 ------------------------------------------------------*/
12091 int
12092 MRIunpackFileName(char *inFname, int *pframe, int *ptype, char *outFname)
12093 {
12094 char *number = NULL, *at = NULL, buf[STRLEN] ;
12095 struct stat stat_buf;
12096
12097 strcpy(outFname, inFname) ;
12098 number = strrchr(outFname, '#') ;
12099 at = strrchr(outFname, '@');
12100
12101 if(at)
12102 *at = '\0';
12103
12104 if (number) /* '#' in filename indicates frame # */
12105 {
12106 if (sscanf(number+1, "%d", pframe) < 1)
12107 *pframe = -1 ;
12108 *number = 0 ;
12109 }
12110 else
12111 *pframe = -1 ;
12112
12113 if (at)
12114 {
12115 at = StrUpper(strcpy(buf, at+1)) ;
12116 if (!strcmp(at, "MNC"))
12117 *ptype = MRI_MINC_FILE ;
12118 else if (!strcmp(at, "MINC"))
12119 *ptype = MRI_MINC_FILE ;
12120 else if (!strcmp(at, "BRIK"))
12121 *ptype = BRIK_FILE ;
12122 else if (!strcmp(at, "SIEMENS"))
12123 *ptype = SIEMENS_FILE ;
12124 else if (!strcmp(at, "MGH"))
12125 *ptype = MRI_MGH_FILE ;
12126 else if (!strcmp(at, "MR"))
12127 *ptype = GENESIS_FILE ;
12128 else if (!strcmp(at, "GE"))
12129 *ptype = GE_LX_FILE ;
12130 else if (!strcmp(at, "IMG"))
12131 *ptype = MRI_ANALYZE_FILE ;
12132 else if (!strcmp(at, "COR"))
12133 *ptype = MRI_CORONAL_SLICE_DIRECTORY ;
12134 else if (!strcmp(at, "BSHORT"))
12135 *ptype = BSHORT_FILE;
12136 else if (!strcmp(at, "SDT"))
12137 *ptype = SDT_FILE;
12138 else
12139 {
12140 errno = 0;
12141 ErrorExit(ERROR_UNSUPPORTED, "unknown file type %s", at);
12142 }
12143 }
12144 else /* no '@' found */
12145 {
12146
12147 *ptype = -1;
12148
12149
12150 if(is_genesis(outFname))
12151 *ptype = GENESIS_FILE;
12152 else if(is_ge_lx(outFname))
12153 *ptype = GE_LX_FILE;
12154 else if(is_brik(outFname))
12155 *ptype = BRIK_FILE;
12156 else if(is_siemens(outFname))
12157 *ptype = SIEMENS_FILE;
12158 else if(is_analyze(outFname))
12159 *ptype = MRI_ANALYZE_FILE;
12160 else if (is_signa(outFname))
12161 *ptype = SIGNA_FILE ;
12162 else if(is_sdt(outFname))
12163 *ptype = SDT_FILE;
12164 else if(is_mgh(outFname))
12165 *ptype = MRI_MGH_FILE;
12166 else if(is_mnc(outFname))
12167 *ptype = MRI_MINC_FILE;
12168 else if(is_bshort(outFname))
12169 *ptype = BSHORT_FILE;
12170 else
12171 {
12172 if(stat(outFname, &stat_buf) < 0)
12173 {
12174 errno = 0;
12175 ErrorReturn
12176 (ERROR_BADFILE,
12177 (ERROR_BAD_FILE, "can't stat file %s", outFname));
12178 }
12179 if(S_ISDIR(stat_buf.st_mode))
12180 *ptype = MRI_CORONAL_SLICE_DIRECTORY;
12181 }
12182
12183 if(*ptype == -1)
12184 {
12185 errno = 0;
12186 ErrorReturn
12187 (ERROR_BADPARM,
12188 (ERROR_BADPARM,
12189 "unrecognized file type for file %s", outFname));
12190 }
12191
12192 }
12193
12194 return(NO_ERROR) ;
12195 }
12196
12197 /*---------------------------------------------------------------
12198 MRIwriteAnyFormat() - saves the data in the given mri structure to
12199 "any" format, where "any" is defined as anything writable by
12200 MRIwrite and wfile format. If wfile format is used, then mriframe
12201 must be a valid frame number. The val field of the surf is
12202 preserved. If another format is used, then, if mriframe = -1, then
12203 all frames are stored, otherwise the given frame is stored. If
12204 fmt is NULL, then it will attempt to infer the format from the
12205 name. surf only needs to be supplied when format is wfile. Legal
12206 formats include: wfile, paint, w, bshort, bfloat, COR, analyze,
12207 analyze4d, spm.
12208 ---------------------------------------------------------------*/
12209 int MRIwriteAnyFormat(MRI *mri, char *fileid, char *fmt,
12210 int mriframe, MRIS *surf)
12211 {
12212 int fmtid, err, n, r, c, s;
12213 float *v=NULL,f;
12214 MRI *mritmp=NULL;
12215
12216 if(fmt != NULL && (!strcmp(fmt,"paint") || !strcmp(fmt,"w") ||
12217 !strcmp(fmt,"wfile")) ){
12218
12219 /* Save as a wfile */
12220 if(surf == NULL){
12221 printf("ERROR: MRIwriteAnyFormat: need surf with paint format\n");
12222 return(1);
12223 }
12224 if(mriframe >= mri->nframes){
12225 printf("ERROR: MRIwriteAnyFormat: frame (%d) exceeds number of\n"
12226 " frames\n",mriframe >= mri->nframes);
12227 return(1);
12228 }
12229
12230 /* Copy current surf values into v (temp storage) */
12231 v = (float *)calloc(surf->nvertices,sizeof(float));
12232 for(n=0; n < surf->nvertices; n++) v[n] = surf->vertices[n].val;
12233
12234 /* Copy the mri values into the surf values */
12235 err = MRIScopyMRI(surf, mri, mriframe, "val");
12236 if(err){
12237 printf("ERROR: MRIwriteAnyFormat: could not copy MRI to MRIS\n");
12238 return(1);
12239 }
12240
12241 /* Write the surf values */
12242 err = MRISwriteValues(surf,fileid);
12243
12244 /* Copy v back into surf values */
12245 for(n=0; n < surf->nvertices; n++) surf->vertices[n].val = v[n];
12246 free(v);
12247
12248 /* Check for errors from write of values */
12249 if(err){
12250 printf("ERROR: MRIwriteAnyFormat: MRISwriteValues\n");
12251 return(1);
12252 }
12253
12254 return(0);
12255 }
12256
12257 /* Copy the desired frame if necessary */
12258 if(mriframe > -1){
12259 if(mriframe >= mri->nframes){
12260 printf("ERROR: MRIwriteAnyFormat: frame (%d) exceeds number of\n"
12261 " frames\n",mriframe >= mri->nframes);
12262 return(1);
12263 }
12264 mritmp = MRIallocSequence(mri->width, mri->height, mri->depth,
12265 mri->type, 1);
12266 for(c=0; c < mri->width; c++){
12267 for(r=0; r < mri->height; r++){
12268 for(s=0; s < mri->depth; s++){
12269 f = MRIgetVoxVal(mri, c, r, s, mriframe);
12270 MRIsetVoxVal(mritmp, c, r, s, 0, f);
12271 }
12272 }
12273 }
12274 }
12275 else mritmp = mri;
12276
12277 /*------------ Save using MRIwrite or MRIwriteType ---------*/
12278 if(fmt != NULL){
12279 /* Save as the given format */
12280 fmtid = string_to_type(fmt);
12281 if(fmtid == MRI_VOLUME_TYPE_UNKNOWN){
12282 printf("ERROR: format string %s unrecognized\n",fmt);
12283 return(1);
12284 }
12285 err = MRIwriteType(mritmp,fileid,fmtid);
12286 if(err){
12287 printf("ERROR: MRIwriteAnyFormat: could not write to %s\n",fileid);
12288 return(1);
12289 }
12290 }
12291 else{
12292 /* Try to infer the type and save (format is NULL) */
12293 err = MRIwrite(mritmp,fileid);
12294 if(err){
12295 printf("ERROR: MRIwriteAnyFormat: could not write to %s\n",fileid);
12296 return(1);
12297 }
12298 }
12299
12300 if(mri != mritmp) MRIfree(&mritmp);
12301
12302 return(0);
12303 }
12304
12305
12306
12307 /* EOF */
12308
12309
12310 /*-------------------------------------------------------------------*/
12311 /*-------------------------------------------------------------------*/
12312 /* ----------- Obsolete functions below. --------------*/
12313 /*-------------------------------------------------------------------*/
12314 /*-------------------------------------------------------------------*/
12315
12316
12317 #if 0
12318 /*-------------------------------------------------------------------
12319 bfloatWrite() - obsolete. Use bvolumeWrite.
12320 -------------------------------------------------------------------*/
12321 static int bfloatWrite(MRI *vol, char *stem)
12322 {
12323
12324 int i, j, t;
12325 char fname[STRLEN];
12326 float *buf;
12327 FILE *fp;
12328 int result;
12329 MRI *mri = NULL;
12330 int dealloc;
12331 int nslices,nframes;
12332
12333 if(vol->type != MRI_FLOAT){
12334 printf("INFO: bfloatWrite: changing type\n");
12335 nslices = vol->depth;
12336 nframes = vol->nframes;
12337 vol->depth = nslices*nframes;
12338 vol->nframes = 1;
12339 mri = MRIchangeType(vol,MRI_FLOAT,0,0,0);
12340 if(mri == NULL) {
12341 fprintf(stderr,"ERROR: bfloatWrite: MRIchangeType\n");
12342 return(1);
12343 }
12344 vol->depth = nslices;
12345 vol->nframes = nframes;
12346 mri->depth = nslices;
12347 mri->nframes = nframes;
12348 dealloc = 1;
12349 }
12350 else{
12351 mri = vol;
12352 dealloc = 0;
12353 }
12354
12355 buf = (float *)malloc(mri->width * sizeof(float));
12356
12357 for(i = 0;i < mri->depth;i++)
12358 {
12359 /* ----- write the header file ----- */
12360 sprintf(fname, "%s_%03d.hdr", stem, i);
12361 if((fp = fopen(fname, "w")) == NULL)
12362 {
12363 free(buf);
12364 errno = 0;
12365 ErrorReturn
12366 (ERROR_BADFILE,
12367 (ERROR_BADFILE,
12368 "bfloatWrite(): can't open file %s", fname));
12369 }
12370 #if (BYTE_ORDER == LITTLE_ENDIAN)
12371 fprintf(fp, "%d %d %d %d\n", mri->height, mri->width, mri->nframes, 1);
12372 #else
12373 fprintf(fp, "%d %d %d %d\n", mri->height, mri->width, mri->nframes, 0);
12374 #endif
12375 fclose(fp);
12376
12377 /* ----- write the data file ----- */
12378 sprintf(fname, "%s_%03d.bfloat", stem, i);
12379 if((fp = fopen(fname, "w")) == NULL)
12380 {
12381 if(dealloc) MRIfree(&mri);
12382 free(buf);
12383 errno = 0;
12384 ErrorReturn
12385 (ERROR_BADFILE,
12386 (ERROR_BADFILE,
12387 "bfloatWrite(): can't open file %s", fname));
12388 }
12389
12390 for(t = 0;t < mri->nframes;t++)
12391 {
12392 for(j = 0;j < mri->height;j++)
12393 {
12394 memcpy(buf, mri->slices[t*mri->depth + i][j],
12395 mri->width * sizeof(float));
12396 #if 0
12397 /* this byte swapping routine does not seem to work */
12398 /* now uses endian flag in .hdr (above) */
12399 for(pos = 0; pos < mri->width * sizeof(float);
12400 pos += sizeof(float))
12401 {
12402 c = (char *) (&(buf[pos]));
12403 memcpy(&(swap_buf[0]), c, 4);
12404 c[0] = swap_buf[3];
12405 c[1] = swap_buf[2];
12406 c[2] = swap_buf[1];
12407 c[3] = swap_buf[0];
12408 }
12409 #endif
12410 fwrite(buf, sizeof(float), mri->width, fp);
12411
12412 }
12413
12414 }
12415
12416 fclose(fp);
12417
12418 }
12419
12420 free(buf);
12421
12422 /* ----- write the bhdr file ----- */
12423 sprintf(fname, "%s.bhdr", stem);
12424 if((fp = fopen(fname, "w")) == NULL)
12425 {
12426 if(dealloc) MRIfree(&mri);
12427 errno = 0;
12428 ErrorReturn
12429 (ERROR_BADFILE,
12430 (ERROR_BADFILE,
12431 "bfloatWrite(): can't open file %s", fname));
12432 }
12433
12434 result = write_bhdr(mri, fp);
12435
12436 fclose(fp);
12437
12438 if(dealloc) MRIfree(&mri);
12439 return(result);
12440
12441 } /* end bfloatWrite() */
12442
12443 /*-------------------------------------------------------------------
12444 bshortWrite() - obsolete. Use bvolumeWrite.
12445 -------------------------------------------------------------------*/
12446 static int bshortWrite(MRI *vol, char *fname_passed)
12447 {
12448
12449 int i, j, t;
12450 char fname[STRLEN];
12451 short *buf;
12452 FILE *fp;
12453 int result;
12454 MRI *subject_info = NULL;
12455 char subject_volume_dir[STRLEN];
12456 char *subjects_dir;
12457 char *sn;
12458 char analyse_fname[STRLEN], register_fname[STRLEN];
12459 char output_dir[STRLEN];
12460 char *c;
12461 int od_length;
12462 char t1_path[STRLEN];
12463 MATRIX *cf, *bf, *ibf, *af, *iaf, *as, *bs, *cs, *ics, *r;
12464 MATRIX *r1, *r2, *r3, *r4;
12465 float det;
12466 int bad_flag;
12467 int l;
12468 char stem[STRLEN];
12469 char *c1, *c2, *c3;
12470 struct stat stat_buf;
12471 char subject_dir[STRLEN];
12472 int dealloc, nslices, nframes;
12473 MRI *mri;
12474 float min,max;
12475
12476 if(vol->type != MRI_SHORT){
12477 printf("INFO: bshortWrite: changing type\n");
12478 nslices = vol->depth;
12479 nframes = vol->nframes;
12480 vol->depth = nslices*nframes;
12481 vol->nframes = 1;
12482 MRIlimits(vol,&min,&max);
12483 printf("INFO: bshortWrite: range %g %g\n",min,max);
12484 mri = MRIchangeType(vol,MRI_SHORT,min,max,1);
12485 if(mri == NULL) {
12486 fprintf(stderr,"ERROR: bshortWrite: MRIchangeType\n");
12487 return(1);
12488 }
12489 vol->depth = nslices;
12490 vol->nframes = nframes;
12491 mri->depth = nslices;
12492 mri->nframes = nframes;
12493 dealloc = 1;
12494 }
12495 else{
12496 mri = vol;
12497 dealloc = 0;
12498 }
12499
12500 /* ----- get the stem from the passed file name ----- */
12501 /*
12502 four options:
12503 1. stem_xxx.bshort
12504 2. stem.bshort
12505 3. stem_xxx
12506 4. stem
12507 other possibles:
12508 stem_.bshort
12509 */
12510
12511 l = strlen(fname_passed);
12512
12513 c1 = fname_passed + l - 11;
12514 c2 = fname_passed + l - 7;
12515 c3 = fname_passed + l - 4;
12516
12517 strcpy(stem, fname_passed);
12518
12519 if(c1 > fname_passed)
12520 {
12521 if(*c1 == '_' && strcmp(c1+4, ".bshort") == 0)
12522 stem[(int)(c1-fname_passed)] = '\0';
12523 }
12524 if(c2 > fname_passed)
12525 {
12526 if(strcmp(c2, ".bshort") == 0)
12527 stem[(int)(c2-fname_passed)] = '\0';
12528 }
12529 if(c3 > fname_passed)
12530 {
12531 if(*c3 == '_')
12532 stem[(int)(c3-fname_passed)] = '\0';
12533 }
12534
12535 c = strrchr(stem, '/');
12536 if(c == NULL)
12537 output_dir[0] = '\0';
12538 else
12539 {
12540 od_length = (int)(c - stem);
12541 strncpy(output_dir, stem, od_length);
12542 /* -- leaving the trailing '/' on a directory is not my
12543 usual convention, but here it's a load easier
12544 if there's no directory in stem... -ch -- */
12545 output_dir[od_length] = '/';
12546 output_dir[od_length+1] = '\0';
12547 }
12548
12549 sprintf(analyse_fname, "%s%s", output_dir, "analyse.dat");
12550 sprintf(register_fname, "%s%s", output_dir, "register.dat");
12551
12552 buf = (short *)malloc(mri->width * mri->height * sizeof(short));
12553
12554 for(i = 0;i < mri->depth;i++)
12555 {
12556
12557 /* ----- write the header file ----- */
12558 sprintf(fname, "%s_%03d.hdr", stem, i);
12559 if((fp = fopen(fname, "w")) == NULL)
12560 {
12561 if(dealloc) MRIfree(&mri);
12562 free(buf);
12563 errno = 0;
12564 ErrorReturn
12565 (ERROR_BADFILE,
12566 (ERROR_BADFILE,
12567 "bshortWrite(): can't open file %s", fname));
12568 }
12569 fprintf(fp, "%d %d %d %d\n", mri->height, mri->width, mri->nframes, 0);
12570 fclose(fp);
12571
12572 /* ----- write the data file ----- */
12573 sprintf(fname, "%s_%03d.bshort", stem, i);
12574 if((fp = fopen(fname, "w")) == NULL)
12575 {
12576 if(dealloc) MRIfree(&mri);
12577 free(buf);
12578 errno = 0;
12579 ErrorReturn
12580 (ERROR_BADFILE,
12581 (ERROR_BADFILE, "bshortWrite(): can't open file %s", fname));
12582 }
12583
12584 for(t = 0;t < mri->nframes;t++)
12585 {
12586 for(j = 0;j < mri->height;j++)
12587 {
12588
12589 #if (BYTE_ORDER == LITTLE_ENDIAN)
12590 swab(mri->slices[t*mri->depth + i][j], buf,
12591 mri->width * sizeof(short));
12592 #else
12593 memcpy(buf, mri->slices[t*mri->depth + i][j],
12594 mri->width * sizeof(short));
12595 #endif
12596
12597 fwrite(buf, sizeof(short), mri->width, fp);
12598
12599 }
12600
12601 }
12602
12603 fclose(fp);
12604
12605 }
12606
12607 free(buf);
12608
12609 sn = subject_name;
12610 if(mri->subject_name[0] != '\0')
12611 sn = mri->subject_name;
12612
12613 if(sn != NULL)
12614 {
12615 if((subjects_dir = getenv("SUBJECTS_DIR")) == NULL)
12616 {
12617 errno = 0;
12618 ErrorPrintf
12619 (ERROR_BADPARM,
12620 "bshortWrite(): environment variable SUBJECTS_DIR unset");
12621 if(dealloc) MRIfree(&mri);
12622 }
12623 else
12624 {
12625
12626 sprintf(subject_dir, "%s/%s", subjects_dir, sn);
12627 if(stat(subject_dir, &stat_buf) < 0)
12628 {
12629 fprintf
12630 (stderr,
12631 "can't stat %s; writing to bhdr instead\n", subject_dir);
12632 }
12633 else
12634 {
12635 if(!S_ISDIR(stat_buf.st_mode))
12636 {
12637 fprintf
12638 (stderr,
12639 "%s is not a directory; writing to bhdr instead\n",
12640 subject_dir);
12641 }
12642 else
12643 {
12644 sprintf(subject_volume_dir, "%s/mri/T1", subject_dir);
12645 subject_info = MRIreadInfo(subject_volume_dir);
12646 if(subject_info == NULL)
12647 {
12648 sprintf(subject_volume_dir, "%s/mri/orig", subject_dir);
12649 subject_info = MRIreadInfo(subject_volume_dir);
12650 if(subject_info == NULL)
12651 fprintf(stderr,
12652 "can't read the subject's orig or T1 volumes; "
12653 "writing to bhdr instead\n");
12654 }
12655 }
12656 }
12657
12658 }
12659
12660 }
12661
12662 if(subject_info != NULL)
12663 {
12664 if(subject_info->ras_good_flag == 0)
12665 {
12666 subject_info->x_r = -1.0;
12667 subject_info->x_a = 0.0;
12668 subject_info->x_s = 0.0;
12669 subject_info->y_r = 0.0;
12670 subject_info->y_a = 0.0;
12671 subject_info->y_s = -1.0;
12672 subject_info->z_r = 0.0;
12673 subject_info->z_a = 1.0;
12674 subject_info->z_s = 0.0;
12675 subject_info->c_r = 0.0;
12676 subject_info->c_a = 0.0;
12677 subject_info->c_s = 0.0;
12678 }
12679 }
12680
12681 cf = bf = ibf = af = iaf = as = bs = cs = ics = r = NULL;
12682 r1 = r2 = r3 = r4 = NULL;
12683
12684 /* ----- write the register.dat and analyse.dat or bhdr files ----- */
12685 if(subject_info != NULL)
12686 {
12687
12688 bad_flag = FALSE;
12689
12690 if((as = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12691 {
12692 errno = 0;
12693 ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12694 bad_flag = TRUE;
12695 }
12696 stuff_four_by_four
12697 (as,
12698 subject_info->x_r,
12699 subject_info->y_r,
12700 subject_info->z_r,
12701 subject_info->c_r,
12702 subject_info->y_r,
12703 subject_info->y_r,
12704 subject_info->y_r,
12705 subject_info->c_r,
12706 subject_info->z_r,
12707 subject_info->z_r,
12708 subject_info->z_r,
12709 subject_info->c_r,
12710 0.0, 0.0, 0.0, 1.0);
12711
12712 if((af = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12713 {
12714 errno = 0;
12715 ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12716 bad_flag = TRUE;
12717 }
12718 stuff_four_by_four(af, mri->x_r, mri->y_r, mri->z_r, mri->c_r,
12719 mri->y_r, mri->y_r, mri->y_r, mri->c_r,
12720 mri->z_r, mri->z_r, mri->z_r, mri->c_r,
12721 0.0, 0.0, 0.0, 1.0);
12722
12723 if((bs = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12724 {
12725 errno = 0;
12726 ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12727 bad_flag = TRUE;
12728 }
12729 stuff_four_by_four(bs, 1, 0, 0, (subject_info->width - 1) / 2.0,
12730 0, 1, 0, (subject_info->height - 1) / 2.0,
12731 0, 0, 1, (subject_info->depth - 1) / 2.0,
12732 0, 0, 0, 1.0);
12733
12734 if((bf = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12735 {
12736 errno = 0;
12737 ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12738 bad_flag = TRUE;
12739 }
12740 stuff_four_by_four(bf, 1, 0, 0, (mri->width - 1) / 2.0,
12741 0, 1, 0, (mri->height - 1) / 2.0,
12742 0, 0, 1, (mri->depth - 1) / 2.0,
12743 0, 0, 0, 1.0);
12744
12745 if((cs = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12746 {
12747 errno = 0;
12748 ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12749 bad_flag = TRUE;
12750 }
12751 stuff_four_by_four
12752 (cs,
12753 -subject_info->xsize, 0, 0,
12754 (subject_info->width * mri->xsize) / 2.0,
12755 0, 0, subject_info->zsize, -(subject_info->depth * mri->zsize) / 2.0,
12756 0, -subject_info->ysize, 0,
12757 (subject_info->height * mri->ysize) / 2.0,
12758 0, 0, 0, 1);
12759
12760 if((cf = MatrixAlloc(4, 4, MATRIX_REAL)) == NULL)
12761 {
12762 errno = 0;
12763 ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error creating matrix");
12764 bad_flag = TRUE;
12765 }
12766 stuff_four_by_four
12767 (cf,
12768 -mri->xsize, 0, 0, (mri->width * mri->xsize) / 2.0,
12769 0, 0, mri->zsize, -(mri->depth * mri->zsize) / 2.0,
12770 0, -mri->ysize, 0, (mri->height * mri->ysize) / 2.0,
12771 0, 0, 0, 1);
12772
12773 if(bad_flag)
12774 {
12775 errno = 0;
12776 ErrorPrintf
12777 (ERROR_BADPARM,
12778 "bshortWrite(): error creating one "
12779 "or more matrices; aborting register.dat "
12780 "write and writing bhdr instead");
12781 MRIfree(&subject_info);
12782 }
12783
12784 }
12785
12786 if(subject_info != NULL)
12787 {
12788
12789 bad_flag = FALSE;
12790
12791 if((det = MatrixDeterminant(as)) == 0.0)
12792 {
12793 errno = 0;
12794 ErrorPrintf
12795 (ERROR_BADPARM,
12796 "bshortWrite(): bad determinant in matrix "
12797 "(check structural volume)");
12798 bad_flag = TRUE;
12799 }
12800 if((det = MatrixDeterminant(bs)) == 0.0)
12801 {
12802 errno = 0;
12803 ErrorPrintf
12804 (ERROR_BADPARM,
12805 "bshortWrite(): bad determinant in matrix "
12806 "(check structural volume)");
12807 bad_flag = TRUE;
12808 }
12809 if((det = MatrixDeterminant(cs)) == 0.0)
12810 {
12811 errno = 0;
12812 ErrorPrintf
12813 (ERROR_BADPARM,
12814 "bshortWrite(): bad determinant in matrix "
12815 "(check structural volume)");
12816 bad_flag = TRUE;
12817 }
12818
12819 if((det = MatrixDeterminant(af)) == 0.0)
12820 {
12821 errno = 0;
12822 ErrorPrintf
12823 (ERROR_BADPARM,
12824 "bshortWrite(): bad determinant in matrix "
12825 "(check functional volume)");
12826 bad_flag = TRUE;
12827 }
12828 if((det = MatrixDeterminant(bf)) == 0.0)
12829 {
12830 errno = 0;
12831 ErrorPrintf
12832 (ERROR_BADPARM,
12833 "bshortWrite(): bad determinant in matrix "
12834 "(check functional volume)");
12835 bad_flag = TRUE;
12836 }
12837 if((det = MatrixDeterminant(cf)) == 0.0)
12838 {
12839 errno = 0;
12840 ErrorPrintf
12841 (ERROR_BADPARM,
12842 "bshortWrite(): bad determinant in matrix "
12843 "(check functional volume)");
12844 bad_flag = TRUE;
12845 }
12846
12847 if(bad_flag)
12848 {
12849 errno = 0;
12850 ErrorPrintf
12851 (ERROR_BADPARM,
12852 "bshortWrite(): one or more zero "
12853 "determinants; aborting register.dat write and "
12854 "writing bhdr instead");
12855 MRIfree(&subject_info);
12856 }
12857
12858 }
12859
12860 if(subject_info != NULL)
12861 {
12862
12863 bad_flag = FALSE;
12864
12865 if((iaf = MatrixInverse(af, NULL)) == NULL)
12866 {
12867 errno = 0;
12868 ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error inverting matrix");
12869 bad_flag = TRUE;
12870 }
12871 if((ibf = MatrixInverse(bf, NULL)) == NULL)
12872 {
12873 errno = 0;
12874 ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error inverting matrix");
12875 bad_flag = TRUE;
12876 }
12877 if((ics = MatrixInverse(cs, NULL)) == NULL)
12878 {
12879 errno = 0;
12880 ErrorPrintf(ERROR_BADPARM, "bshortWrite(): error inverting matrix");
12881 bad_flag = TRUE;
12882 }
12883
12884 if(bad_flag)
12885 {
12886 errno = 0;
12887 ErrorPrintf
12888 (ERROR_BADPARM,
12889 "bshortWrite(): one or more zero "
12890 "determinants; aborting register.dat write and "
12891 "writing bhdr instead");
12892 MRIfree(&subject_info);
12893 }
12894 }
12895
12896 bad_flag = FALSE;
12897
12898 if(subject_info != NULL)
12899 {
12900
12901 if((r1 = MatrixMultiply(bs, ics, NULL)) == NULL)
12902 {
12903 bad_flag = TRUE;
12904 MRIfree(&subject_info);
12905 }
12906
12907 }
12908
12909 if(subject_info != NULL)
12910 {
12911
12912 if((r2 = MatrixMultiply(as, r1, NULL)) == NULL)
12913 {
12914 bad_flag = TRUE;
12915 MRIfree(&subject_info);
12916 }
12917
12918 }
12919
12920 if(subject_info != NULL)
12921 {
12922
12923 if((r3 = MatrixMultiply(iaf, r2, NULL)) == NULL)
12924 {
12925 bad_flag = TRUE;
12926 MRIfree(&subject_info);
12927 }
12928
12929 }
12930
12931 if(subject_info != NULL)
12932 {
12933
12934 if((r4 = MatrixMultiply(ibf, r3, NULL)) == NULL)
12935 {
12936 bad_flag = TRUE;
12937 MRIfree(&subject_info);
12938 }
12939
12940 }
12941
12942 if(subject_info != NULL)
12943 {
12944
12945 if((r = MatrixMultiply(cf, r4, NULL)) == NULL)
12946 {
12947 bad_flag = TRUE;
12948 MRIfree(&subject_info);
12949 }
12950
12951 }
12952
12953 if(bad_flag)
12954 {
12955 errno = 0;
12956 ErrorPrintf
12957 (ERROR_BADPARM,
12958 "bshortWrite(): error during matrix "
12959 "multiplications; aborting register.dat write and "
12960 "writing bhdr instead");
12961 }
12962
12963 if( as != NULL) MatrixFree( &as);
12964 if( bs != NULL) MatrixFree( &bs);
12965 if( cs != NULL) MatrixFree( &cs);
12966 if( af != NULL) MatrixFree( &af);
12967 if( bf != NULL) MatrixFree( &bf);
12968 if( cf != NULL) MatrixFree( &cf);
12969 if(iaf != NULL) MatrixFree(&iaf);
12970 if(ibf != NULL) MatrixFree(&ibf);
12971 if(ics != NULL) MatrixFree(&ics);
12972 if( r1 != NULL) MatrixFree( &r1);
12973 if( r2 != NULL) MatrixFree( &r2);
12974 if( r3 != NULL) MatrixFree( &r3);
12975 if( r4 != NULL) MatrixFree( &r4);
12976
12977 if(subject_info != NULL)
12978 {
12979
12980 if(mri->path_to_t1[0] == '\0')
12981 sprintf(t1_path, ".");
12982 else
12983 strcpy(t1_path, mri->path_to_t1);
12984
12985 if(FileExists(analyse_fname))
12986 fprintf(stderr, "warning: overwriting file %s\n", analyse_fname);
12987
12988 if((fp = fopen(analyse_fname, "w")) == NULL)
12989 {
12990 MRIfree(&subject_info);
12991 errno = 0;
12992 ErrorReturn
12993 (ERROR_BADFILE,
12994 (ERROR_BADFILE,
12995 "bshortWrite(): couldn't open file %s for writing",
12996 analyse_fname));
12997 }
12998
12999 fprintf(fp, "%s\n", t1_path);
13000 fprintf(fp, "%s_%%03d.bshort\n", stem);
13001 fprintf(fp, "%d %d\n", mri->depth, mri->nframes);
13002 fprintf(fp, "%d %d\n", mri->width, mri->height);
13003
13004 fclose(fp);
13005
13006 if(FileExists(analyse_fname))
13007 fprintf(stderr, "warning: overwriting file %s\n", register_fname);
13008
13009 if((fp = fopen(register_fname, "w")) == NULL)
13010 {
13011 MRIfree(&subject_info);
13012 errno = 0;
13013 ErrorReturn
13014 (ERROR_BADFILE,
13015 (ERROR_BADFILE,
13016 "bshortWrite(): couldn't open file %s for writing",
13017 register_fname));
13018 }
13019
13020 fprintf(fp, "%s\n", sn);
13021 fprintf(fp, "%g\n", mri->xsize);
13022 fprintf(fp, "%g\n", mri->zsize);
13023 fprintf(fp, "%g\n", 1.0);
13024 fprintf(fp, "%g %g %g %g\n",
13025 *MATRIX_RELT(r, 1, 1),
13026 *MATRIX_RELT(r, 1, 2),
13027 *MATRIX_RELT(r, 1, 3),
13028 *MATRIX_RELT(r, 1, 4));
13029 fprintf(fp, "%g %g %g %g\n",
13030 *MATRIX_RELT(r, 2, 1),
13031 *MATRIX_RELT(r, 2, 2),
13032 *MATRIX_RELT(r, 2, 3),
13033 *MATRIX_RELT(r, 2, 4));
13034 fprintf(fp, "%g %g %g %g\n",
13035 *MATRIX_RELT(r, 3, 1),
13036 *MATRIX_RELT(r, 3, 2),
13037 *MATRIX_RELT(r, 3, 3),
13038 *MATRIX_RELT(r, 3, 4));
13039 fprintf(fp, "%g %g %g %g\n",
13040 *MATRIX_RELT(r, 4, 1),
13041 *MATRIX_RELT(r, 4, 2),
13042 *MATRIX_RELT(r, 4, 3),
13043 *MATRIX_RELT(r, 4, 4));
13044
13045 fclose(fp);
13046
13047 MatrixFree(&r);
13048
13049 }
13050
13051 if(subject_info == NULL)
13052 {
13053 sprintf(fname, "%s.bhdr", stem);
13054 if((fp = fopen(fname, "w")) == NULL)
13055 {
13056 if(dealloc) MRIfree(&mri);
13057 errno = 0;
13058 ErrorReturn
13059 (ERROR_BADFILE,
13060 (ERROR_BADFILE, "bshortWrite(): can't open file %s", fname));
13061 }
13062
13063 result = write_bhdr(mri, fp);
13064
13065 fclose(fp);
13066
13067 if(result != NO_ERROR)
13068 return(result);
13069
13070 }
13071 else
13072 MRIfree(&subject_info);
13073
13074 if(dealloc) MRIfree(&mri);
13075
13076 return(NO_ERROR);
13077
13078 } /* end bshortWrite() */
13079
13080 /*-------------------------------------------------------------------
13081 bshortRead() - obsolete. Use bvolumeRead.
13082 -------------------------------------------------------------------*/
13083 static MRI *bshortRead(char *fname_passed, int read_volume)
13084 {
13085
13086 MRI *mri;
13087 FILE *fp;
13088 char fname[STRLEN];
13089 char directory[STRLEN];
13090 char stem[STRLEN];
13091 int swap_bytes_flag;
13092 int slice, frame, row, k;
13093 int nread;
13094
13095 mri = get_b_info(fname_passed, read_volume, directory, stem, MRI_SHORT);
13096 if(mri == NULL)
13097 return(NULL);
13098
13099 if(read_volume)
13100 {
13101
13102 sprintf(fname, "%s/%s_%03d.hdr", directory, stem, 0);
13103 if((fp = fopen(fname, "r")) == NULL){
13104 fprintf
13105 (stderr, "can't open file %s; assuming big-endian bvolume\n", fname);
13106 swap_bytes_flag = 0;
13107 }
13108 else
13109 {
13110 fscanf(fp, "%*d %*d %*d %d", &swap_bytes_flag);
13111 #if (BYTE_ORDER == LITTLE_ENDIAN)
13112 swap_bytes_flag = !swap_bytes_flag;
13113 #endif
13114 fclose(fp);
13115 }
13116
13117 for(slice = 0;slice < mri->depth; slice++){
13118
13119 sprintf(fname, "%s/%s_%03d.bshort", directory, stem, slice);
13120 if((fp = fopen(fname, "r")) == NULL){
13121 MRIfree(&mri);
13122 errno = 0;
13123 ErrorReturn(NULL, (ERROR_BADFILE,
13124 "bshortRead(): error opening file %s", fname));
13125 }
13126
13127 for(frame = 0; frame < mri->nframes; frame ++){
13128 k = slice + mri->depth*frame;
13129 for(row = 0;row < mri->height; row++){
13130
13131 /* read in a column */
13132 nread = fread(mri->slices[k][row], sizeof(short), mri->width, fp);
13133 if( nread != mri->width){
13134 fclose(fp);
13135 MRIfree(&mri);
13136 errno = 0;
13137 ErrorReturn
13138 (NULL,
13139 (ERROR_BADFILE,
13140 "bshortRead(): error reading from file %s", fname));
13141 }
13142
13143 if(swap_bytes_flag)
13144 swab(mri->slices[k][row], mri->slices[k][row],
13145 mri->width * sizeof(short));
13146
13147 } /* row loop */
13148 } /* frame loop */
13149 fclose(fp);
13150 }
13151 }
13152
13153 return(mri);
13154
13155 } /* end bshortRead() */
13156
13157
13158 /*-------------------------------------------------------------------
13159 bfloatRead() - obsolete. Use bvolumeRead.
13160 -------------------------------------------------------------------*/
13161 static MRI *bfloatRead(char *fname_passed, int read_volume)
13162 {
13163
13164 MRI *mri;
13165 FILE *fp;
13166 char fname[STRLEN];
13167 char directory[STRLEN];
13168 char stem[STRLEN];
13169 int swap_bytes_flag;
13170 int i, j, k;
13171
13172 mri = get_b_info(fname_passed, read_volume, directory, stem, MRI_FLOAT);
13173 if(mri == NULL)
13174 return(NULL);
13175
13176 if(read_volume)
13177 {
13178
13179 sprintf(fname, "%s/%s_%03d.hdr", directory, stem, 0);
13180 if((fp = fopen(fname, "r")) == NULL)
13181 {
13182 fprintf
13183 (stderr,
13184 "INFO: Can't open file %s; assuming big-endian bshorts\n",
13185 fname);
13186 swap_bytes_flag = 0;
13187 }
13188 else
13189 {
13190 fscanf(fp, "%*d %*d %*d %d", &swap_bytes_flag);
13191 #if (BYTE_ORDER == LITTLE_ENDIAN)
13192 swap_bytes_flag = !swap_bytes_flag;
13193 #endif
13194 fclose(fp);
13195 }
13196
13197 printf("swap = %d\n",swap_bytes_flag);
13198
13199 for(i = 0;i < mri->depth;i++)
13200 {
13201
13202 sprintf(fname, "%s/%s_%03d.bfloat", directory, stem, i);
13203
13204 if((fp = fopen(fname, "r")) == NULL)
13205 {
13206 MRIfree(&mri);
13207 errno = 0;
13208 ErrorReturn
13209 (NULL,
13210 (ERROR_BADFILE,
13211 "bfloatRead(): error opening file %s", fname));
13212 }
13213
13214 for(j = 0;j < mri->height;j++)
13215 {
13216 if(fread(mri->slices[i][j], sizeof(float), mri->width, fp) !=
13217 mri->width)
13218 {
13219 fclose(fp);
13220 MRIfree(&mri);
13221 errno = 0;
13222 ErrorReturn
13223 (NULL,
13224 (ERROR_BADFILE,
13225 "bfloatRead(): error reading from file %s", fname));
13226 }
13227 if(swap_bytes_flag)
13228 {
13229 for(k = 0;k < mri->depth;k++)
13230 mri->slices[i][j][k] = swapFloat(mri->slices[i][j][k]);
13231 }
13232 }
13233
13234 fclose(fp);
13235
13236 }
13237
13238 }
13239
13240 return(mri);
13241
13242 } /* end bfloatRead() */
13243
13244
13245 /*-------------------------------------------------------------------------*/
13246 static MRI *analyzeReadOld(char *fname, int read_volume)
13247 {
13248
13249 MRI *mri = NULL;
13250 FILE *fp;
13251 char hdr_fname[STRLEN];
13252 char mat_fname[STRLEN];
13253 char *c;
13254 dsr hdr;
13255 int dtype;
13256 int flip_flag = 0;
13257 int i, j, k;
13258 float dx, dy, dz;
13259 int nread;
13260 unsigned char *buf;
13261 int bytes_per_voxel;
13262 int bufsize;
13263 MATRIX *m;
13264 MATRIX *center_index_mat;
13265 MATRIX *center_ras_mat;
13266 float xfov, yfov, zfov;
13267
13268 c = strrchr(fname, '.');
13269 if(c == NULL)
13270 {
13271 errno = 0;
13272 ErrorReturn
13273 (NULL, (ERROR_BADPARM, "analyzeRead(): bad file name %s", fname));
13274 }
13275 if(strcmp(c, ".img") != 0)
13276 {
13277 errno = 0;
13278 ErrorReturn
13279 (NULL, (ERROR_BADPARM, "analyzeRead(): bad file name %s", fname));
13280 }
13281
13282 strcpy(hdr_fname, fname);
13283 sprintf(hdr_fname + (c - fname), ".hdr");
13284
13285 strcpy(mat_fname, fname);
13286 sprintf(mat_fname + (c - fname), ".mat");
13287
13288 /* Open the header file */
13289 if((fp = fopen(hdr_fname, "r")) == NULL)
13290 {
13291 errno = 0;
13292 ErrorReturn(NULL, (ERROR_BADFILE, "read_analyze_header(): "
13293 "error opening file %s", fname));
13294 }
13295
13296 /* Read the header file */
13297 fread(&hdr, sizeof(hdr), 1, fp);
13298 fclose(fp);
13299
13300 if(hdr.hk.sizeof_hdr != sizeof(hdr))
13301 {
13302 flip_flag = 1;
13303 swap_analyze_header(&hdr);
13304 }
13305
13306 if(hdr.dime.datatype == DT_UNSIGNED_CHAR)
13307 {
13308 dtype = MRI_UCHAR;
13309 bytes_per_voxel = 1;
13310 }
13311 else if(hdr.dime.datatype == DT_SIGNED_SHORT)
13312 {
13313 dtype = MRI_SHORT;
13314 bytes_per_voxel = 2;
13315 }
13316 else if(hdr.dime.datatype == DT_SIGNED_INT)
13317 {
13318 dtype = MRI_INT;
13319 bytes_per_voxel = 4;
13320 }
13321 else if(hdr.dime.datatype == DT_FLOAT)
13322 {
13323 dtype = MRI_FLOAT;
13324 bytes_per_voxel = 4;
13325 }
13326 else if(hdr.dime.datatype == DT_DOUBLE)
13327 {
13328 dtype = MRI_FLOAT;
13329 bytes_per_voxel = 8;
13330 }
13331 else
13332 {
13333 errno = 0;
13334 ErrorReturn(NULL, (ERROR_UNSUPPORTED, "analyzeRead: "
13335 "unsupported data type %d", hdr.dime.datatype));
13336 }
13337
13338 /* ----- allocate the mri structure ----- */
13339 if(read_volume)
13340 mri = MRIalloc(hdr.dime.dim[1], hdr.dime.dim[2], hdr.dime.dim[3], dtype);
13341 else
13342 mri = MRIalloc(hdr.dime.dim[1], hdr.dime.dim[2], hdr.dime.dim[3], dtype);
13343
13344 mri->xsize = hdr.dime.pixdim[1];
13345 mri->ysize = hdr.dime.pixdim[2];
13346 mri->zsize = hdr.dime.pixdim[3];
13347
13348 mri->thick = mri->zsize;
13349 mri->ps = mri->xsize;
13350 mri->xend = mri->width * mri->xsize / 2.0; mri->xstart = -mri->xend;
13351 mri->yend = mri->height * mri->ysize / 2.0; mri->ystart = -mri->yend;
13352 mri->zend = mri->depth * mri->zsize / 2.0; mri->zstart = -mri->zend;
13353 xfov = mri->xend - mri->xstart;
13354 yfov = mri->yend - mri->ystart;
13355 zfov = mri->zend - mri->zstart;
13356
13357 mri->fov =
13358 (xfov > yfov ? (xfov > zfov ? xfov : zfov) : (yfov > zfov ? yfov : zfov));
13359
13360 /* --- default (no .mat file) --- */
13361 mri->x_r = 1.0; mri->x_a = 0.0; mri->x_s = 0.0;
13362 mri->y_r = 0.0; mri->y_a = 1.0; mri->y_s = 0.0;
13363 mri->z_r = 0.0; mri->z_a = 0.0; mri->z_s = 1.0;
13364
13365 /* --- originator gives the voxel index of (r, a, s) = (0, 0, 0) --- */
13366 dx = (mri->width - 1.0) / 2. - (float)(((short *)hdr.hist.originator)[0]);
13367 dy = (mri->height - 1.0) / 2. - (float)(((short *)hdr.hist.originator)[1]);
13368 dz = (mri->depth - 1.0) / 2. - (float)(((short *)hdr.hist.originator)[2]);
13369
13370 mri->c_r = (dx * mri->x_r) + (dy * mri->y_r) + (dz * mri->z_r);
13371 mri->c_a = (dx * mri->x_a) + (dy * mri->y_a) + (dz * mri->z_a);
13372 mri->c_s = (dx * mri->x_s) + (dy * mri->y_s) + (dz * mri->z_s);
13373
13374 mri->ras_good_flag = 1;
13375
13376 strcpy(mri->fname, fname);
13377
13378 if(read_volume)
13379 {
13380
13381 if((fp = fopen(fname, "r")) == NULL)
13382 {
13383 MRIfree(&mri);
13384 errno = 0;
13385 ErrorReturn
13386 (NULL,
13387 (ERROR_BADFILE, "analyzeRead: error opening file %s", fname));
13388 }
13389
13390 fseek(fp, (int)(hdr.dime.vox_offset), SEEK_SET);
13391
13392 bufsize = mri->width * bytes_per_voxel;
13393 buf = (unsigned char *)malloc(bufsize);
13394
13395 for(k = 0;k < mri->depth;k++)
13396 {
13397 for(j = 0;j < mri->height;j++)
13398 {
13399
13400 nread = fread(buf, bytes_per_voxel, mri->width, fp);
13401 if(nread != mri->width)
13402 {
13403 free(buf);
13404 fclose(fp);
13405 errno = 0;
13406 ErrorReturn
13407 (NULL,
13408 (ERROR_BADFILE,
13409 "analyzeRead: error reading from file %s\n", fname));
13410 }
13411
13412 if(flip_flag)
13413 nflip(buf, bytes_per_voxel, mri->width);
13414
13415
13416 for(i = 0;i < mri->width;i++)
13417 {
13418 if(hdr.dime.datatype == DT_UNSIGNED_CHAR)
13419 MRIvox(mri, i, j, k) = buf[i];
13420 if(hdr.dime.datatype == DT_SIGNED_SHORT)
13421 MRISvox(mri, i, j, k) = ((short *)buf)[i];
13422 if(hdr.dime.datatype == DT_SIGNED_INT)
13423 MRIIvox(mri, i, j, k) = ((int *)buf)[i];
13424 if(hdr.dime.datatype == DT_FLOAT)
13425 MRIFvox(mri, i, j, k) = ((float *)buf)[i];
13426 if(hdr.dime.datatype == DT_DOUBLE)
13427 MRIFvox(mri, i, j, k) = (float)(((double *)buf)[i]);
13428 }
13429
13430 }
13431 }
13432
13433 free(buf);
13434 fclose(fp);
13435
13436 }
13437
13438 /* ----- read mat file ----- */
13439 if(FileExists(mat_fname))
13440 {
13441
13442 m = MatlabRead(mat_fname);
13443
13444 if(m == NULL)
13445 {
13446 MRIfree(&mri);
13447 return(NULL);
13448 }
13449
13450 if(m->rows != 4 || m->cols != 4)
13451 {
13452 MRIfree(&mri);
13453 errno = 0;
13454 ErrorReturn
13455 (NULL,
13456 (ERROR_BADFILE,
13457 "analyzeRead(): not a 4 by 4 matrix in file %s", mat_fname));
13458 }
13459
13460 /* swap y and z here ?*/
13461 mri->x_r = *MATRIX_RELT(m, 1, 1);
13462 mri->y_r = *MATRIX_RELT(m, 1, 2);
13463 mri->z_r = *MATRIX_RELT(m, 1, 3);
13464 mri->x_a = *MATRIX_RELT(m, 2, 1);
13465 mri->y_a = *MATRIX_RELT(m, 2, 2);
13466 mri->z_a = *MATRIX_RELT(m, 2, 3);
13467 mri->x_s = *MATRIX_RELT(m, 3, 1);
13468 mri->y_s = *MATRIX_RELT(m, 3, 2);
13469 mri->z_s = *MATRIX_RELT(m, 3, 3);
13470
13471 mri->xsize =
13472 sqrt(mri->x_r * mri->x_r + mri->x_a * mri->x_a + mri->x_s * mri->x_s);
13473 mri->ysize =
13474 sqrt(mri->y_r * mri->y_r + mri->y_a * mri->y_a + mri->y_s * mri->y_s);
13475 mri->zsize =
13476 sqrt(mri->z_r * mri->z_r + mri->z_a * mri->z_a + mri->z_s * mri->z_s);
13477
13478 mri->x_r = mri->x_r / mri->xsize;
13479 mri->x_a = mri->x_a / mri->xsize;
13480 mri->x_s = mri->x_s / mri->xsize;
13481 mri->y_r = mri->y_r / mri->ysize;
13482 mri->y_a = mri->y_a / mri->ysize;
13483 mri->y_s = mri->y_s / mri->ysize;
13484 mri->z_r = mri->z_r / mri->zsize;
13485 mri->z_a = mri->z_a / mri->zsize;
13486 mri->z_s = mri->z_s / mri->zsize;
13487
13488 center_index_mat = MatrixAlloc(4, 1, MATRIX_REAL);
13489
13490 /* Is this right?? */
13491 /* --- matlab matrices start at 1, so the middle index is
13492 [(width, height, depth)+(1, 1, 1)]/2, (not -) --- */
13493 *MATRIX_RELT(center_index_mat, 1, 1) = (mri->width + 1.0) / 2.0;
13494 *MATRIX_RELT(center_index_mat, 2, 1) = (mri->height + 1.0) / 2.0;
13495 *MATRIX_RELT(center_index_mat, 3, 1) = (mri->depth + 1.0) / 2.0;
13496 *MATRIX_RELT(center_index_mat, 4, 1) = 1.0;
13497
13498 center_ras_mat = MatrixMultiply(m, center_index_mat, NULL);
13499 if(center_ras_mat == NULL)
13500 {
13501
13502 errno = 0;
13503 ErrorPrintf(ERROR_BADPARM, "multiplying: m * cim:\n");
13504 ErrorPrintf(ERROR_BADPARM, "m = \n");
13505 MatrixPrint(stderr, m);
13506 ErrorPrintf(ERROR_BADPARM, "cim = \n");
13507 MatrixPrint(stderr, center_index_mat);
13508
13509 MatrixFree(&m);
13510 MatrixFree(¢er_index_mat);
13511 MatrixFree(¢er_ras_mat);
13512 MRIfree(&mri);
13513 errno = 0;
13514 ErrorReturn
13515 (NULL,
13516 (ERROR_BADPARM, "analyzeRead(): error in matrix multiplication"));
13517 }
13518
13519 mri->c_r = *MATRIX_RELT(center_ras_mat, 1, 1);
13520 mri->c_a = *MATRIX_RELT(center_ras_mat, 2, 1);
13521 mri->c_s = *MATRIX_RELT(center_ras_mat, 3, 1);
13522
13523 MatrixFree(&m);
13524 MatrixFree(¢er_index_mat);
13525 MatrixFree(¢er_ras_mat);
13526
13527 }
13528
13529 return(mri);
13530
13531 } /* end analyzeRead() */
13532
13533 static void nflip(unsigned char *buf, int b, int n)
13534 {
13535 int i, j;
13536 unsigned char *copy;
13537
13538 copy = (unsigned char *)malloc(b);
13539 for(i = 0;i < n;i++)
13540 {
13541 memcpy(copy, &buf[i*b], b);
13542 for(j = 0;j < b;j++)
13543 buf[i*b+j] = copy[b-j-1];
13544 }
13545 free(copy);
13546
13547 } /* end nflip() */
13548
13549 #endif
13550 #include "gca.h"
13551 static MRI *
13552 readGCA(char *fname)
13553 {
13554 GCA *gca ;
13555 MRI *mri ;
13556
13557 gca = GCAread(fname) ;
13558 if (!gca)
13559 return(NULL) ;
13560 mri = GCAbuildMostLikelyVolume(gca, NULL) ;
13561 GCAfree(&gca) ;
13562 return(mri) ;
13563 }
13564
13565 MRI *
13566 MRIremoveNaNs(MRI *mri_src, MRI *mri_dst)
13567 {
13568 int x, y, z, nans=0 ;
13569 float val ;
13570
13571 if (mri_dst != mri_src)
13572 mri_dst = MRIcopy(mri_src, mri_dst) ;
13573
13574 for (x = 0 ; x < mri_dst->width ; x++)
13575 {
13576 for (y = 0 ; y < mri_dst->height ; y++)
13577 {
13578 for (z = 0 ; z < mri_dst->depth ; z++)
13579 {
13580 val = MRIgetVoxVal(mri_dst, x, y, z, 0) ;
13581 if (!finite(val))
13582 {
13583 nans++ ;
13584 MRIsetVoxVal(mri_dst, x, y, z, 0, 0) ;
13585 }
13586 }
13587 }
13588 }
13589 if (nans > 0)
13590 ErrorPrintf
13591 (ERROR_BADPARM,
13592 "WARNING: %d NaNs found in volume %s...\n", nans, mri_src->fname) ;
13593 return(mri_dst) ;
13594 }
13595
13596 int
13597 MRIaddCommandLine(MRI *mri, char *cmdline)
13598 {
13599 int i ;
13600 if (mri->ncmds >= MAX_CMDS)
13601 ErrorExit
13602 (ERROR_NOMEMORY,
13603 "MRIaddCommandLine: can't add cmd %s (%d)", cmdline, mri->ncmds) ;
13604
13605 i = mri->ncmds++ ;
13606 mri->cmdlines[i] = (char *)calloc(strlen(cmdline)+1, sizeof(char)) ;
13607 strcpy(mri->cmdlines[i], cmdline) ;
13608 return(NO_ERROR) ;
13609 }
13610
13611
13612 //---------------------------------------------------------------
13613 #if 0 // old versions without support for compressed nifti
13614 /*------------------------------------------------------------------
13615 niiRead() - note: there is also an nifti1Read(). Make sure to
13616 edit both.
13617 -----------------------------------------------------------------*/
13618 static MRI *niiRead(char *fname, int read_volume)
13619 {
13620
13621 FILE *fp;
13622 MRI *mri;
13623 struct nifti_1_header hdr;
13624 int nslices;
13625 int fs_type;
13626 float time_units_factor, space_units_factor;
13627 int swapped_flag;
13628 int n_read, i, j, k, t;
13629 int bytes_per_voxel,time_units,space_units ;
13630
13631 fp = fopen(fname, "r");
13632 if(fp == NULL){
13633 errno = 0;
13634 ErrorReturn
13635 (NULL, (ERROR_BADFILE, "niiRead(): error opening file %s", fname));
13636 }
13637
13638 if(fread(&hdr, sizeof(hdr), 1, fp) != 1){
13639 fclose(fp);
13640 errno = 0;
13641 ErrorReturn
13642 (NULL,
13643 (ERROR_BADFILE, "niiRead(): error reading header from %s", fname));
13644 }
13645
13646 fclose(fp);
13647
13648 swapped_flag = FALSE;
13649 if(hdr.dim[0] < 1 || hdr.dim[0] > 7){
13650 swapped_flag = TRUE;
13651 swap_nifti_1_header(&hdr);
13652 if(hdr.dim[0] < 1 || hdr.dim[0] > 7)
13653 {
13654 ErrorReturn(NULL, (ERROR_BADFILE,
13655 "niiRead(): bad number of dimensions (%hd) in %s",
13656 hdr.dim[0], fname));
13657 }
13658 }
13659
13660 if(memcmp(hdr.magic, NII_MAGIC, 4) != 0){
13661 ErrorReturn
13662 (NULL, (ERROR_BADFILE, "niiRead(): bad magic number in %s", fname));
13663 }
13664
13665 if(hdr.dim[0] != 3 && hdr.dim[0] != 4){
13666 ErrorReturn(NULL,
13667 (ERROR_UNSUPPORTED,
13668 "niiRead(): %hd dimensions in %s; unsupported",
13669 hdr.dim[0], fname));
13670 }
13671
13672 if(hdr.datatype == DT_NONE || hdr.datatype == DT_UNKNOWN)
13673 {
13674 ErrorReturn(NULL,
13675 (ERROR_UNSUPPORTED,
13676 "niiRead(): unknown or no data type in %s; bailing out",
13677 fname));
13678 }
13679
13680 space_units = XYZT_TO_SPACE(hdr.xyzt_units) ;
13681 if(space_units == NIFTI_UNITS_METER) space_units_factor = 1000.0;
13682 else if(space_units == NIFTI_UNITS_MM) space_units_factor = 1.0;
13683 else if(space_units == NIFTI_UNITS_MICRON) space_units_factor = 0.001;
13684 else
13685 ErrorReturn
13686 (NULL,
13687 (ERROR_BADFILE,
13688 "niiRead(): unknown space units %d in %s", space_units,
13689 fname));
13690
13691 time_units = XYZT_TO_TIME (hdr.xyzt_units) ;
13692 if(time_units == NIFTI_UNITS_SEC) time_units_factor = 1000.0;
13693 else if(time_units == NIFTI_UNITS_MSEC) time_units_factor = 1.0;
13694 else if(time_units == NIFTI_UNITS_USEC) time_units_factor = 0.001;
13695 else{
13696 if(hdr.dim[4] > 1){
13697 ErrorReturn
13698 (NULL, (ERROR_BADFILE, "niiRead(): unknown time units %d in %s",
13699 time_units,fname));
13700 }
13701 else time_units_factor = 0;
13702 }
13703 //printf("hdr.xyzt_units = %d, time_units = %d, %g, %g\n",
13704 // hdr.xyzt_units,time_units,hdr.pixdim[4],time_units_factor);
13705
13706 /*
13707 nifti1.h says: slice_code = If this is nonzero,
13708 AND if slice_dim is nonzero, AND
13709 if slice_duration is positive, indicates the timing
13710 pattern of the slice acquisition.
13711 not yet supported here
13712 */
13713
13714 if(hdr.slice_code != 0 && DIM_INFO_TO_SLICE_DIM(hdr.dim_info) != 0
13715 && hdr.slice_duration > 0.0){
13716 ErrorReturn(NULL,
13717 (ERROR_UNSUPPORTED,
13718 "niiRead(): unsupported timing pattern in %s", fname));
13719 }
13720
13721 if(hdr.dim[0] == 3)
13722 nslices = 1;
13723 else
13724 nslices = hdr.dim[4];
13725
13726 if(hdr.scl_slope == 0){
13727 // voxel values are unscaled -- we use the file's data type
13728 if(hdr.datatype == DT_UNSIGNED_CHAR){
13729 fs_type = MRI_UCHAR;
13730 bytes_per_voxel = 1;
13731 }
13732 else if(hdr.datatype == DT_SIGNED_SHORT){
13733 fs_type = MRI_SHORT;
13734 bytes_per_voxel = 2;
13735 }
13736 else if(hdr.datatype == DT_SIGNED_INT){
13737 fs_type = MRI_INT;
13738 bytes_per_voxel = 4;
13739 }
13740 else if(hdr.datatype == DT_FLOAT){
13741 fs_type = MRI_FLOAT;
13742 bytes_per_voxel = 4;
13743 }
13744 else{
13745 ErrorReturn
13746 (NULL,
13747 (ERROR_UNSUPPORTED,
13748 "niiRead(): unsupported datatype %d (with scl_slope = 0) in %s",
13749 hdr.datatype, fname));
13750 }
13751 }
13752 else{
13753 // we must scale the voxel values
13754 if( hdr.datatype != DT_UNSIGNED_CHAR
13755 && hdr.datatype != DT_SIGNED_SHORT
13756 && hdr.datatype != DT_SIGNED_INT
13757 && hdr.datatype != DT_FLOAT
13758 && hdr.datatype != DT_DOUBLE
13759 && hdr.datatype != DT_INT8
13760 && hdr.datatype != DT_UINT16
13761 && hdr.datatype != DT_UINT32){
13762 ErrorReturn
13763 (NULL,
13764 (ERROR_UNSUPPORTED,
13765 "niiRead(): unsupported datatype %d (with scl_slope != 0) in %s",
13766 hdr.datatype, fname));
13767 }
13768 fs_type = MRI_FLOAT;
13769 bytes_per_voxel = 0; /* set below -- avoid the compiler warning */
13770 }
13771
13772 if(read_volume)
13773 mri = MRIallocSequence(hdr.dim[1],hdr.dim[2],hdr.dim[3],fs_type,nslices);
13774 else{
13775 mri = MRIallocHeader(hdr.dim[1], hdr.dim[2], hdr.dim[3], fs_type);
13776 mri->nframes = nslices;
13777 }
13778
13779 if(mri == NULL) return(NULL);
13780
13781 mri->xsize = hdr.pixdim[1];
13782 mri->ysize = hdr.pixdim[2];
13783 mri->zsize = hdr.pixdim[3];
13784 if(hdr.dim[0] == 4) mri->tr = hdr.pixdim[4];
13785
13786 if(hdr.qform_code == 0){
13787 printf("WARNING: missing NIfTI-1 orientation (qform_code = 0)\n");
13788 printf("WARNING: your volume will probably be incorrectly oriented\n");
13789 mri->x_r = 1.0; mri->x_a = 0.0; mri->x_s = 0.0;
13790 mri->y_r = 0.0; mri->y_a = 1.0; mri->y_s = 0.0;
13791 mri->z_r = 0.0; mri->z_a = 0.0; mri->z_s = 1.0;
13792 mri->c_r = mri->xsize * mri->width / 2.0;
13793 mri->c_a = mri->ysize * mri->height / 2.0;
13794 mri->c_s = mri->zsize * mri->depth / 2.0;
13795 }
13796 else if(hdr.sform_code <= 0){
13797 if(niftiQformToMri(mri, &hdr) != NO_ERROR){
13798 MRIfree(&mri);
13799 return(NULL);
13800 }
13801 }
13802 else{
13803 if(niftiSformToMri(mri, &hdr) != NO_ERROR){
13804 MRIfree(&mri);
13805 return(NULL);
13806 }
13807 }
13808
13809 mri->xsize = mri->xsize * space_units_factor;
13810 mri->ysize = mri->ysize * space_units_factor;
13811 mri->zsize = mri->zsize * space_units_factor;
13812 mri->c_r = mri->c_r * space_units_factor;
13813 mri->c_a = mri->c_a * space_units_factor;
13814 mri->c_s = mri->c_s * space_units_factor;
13815 if(hdr.dim[0] == 4) mri->tr = mri->tr * time_units_factor;
13816
13817 if(!read_volume) return(mri);
13818
13819 fp = fopen(fname, "r");
13820 if(fp == NULL) {
13821 MRIfree(&mri);
13822 errno = 0;
13823 ErrorReturn(NULL, (ERROR_BADFILE,
13824 "niiRead(): error opening file %s", fname));
13825 }
13826
13827 if(fseek(fp, (long)(hdr.vox_offset), SEEK_SET) == -1){
13828 fclose(fp);
13829 MRIfree(&mri);
13830 errno = 0;
13831 ErrorReturn(NULL, (ERROR_BADFILE,
13832 "niiRead(): error finding voxel data in %s", fname));
13833 }
13834
13835 if(hdr.scl_slope == 0){
13836 // no voxel value scaling needed
13837 void *buf;
13838
13839 for(t = 0;t < mri->nframes;t++)
13840 for(k = 0;k < mri->depth;k++)
13841 for(j = 0;j < mri->height;j++) {
13842 buf = &MRIseq_vox(mri, 0, j, k, t);
13843
13844 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13845 if(n_read != mri->width) {
13846 fclose(fp);
13847 MRIfree(&mri);
13848 errno = 0;
13849 ErrorReturn(NULL, (ERROR_BADFILE,
13850 "niiRead(): error reading from %s", fname));
13851 }
13852
13853 if(swapped_flag) {
13854 if(bytes_per_voxel == 2)
13855 byteswapbufshort(buf, bytes_per_voxel * mri->width);
13856 if(bytes_per_voxel == 4)
13857 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
13858 }
13859
13860 }
13861
13862 }
13863 else{
13864 // voxel value scaling needed
13865 if(hdr.datatype == DT_UNSIGNED_CHAR) {
13866 unsigned char *buf;
13867 bytes_per_voxel = 1;
13868 buf = (unsigned char *)malloc(mri->width * bytes_per_voxel);
13869 for(t = 0;t < mri->nframes;t++)
13870 for(k = 0;k < mri->depth;k++)
13871 for(j = 0;j < mri->height;j++) {
13872 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13873 if(n_read != mri->width) {
13874 free(buf);
13875 fclose(fp);
13876 MRIfree(&mri);
13877 errno = 0;
13878 ErrorReturn(NULL,
13879 (ERROR_BADFILE,
13880 "niiRead(): error reading from %s", fname));
13881 }
13882 for(i = 0;i < mri->width;i++)
13883 MRIFseq_vox(mri, i, j, k, t) =
13884 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
13885 }
13886 free(buf);
13887 }
13888
13889 if(hdr.datatype == DT_SIGNED_SHORT){
13890 short *buf;
13891 bytes_per_voxel = 2;
13892 buf = (short *)malloc(mri->width * bytes_per_voxel);
13893 for(t = 0;t < mri->nframes;t++)
13894 for(k = 0;k < mri->depth;k++)
13895 for(j = 0;j < mri->height;j++) {
13896 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13897 if(n_read != mri->width) {
13898 free(buf);
13899 fclose(fp);
13900 MRIfree(&mri);
13901 errno = 0;
13902 ErrorReturn(NULL,
13903 (ERROR_BADFILE,
13904 "niiRead(): error reading from %s", fname));
13905 }
13906 if(swapped_flag)
13907 byteswapbufshort(buf, bytes_per_voxel * mri->width);
13908 for(i = 0;i < mri->width;i++)
13909 MRIFseq_vox(mri, i, j, k, t) =
13910 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
13911 }
13912 free(buf);
13913 }
13914
13915 if(hdr.datatype == DT_SIGNED_INT) {
13916 int *buf;
13917 bytes_per_voxel = 4;
13918 buf = (int *)malloc(mri->width * bytes_per_voxel);
13919 for(t = 0;t < mri->nframes;t++)
13920 for(k = 0;k < mri->depth;k++)
13921 for(j = 0;j < mri->height;j++) {
13922 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13923 if(n_read != mri->width){
13924 free(buf);
13925 fclose(fp);
13926 MRIfree(&mri);
13927 errno = 0;
13928 ErrorReturn(NULL,
13929 (ERROR_BADFILE,
13930 "niiRead(): error reading from %s", fname));
13931 }
13932 if(swapped_flag)
13933 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
13934 for(i = 0;i < mri->width;i++)
13935 MRIFseq_vox(mri, i, j, k, t) =
13936 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
13937 }
13938 free(buf);
13939 }
13940
13941 if(hdr.datatype == DT_FLOAT) {
13942 float *buf;
13943 bytes_per_voxel = 4;
13944 buf = (float *)malloc(mri->width * bytes_per_voxel);
13945 for(t = 0;t < mri->nframes;t++)
13946 for(k = 0;k < mri->depth;k++)
13947 for(j = 0;j < mri->height;j++) {
13948 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13949 if(n_read != mri->width) {
13950 free(buf);
13951 fclose(fp);
13952 MRIfree(&mri);
13953 errno = 0;
13954 ErrorReturn(NULL,
13955 (ERROR_BADFILE,
13956 "niiRead(): error reading from %s", fname));
13957 }
13958 if(swapped_flag)
13959 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
13960 for(i = 0;i < mri->width;i++)
13961 MRIFseq_vox(mri, i, j, k, t) =
13962 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
13963 }
13964 free(buf);
13965 }
13966
13967 if(hdr.datatype == DT_DOUBLE) {
13968 double *buf;
13969 unsigned char *cbuf, ccbuf[8];
13970 bytes_per_voxel = 8;
13971 buf = (double *)malloc(mri->width * bytes_per_voxel);
13972 for(t = 0;t < mri->nframes;t++)
13973 for(k = 0;k < mri->depth;k++)
13974 for(j = 0;j < mri->height;j++) {
13975 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
13976 if(n_read != mri->width) {
13977 free(buf);
13978 fclose(fp);
13979 MRIfree(&mri);
13980 errno = 0;
13981 ErrorReturn(NULL,
13982 (ERROR_BADFILE,
13983 "niiRead(): error reading from %s", fname));
13984 }
13985 if(swapped_flag) {
13986 for(i = 0;i < mri->width;i++)
13987 {
13988 cbuf = (unsigned char *)&buf[i];
13989 memcpy(ccbuf, cbuf, 8);
13990 cbuf[0] = ccbuf[7];
13991 cbuf[1] = ccbuf[6];
13992 cbuf[2] = ccbuf[5];
13993 cbuf[3] = ccbuf[4];
13994 cbuf[4] = ccbuf[3];
13995 cbuf[5] = ccbuf[2];
13996 cbuf[6] = ccbuf[1];
13997 cbuf[7] = ccbuf[0];
13998 }
13999 }
14000 for(i = 0;i < mri->width;i++)
14001 MRIFseq_vox(mri, i, j, k, t) =
14002 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
14003 }
14004 free(buf);
14005 }
14006
14007 if(hdr.datatype == DT_INT8) {
14008 char *buf;
14009 bytes_per_voxel = 1;
14010 buf = (char *)malloc(mri->width * bytes_per_voxel);
14011 for(t = 0;t < mri->nframes;t++)
14012 for(k = 0;k < mri->depth;k++)
14013 for(j = 0;j < mri->height;j++){
14014 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
14015 if(n_read != mri->width) {
14016 free(buf);
14017 fclose(fp);
14018 MRIfree(&mri);
14019 errno = 0;
14020 ErrorReturn(NULL,
14021 (ERROR_BADFILE,
14022 "niiRead(): error reading from %s", fname));
14023 }
14024 for(i = 0;i < mri->width;i++)
14025 MRIFseq_vox(mri, i, j, k, t) =
14026 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
14027 }
14028 free(buf);
14029 }
14030
14031 if(hdr.datatype == DT_UINT16) {
14032 unsigned short *buf;
14033 bytes_per_voxel = 2;
14034 buf = (unsigned short *)malloc(mri->width * bytes_per_voxel);
14035 for(t = 0;t < mri->nframes;t++)
14036 for(k = 0;k < mri->depth;k++)
14037 for(j = 0;j < mri->height;j++) {
14038 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
14039 if(n_read != mri->width){
14040 free(buf);
14041 fclose(fp);
14042 MRIfree(&mri);
14043 errno = 0;
14044 ErrorReturn(NULL,
14045 (ERROR_BADFILE,
14046 "niiRead(): error reading from %s", fname));
14047 }
14048 if(swapped_flag)
14049 byteswapbufshort(buf, bytes_per_voxel * mri->width);
14050 for(i = 0;i < mri->width;i++)
14051 MRIFseq_vox(mri, i, j, k, t) =
14052 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
14053 }
14054 free(buf);
14055 }
14056
14057 if(hdr.datatype == DT_UINT32) {
14058 unsigned int *buf;
14059 bytes_per_voxel = 4;
14060 buf = (unsigned int *)malloc(mri->width * bytes_per_voxel);
14061 for(t = 0;t < mri->nframes;t++)
14062 for(k = 0;k < mri->depth;k++)
14063 for(j = 0;j < mri->height;j++)
14064 {
14065 n_read = fread(buf, bytes_per_voxel, mri->width, fp);
14066 if(n_read != mri->width)
14067 {
14068 free(buf);
14069 fclose(fp);
14070 MRIfree(&mri);
14071 errno = 0;
14072 ErrorReturn(NULL,
14073 (ERROR_BADFILE,
14074 "niiRead(): error reading from %s", fname));
14075 }
14076 if(swapped_flag)
14077 byteswapbuffloat(buf, bytes_per_voxel * mri->width);
14078 for(i = 0;i < mri->width;i++)
14079 MRIFseq_vox(mri, i, j, k, t) =
14080 hdr.scl_slope * (float)(buf[i]) + hdr.scl_inter;
14081 }
14082 free(buf);
14083 }
14084 }
14085 fclose(fp);
14086
14087 return(mri);
14088
14089 } /* end niiRead() */
14090 /*------------------------------------------------------------------
14091 niiWrite() - note: there is also an nifti1Write(). Make sure to
14092 edit both.
14093 -----------------------------------------------------------------*/
14094 static int niiWrite(MRI *mri, char *fname)
14095 {
14096
14097 FILE *fp;
14098 int j, k, t;
14099 BUFTYPE *buf;
14100 struct nifti_1_header hdr;
14101 int error;
14102
14103 memset(&hdr, 0x00, sizeof(hdr));
14104
14105 hdr.sizeof_hdr = 348;
14106 hdr.dim_info = 0;
14107
14108 if(mri->nframes == 1){
14109 hdr.dim[0] = 3;
14110 hdr.dim[1] = mri->width;
14111 hdr.dim[2] = mri->height;
14112 hdr.dim[3] = mri->depth;
14113 hdr.pixdim[1] = mri->xsize;
14114 hdr.pixdim[2] = mri->ysize;
14115 hdr.pixdim[3] = mri->zsize;
14116 }
14117 else{
14118 hdr.dim[0] = 4;
14119 hdr.dim[1] = mri->width;
14120 hdr.dim[2] = mri->height;
14121 hdr.dim[3] = mri->depth;
14122 hdr.dim[4] = mri->nframes;
14123 hdr.pixdim[1] = mri->xsize;
14124 hdr.pixdim[2] = mri->ysize;
14125 hdr.pixdim[3] = mri->zsize;
14126 hdr.pixdim[4] = mri->tr/1000.0; // see also xyzt_units
14127 }
14128
14129 if(mri->type == MRI_UCHAR)
14130 {
14131 hdr.datatype = DT_UNSIGNED_CHAR;
14132 hdr.bitpix = 8;
14133 }
14134 else if(mri->type == MRI_INT)
14135 {
14136 hdr.datatype = DT_SIGNED_INT;
14137 hdr.bitpix = 32;
14138 }
14139 else if(mri->type == MRI_LONG)
14140 {
14141 hdr.datatype = DT_SIGNED_INT;
14142 hdr.bitpix = 32;
14143 }
14144 else if(mri->type == MRI_FLOAT)
14145 {
14146 hdr.datatype = DT_FLOAT;
14147 hdr.bitpix = 32;
14148 }
14149 else if(mri->type == MRI_SHORT)
14150 {
14151 hdr.datatype = DT_SIGNED_SHORT;
14152 hdr.bitpix = 16;
14153 }
14154 else if(mri->type == MRI_BITMAP)
14155 {
14156 ErrorReturn(ERROR_UNSUPPORTED,
14157 (ERROR_UNSUPPORTED,
14158 "niiWrite(): data type MRI_BITMAP unsupported"));
14159 }
14160 else if(mri->type == MRI_TENSOR)
14161 {
14162 ErrorReturn(ERROR_UNSUPPORTED,
14163 (ERROR_UNSUPPORTED,
14164 "niiWrite(): data type MRI_TENSOR unsupported"));
14165 }
14166 else
14167 {
14168 ErrorReturn(ERROR_BADPARM,
14169 (ERROR_BADPARM,
14170 "niiWrite(): unknown data type %d", mri->type));
14171 }
14172
14173 hdr.intent_code = NIFTI_INTENT_NONE;
14174 hdr.intent_name[0] = '\0';
14175 hdr.vox_offset = sizeof(hdr);
14176 hdr.scl_slope = 0.0;
14177 hdr.slice_code = 0;
14178 hdr.xyzt_units = NIFTI_UNITS_MM | NIFTI_UNITS_SEC;
14179 hdr.cal_max = 0.0;
14180 hdr.cal_min = 0.0;
14181 hdr.toffset = 0;
14182
14183 /* set the nifti header qform values */
14184 error = mriToNiftiQform(mri, &hdr);
14185 if(error != NO_ERROR)
14186 return(error);
14187
14188 memcpy(hdr.magic, NII_MAGIC, 4);
14189
14190 fp = fopen(fname, "w");
14191 if(fp == NULL)
14192 {
14193 errno = 0;
14194 ErrorReturn(ERROR_BADFILE,
14195 (ERROR_BADFILE,
14196 "niiWrite(): error opening file %s", fname));
14197 }
14198
14199 if(fwrite(&hdr, sizeof(hdr), 1, fp) != 1)
14200 {
14201 fclose(fp);
14202 errno = 0;
14203 ErrorReturn(ERROR_BADFILE,
14204 (ERROR_BADFILE,
14205 "niiWrite(): error writing header to %s", fname));
14206 }
14207
14208 for(t = 0;t < mri->nframes;t++)
14209 for(k = 0;k < mri->depth;k++)
14210 for(j = 0;j < mri->height;j++)
14211 {
14212 buf = &MRIseq_vox(mri, 0, j, k, t);
14213 if(fwrite(buf, hdr.bitpix/8, mri->width, fp) != mri->width)
14214 {
14215 fclose(fp);
14216 errno = 0;
14217 ErrorReturn(ERROR_BADFILE,
14218 (ERROR_BADFILE,
14219 "niiWrite(): error writing data to %s", fname));
14220 }
14221 }
14222
14223 fclose(fp);
14224
14225 return(NO_ERROR);
14226
14227 } /* end niiWrite() */
14228
14229 #endif
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.- [get | view] (2009-01-26 22:35:32, 12.9 KB) [[attachment:fio.c]]
- [get | view] (2009-01-26 22:35:32, 1.3 KB) [[attachment:fio.h]]
- [get | view] (2009-01-26 22:35:32, 5.9 KB) [[attachment:load_mgh.m]]
- [get | view] (2009-01-26 22:35:32, 9.3 KB) [[attachment:matrix.h]]
- [get | view] (2009-01-26 22:35:32, 390.2 KB) [[attachment:mri.c]]
- [get | view] (2009-01-26 22:35:32, 48.5 KB) [[attachment:mri.h]]
- [get | view] (2009-01-26 22:35:32, 94.4 KB) [[attachment:mri_convert.c]]
- [get | view] (2009-01-26 22:35:32, 14.1 KB) [[attachment:mri_info.c]]
- [get | view] (2009-01-26 22:35:32, 395.4 KB) [[attachment:mriio.c]]
- [get | view] (2009-01-26 22:35:32, 2.4 KB) [[attachment:save_mgh.m]]
- [get | view] (2009-01-26 22:35:32, 2.2 KB) [[attachment:tags.c]]
- [get | view] (2009-01-26 22:35:32, 0.9 KB) [[attachment:tags.h]]
You are not allowed to attach a file to this page.