analyze.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   Copyright (c) 2003-2008 by Turku PET Centre
00004 
00005   Library:      analyze.c
00006   Description:  Procedures for reading and writing Analyze 7.5 images.
00007 
00008   This library is free software; you can redistribute it and/or
00009   modify it under the terms of the GNU Lesser General Public
00010   License as published by the Free Software Foundation; either
00011   version 2.1 of the License, or (at your option) any later version.
00012 
00013   This library is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016   See the GNU Lesser General Public License for more details:
00017   http://www.gnu.org/copyleft/lesser.html
00018 
00019   You should have received a copy of the GNU Lesser General Public License
00020   along with this library/program; if not, write to the Free Software
00021   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
00022 
00023   Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi/
00024 
00025   Modification history:
00026   2003-10-05 Vesa Oikonen
00027     First created.
00028   2003-12-05 VO
00029     Included function anaFlipping().
00030   2003-12-10 VO
00031     Setting of maximum nr of characters for string printing in
00032     anaPrintHeader().
00033   2004-02-05 VO
00034     Change in function information, no change in compiled code.
00035   2004-09-17 VO
00036     Doxygen style comments.
00037   2007-02-27 VO
00038     Included functions anaRemove(), anaRemoveFNameExtension(),
00039     anaDatabaseExists() and anaMakeSIFName().
00040   2007-17-07 Harri Merisaari
00041     modified anaRemoveFNameExtension(char *fname) for ANSI 
00042     compatibility build option
00043   2007-09-11 VO
00044     Corrected a bug in anaRemoveFNameExtension().
00045   2008-10-03 VO
00046     AnaReadImageData() accepts ANALYZE_DT_FLOAT and ANALYZE_DT_SIGNED_INT
00047     with both 16 and 32 bit pixel values (previously only 16 bits).
00048     Function might need to be rewritten.
00049   2008-10-09 VO
00050     AnaReadImageData() accepts ANALYZE_DT_COMPLEX, since PVELab writes pixel
00051     values in this (32/32) format.
00052 
00053 
00054 ******************************************************************************/
00055 #include <stdio.h>
00056 #include <string.h>
00057 #include <math.h>
00058 #include <stdlib.h>
00059 #include <time.h>
00060 #include <unistd.h>
00061 /*****************************************************************************/
00062 #include "swap.h"
00063 #include "substitutions.h"
00064 /*****************************************************************************/
00065 #include "include/analyze.h"
00066 /*****************************************************************************/
00067 
00068 /*****************************************************************************/
00075 int anaExists(const char *dbname) {
00076   char temp[FILENAME_MAX];
00077 
00078   if(dbname==NULL || strlen(dbname)==0) return(0);
00079   /* Header file? */
00080   strcpy(temp, dbname); strcat(temp, ".hdr");
00081   if(access(temp, 0) == -1) return(0);
00082   /* Image data? */
00083   strcpy(temp, dbname); strcat(temp, ".img");
00084   if(access(temp, 0) == -1) return(0);
00085   /* SIF? */
00086   strcat(temp, ".sif"); if(access(temp, 0) != -1) return(2);
00087   strcpy(temp, dbname); strcat(temp, ".sif");
00088   if(access(temp, 0) != -1) return(2);
00089   return(1);
00090 }
00091 /*****************************************************************************/
00092 
00093 /*****************************************************************************/
00102 int anaReadHeader(char *filename, ANALYZE_DSR *h) {
00103   unsigned char buf1[ANALYZE_HEADER_KEY_SIZE];
00104   unsigned char buf2[ANALYZE_HEADER_IMGDIM_SIZE];
00105   unsigned char buf3[ANALYZE_HEADER_HISTORY_SIZE];
00106   int little; /* 1 if current platform is little endian (i386), else 0 */
00107   FILE *fp;
00108   int ret, nr=0, s1, s2, same_order;
00109 
00110   if(ANALYZE_TEST) printf("anaReadHeader(%s, *dsr)\n", filename);
00111 
00112   /* Check arguments */
00113   if(strlen(filename)<1 || h==NULL) return(1);
00114   little=little_endian();
00115   /* Open file */
00116   fp=fopen(filename, "rb"); if(fp==NULL) return(2);
00117   /* Get file size */
00118   nr=0; while((ret=fgetc(fp))!=EOF) nr++; rewind(fp);
00119   if(nr<1) {fclose(fp); return(3);}
00120   /* Read Analyze header key */
00121   if(fread(buf1, ANALYZE_HEADER_KEY_SIZE, 1, fp)<1) return(3);
00122   /* Read Analyze header image dimension */
00123   if(fread(buf2, ANALYZE_HEADER_IMGDIM_SIZE, 1, fp)<1) return(3);
00124   /* Read Analyze header image data history */
00125   memset(buf3, 0, sizeof(ANALYZE_HEADER_HISTORY));
00126   ret=fread(buf3, ANALYZE_HEADER_HISTORY_SIZE, 1, fp);
00127   if(ANALYZE_TEST>1 && ret) printf(" complete data_history not found.\n");
00128   /* Close file */
00129   fclose(fp);
00130   /* Compare file size from header contents to the calculated value */
00131   /* to determine whether Analyze file is in little or big endian */
00132   memcpy(&s1, buf1+0, 4); s2=s1; swawbip(&s2, 4);
00133   if(abs(s1-nr)<abs(s2-nr)) same_order=1; else same_order=0;
00134   if(ANALYZE_TEST>1) printf("same byte order: %d (s1=%d s2=%d nr=%d)\n",
00135     same_order, s1, s2, nr);
00136   if(same_order) h->little=little;
00137   else {if(little) h->little=0; else h->little=1;}
00138 
00139   /* Set key header structure contents */
00140   if(!same_order) swawbip(buf1+0, 4); memcpy(&h->hk.sizeof_hdr, buf1+0, 4);
00141   memcpy(h->hk.data_type, buf1+4, 10);
00142   memcpy(h->hk.db_name, buf1+14, 18);
00143   if(!same_order) swawbip(buf1+32, 4); memcpy(&h->hk.extents, buf1+32, 4);
00144   if(!same_order) swabip(buf1+36, 2); memcpy(&h->hk.session_error, buf1+36, 2);
00145   memcpy(&h->hk.regular, buf1+38, 1);
00146   memcpy(&h->hk.hkey_un0, buf1+39, 1);
00147 
00148   /* Set image dimension header structure contents */
00149   if(!same_order) swabip(buf2+0, 16); memcpy(h->dime.dim, buf2+0, 16);
00150   if(!same_order) swabip(buf2+16, 2); memcpy(&h->dime.unused8, buf2+16, 2);
00151   if(!same_order) swabip(buf2+18, 2); memcpy(&h->dime.unused9, buf2+18, 2);
00152   if(!same_order) swabip(buf2+20, 2); memcpy(&h->dime.unused10, buf2+20, 2);
00153   if(!same_order) swabip(buf2+22, 2); memcpy(&h->dime.unused11, buf2+22, 2);
00154   if(!same_order) swabip(buf2+24, 2); memcpy(&h->dime.unused12, buf2+24, 2);
00155   if(!same_order) swabip(buf2+26, 2); memcpy(&h->dime.unused13, buf2+26, 2);
00156   if(!same_order) swabip(buf2+28, 2); memcpy(&h->dime.unused14, buf2+28, 2);
00157   if(!same_order) swabip(buf2+30, 2); memcpy(&h->dime.datatype, buf2+30, 2);
00158   if(!same_order) swabip(buf2+32, 2); memcpy(&h->dime.bitpix, buf2+32, 2);
00159   if(!same_order) swabip(buf2+34, 2); memcpy(&h->dime.dim_un0, buf2+34, 2);
00160   if(!same_order) swawbip(buf2+36, 32); memcpy(h->dime.pixdim, buf2+36, 32);
00161   if(!same_order) swawbip(buf2+68, 4); memcpy(&h->dime.vox_offset, buf2+68, 4);
00162   if(!same_order) swawbip(buf2+72, 4); memcpy(&h->dime.funused1, buf2+72, 4);
00163   if(!same_order) swawbip(buf2+76, 4); memcpy(&h->dime.funused2, buf2+76, 4);
00164   if(!same_order) swawbip(buf2+80, 4); memcpy(&h->dime.funused3, buf2+80, 4);
00165   if(!same_order) swawbip(buf2+84, 4); memcpy(&h->dime.cal_max, buf2+84, 4);
00166   if(!same_order) swawbip(buf2+88, 4); memcpy(&h->dime.cal_min, buf2+88, 4);
00167   if(!same_order) swawbip(buf2+92, 4); memcpy(&h->dime.compressed, buf2+92, 4);
00168   if(!same_order) swawbip(buf2+96, 4); memcpy(&h->dime.verified, buf2+96, 4);
00169   if(!same_order) swawbip(buf2+100, 4); memcpy(&h->dime.glmax, buf2+100, 4);
00170   if(!same_order) swawbip(buf2+104, 4); memcpy(&h->dime.glmin, buf2+104, 4);
00171 
00172   /* Set data history header structure contents */
00173   memcpy(h->hist.descrip, buf3+0, 80);
00174   memcpy(h->hist.aux_file, buf3+80, 24);
00175   memcpy(&h->hist.orient, buf3+104, 1);
00176   memcpy(h->hist.originator, buf3+105, 10);
00177   memcpy(h->hist.generated, buf3+115, 10);
00178   memcpy(h->hist.scannum, buf3+125, 10);
00179   memcpy(h->hist.patient_id, buf3+135, 10);
00180   memcpy(h->hist.exp_date, buf3+145, 10);
00181   memcpy(h->hist.exp_time, buf3+155, 10);
00182   memcpy(h->hist.hist_un0, buf3+165, 3);
00183   if(!same_order) swawbip(buf3+168, 4); memcpy(&h->hist.views, buf3+168, 4);
00184   if(!same_order) swawbip(buf3+172, 4); memcpy(&h->hist.vols_added, buf3+172, 4);
00185   if(!same_order) swawbip(buf3+176, 4); memcpy(&h->hist.start_field, buf3+176, 4);
00186   if(!same_order) swawbip(buf3+180, 4); memcpy(&h->hist.field_skip, buf3+180, 4);
00187   if(!same_order) swawbip(buf3+184, 4); memcpy(&h->hist.omax, buf3+184, 4);
00188   if(!same_order) swawbip(buf3+188, 4); memcpy(&h->hist.omin, buf3+188, 4);
00189   if(!same_order) swawbip(buf3+192, 4); memcpy(&h->hist.smax, buf3+192, 4);
00190   if(!same_order) swawbip(buf3+196, 4); memcpy(&h->hist.smin, buf3+196, 4);
00191 
00192   /* Check header contents */
00193   if(h->hk.extents!=16384 && h->hk.extents!=0) return(11);
00194   if(h->hk.regular!='r') return(12);
00195 
00196   return(0);
00197 }
00198 /*****************************************************************************/
00199 
00200 /*****************************************************************************/
00209 int anaWriteHeader(char *filename, ANALYZE_DSR *h) {
00210   unsigned char buf1[ANALYZE_HEADER_KEY_SIZE];
00211   unsigned char buf2[ANALYZE_HEADER_IMGDIM_SIZE];
00212   unsigned char buf3[ANALYZE_HEADER_HISTORY_SIZE];
00213   FILE *fp;
00214   int same_order, little;
00215 
00216 
00217   if(ANALYZE_TEST) printf("anaWriteHeader(%s, *dsr)\n", filename);
00218 
00219   /* Check arguments */
00220   if(strlen(filename)<1 || h==NULL) return(1);
00221   little=little_endian();
00222   if(little==h->little) same_order=1; else same_order=0;
00223   
00224   /* Copy header contents into buffers */
00225   /* Header key */
00226   memset(buf1, 0, sizeof(ANALYZE_HEADER_KEY_SIZE));
00227   memcpy(buf1+0, &h->hk.sizeof_hdr, 4); if(!same_order) swawbip(buf1+0, 4);
00228   memcpy(buf1+4, &h->hk.data_type, 10);
00229   memcpy(buf1+14, &h->hk.db_name, 18);
00230   memcpy(buf1+32, &h->hk.extents, 4); if(!same_order) swawbip(buf1+32, 4);
00231   memcpy(buf1+36, &h->hk.session_error, 2); if(!same_order) swabip(buf1+36, 2);
00232   memcpy(buf1+38, &h->hk.regular, 1);
00233   memcpy(buf1+39, &h->hk.hkey_un0, 1);
00234   /* Image dimension */
00235   memset(buf2, 0, sizeof(ANALYZE_HEADER_IMGDIM_SIZE));
00236   memcpy(buf2+0, h->dime.dim, 16); if(!same_order) swabip(buf2+0, 16);
00237   memcpy(buf2+16, &h->dime.unused8, 2); if(!same_order) swabip(buf2+16, 2);
00238   memcpy(buf2+18, &h->dime.unused9, 2); if(!same_order) swabip(buf2+18, 2);
00239   memcpy(buf2+20, &h->dime.unused10, 2); if(!same_order) swabip(buf2+20, 2);
00240   memcpy(buf2+22, &h->dime.unused11, 2); if(!same_order) swabip(buf2+22, 2);
00241   memcpy(buf2+24, &h->dime.unused12, 2); if(!same_order) swabip(buf2+24, 2);
00242   memcpy(buf2+26, &h->dime.unused13, 2); if(!same_order) swabip(buf2+26, 2);
00243   memcpy(buf2+28, &h->dime.unused14, 2); if(!same_order) swabip(buf2+28, 2);
00244   memcpy(buf2+30, &h->dime.datatype, 2); if(!same_order) swabip(buf2+30, 2);
00245   memcpy(buf2+32, &h->dime.bitpix, 2); if(!same_order) swabip(buf2+32, 2);
00246   memcpy(buf2+34, &h->dime.dim_un0, 2); if(!same_order) swabip(buf2+34, 2);
00247   memcpy(buf2+36, h->dime.pixdim, 32); if(!same_order) swawbip(buf2+36, 32);
00248   memcpy(buf2+68, &h->dime.vox_offset, 4); if(!same_order) swawbip(buf2+68, 4);
00249   memcpy(buf2+72, &h->dime.funused1, 4); if(!same_order) swawbip(buf2+72, 4);
00250   memcpy(buf2+76, &h->dime.funused2, 4); if(!same_order) swawbip(buf2+76, 4);
00251   memcpy(buf2+80, &h->dime.funused3, 4); if(!same_order) swawbip(buf2+80, 4);
00252   memcpy(buf2+84, &h->dime.cal_max, 4); if(!same_order) swawbip(buf2+84, 4);
00253   memcpy(buf2+88, &h->dime.cal_min, 4); if(!same_order) swawbip(buf2+88, 4);
00254   memcpy(buf2+92, &h->dime.compressed, 4); if(!same_order) swawbip(buf2+92, 4);
00255   memcpy(buf2+96, &h->dime.verified, 4); if(!same_order) swawbip(buf2+96, 4);
00256   memcpy(buf2+100, &h->dime.glmax, 4); if(!same_order) swawbip(buf2+100, 4);
00257   memcpy(buf2+104, &h->dime.glmin, 4); if(!same_order) swawbip(buf2+104, 4);
00258   /* Data history */
00259   memset(buf3, 0, sizeof(ANALYZE_HEADER_HISTORY_SIZE));
00260   memcpy(buf3+0, &h->hist.descrip, 80);
00261   memcpy(buf3+80, &h->hist.aux_file, 24);
00262   memcpy(buf3+104, &h->hist.orient, 1);
00263   memcpy(buf3+105, &h->hist.originator, 10);
00264   memcpy(buf3+115, &h->hist.generated, 10);
00265   memcpy(buf3+125, &h->hist.scannum, 10);
00266   memcpy(buf3+135, &h->hist.patient_id, 10);
00267   memcpy(buf3+145, &h->hist.exp_date, 10);
00268   memcpy(buf3+155, &h->hist.exp_time, 10);
00269   memcpy(buf3+165, &h->hist.hist_un0, 3);
00270   memcpy(buf3+168, &h->hist.views, 4); if(!same_order) swawbip(buf3+168, 4);
00271   memcpy(buf3+172, &h->hist.vols_added, 4); if(!same_order) swawbip(buf3+172, 4);
00272   memcpy(buf3+176, &h->hist.start_field, 4); if(!same_order) swawbip(buf3+176, 4);
00273   memcpy(buf3+180, &h->hist.field_skip, 4); if(!same_order) swawbip(buf3+180, 4);
00274   memcpy(buf3+184, &h->hist.omax, 4); if(!same_order) swawbip(buf3+184, 4);
00275   memcpy(buf3+188, &h->hist.omin, 4); if(!same_order) swawbip(buf3+188, 4);
00276   memcpy(buf3+192, &h->hist.smax, 4); if(!same_order) swawbip(buf3+192, 4);
00277   memcpy(buf3+196, &h->hist.smin, 4); if(!same_order) swawbip(buf3+196, 4);
00278 
00279   /* Open header file for write */
00280   fp=fopen(filename, "wb"); if(fp==NULL) return(2);
00281   /* Write header key */
00282   if(fwrite(buf1, 1, ANALYZE_HEADER_KEY_SIZE, fp) != ANALYZE_HEADER_KEY_SIZE) {
00283     fclose(fp); return(3);
00284   }
00285   /* Write image dimension */
00286   if(fwrite(buf2, 1, ANALYZE_HEADER_IMGDIM_SIZE, fp) != ANALYZE_HEADER_IMGDIM_SIZE) {
00287     fclose(fp); return(4);
00288   }
00289   /* Write data history */
00290   if(fwrite(buf3, 1, ANALYZE_HEADER_HISTORY_SIZE, fp) != ANALYZE_HEADER_HISTORY_SIZE) {
00291     fclose(fp); return(5);
00292   }
00293   fclose(fp);
00294 
00295   return(0);
00296 }
00297 /*****************************************************************************/
00298 
00299 /*****************************************************************************/
00307 int anaPrintHeader(ANALYZE_DSR *h, FILE *fp) {
00308   int i;
00309 
00310   if(fp==NULL || h==NULL) return(1);
00311   fprintf(fp, "original_byte_order := %d (1=little, 0=big)\n", h->little);
00312   /* Key */
00313   fprintf(fp, "header_key.sizeof_hdr := %d\n", h->hk.sizeof_hdr);
00314   fprintf(fp, "header_key.data_type := %.10s\n", h->hk.data_type);
00315   fprintf(fp, "header_key.db_name := %.18s\n", h->hk.db_name);
00316   fprintf(fp, "header_key.extents := %d\n", h->hk.extents);
00317   fprintf(fp, "header_key.session_error := %d\n", h->hk.session_error);
00318   fprintf(fp, "header_key.regular := %d (%c)\n", (int)h->hk.regular, h->hk.regular);
00319   fprintf(fp, "header_key.hkey_un0 := %d\n", (int)h->hk.hkey_un0);
00320   /* Image dimension */
00321   fprintf(fp, "header_image_dimension.dim :=");
00322   for(i=0; i<8; i++) fprintf(fp, " %d", h->dime.dim[i]);
00323   fprintf(fp, "\n");
00324   fprintf(fp, "header_image_dimension.unused8 := %d\n", h->dime.unused8);
00325   fprintf(fp, "header_image_dimension.unused9 := %d\n", h->dime.unused9);
00326   fprintf(fp, "header_image_dimension.unused10 := %d\n", h->dime.unused10);
00327   fprintf(fp, "header_image_dimension.unused11 := %d\n", h->dime.unused11);
00328   fprintf(fp, "header_image_dimension.unused12 := %d\n", h->dime.unused12);
00329   fprintf(fp, "header_image_dimension.unused13 := %d\n", h->dime.unused13);
00330   fprintf(fp, "header_image_dimension.unused14 := %d\n", h->dime.unused14);
00331   fprintf(fp, "header_image_dimension.datatype := %d\n", h->dime.datatype);
00332   fprintf(fp, "header_image_dimension.bitpix := %d\n", h->dime.bitpix);
00333   fprintf(fp, "header_image_dimension.dim_un0 := %d\n", h->dime.dim_un0);
00334   fprintf(fp, "header_image_dimension.pixdim :=");
00335   for(i=0; i<8; i++) fprintf(fp, " %g", h->dime.pixdim[i]);
00336   fprintf(fp, "\n");
00337   fprintf(fp, "header_image_dimension.vox_offset := %g\n", h->dime.vox_offset);
00338   fprintf(fp, "header_image_dimension.funused1 := %g\n", h->dime.funused1);
00339   fprintf(fp, "header_image_dimension.funused2 := %g\n", h->dime.funused2);
00340   fprintf(fp, "header_image_dimension.funused3 := %g\n", h->dime.funused3);
00341   fprintf(fp, "header_image_dimension.cal_max := %g\n", h->dime.cal_max);
00342   fprintf(fp, "header_image_dimension.cal_min := %g\n", h->dime.cal_min);
00343   fprintf(fp, "header_image_dimension.compressed := %g\n", h->dime.compressed);
00344   fprintf(fp, "header_image_dimension.verified := %g\n", h->dime.verified);
00345   fprintf(fp, "header_image_dimension.glmax := %d\n", h->dime.glmax);
00346   fprintf(fp, "header_image_dimension.glmin := %d\n", h->dime.glmin);
00347   /* Data history */
00348   fprintf(fp, "header_data_history.descrip := %s.80\n", h->hist.descrip);
00349   fprintf(fp, "header_data_history.aux_file := %.24s\n", h->hist.aux_file);
00350   fprintf(fp, "header_data_history.orient := %d\n", (int)h->hist.orient);
00351   fprintf(fp, "header_data_history.originator := %.10s\n", h->hist.originator);
00352   fprintf(fp, "header_data_history.generated := %.10s\n", h->hist.generated);
00353   fprintf(fp, "header_data_history.scannum := %.10s\n", h->hist.scannum);
00354   fprintf(fp, "header_data_history.patient_id := %.10s\n", h->hist.patient_id);
00355   fprintf(fp, "header_data_history.exp_date := %.10s\n", h->hist.exp_date);
00356   fprintf(fp, "header_data_history.exp_time := %.10s\n", h->hist.exp_time);
00357   fprintf(fp, "header_data_history.hist_un0 := %.3s\n", h->hist.hist_un0);
00358   fprintf(fp, "header_data_history.views := %d\n", h->hist.views);
00359   fprintf(fp, "header_data_history.vols_added := %d\n", h->hist.vols_added);
00360   fprintf(fp, "header_data_history.start_field := %d\n", h->hist.start_field);
00361   fprintf(fp, "header_data_history.field_skip := %d\n", h->hist.field_skip);
00362   fprintf(fp, "header_data_history.omax := %d\n", h->hist.omax);
00363   fprintf(fp, "header_data_history.omin := %d\n", h->hist.omin);
00364   fprintf(fp, "header_data_history.smax := %d\n", h->hist.smax);
00365   fprintf(fp, "header_data_history.smin := %d\n", h->hist.smin);
00366 
00367   return(0);
00368 }
00369 /*****************************************************************************/
00370 
00371 /*****************************************************************************/
00381 int anaReadImagedata(FILE *fp, ANALYZE_DSR *h, int frame, float *data) {
00382   int dimNr, dimx, dimy, dimz=1, dimt=1, pxlNr=0;
00383   int i, n, little, start_pos, rawSize;
00384   char *mdata, *mptr;
00385   float f, *fptr;
00386   short int *sptr;
00387   int *iptr;
00388   double d;
00389 
00390 
00391   if(ANALYZE_TEST) printf("anaReadImagedata(fp, h, %d, data)\n", frame);
00392 
00393   /* Check the arguments */
00394   if(frame<=0 || fp==NULL || h==NULL || data==NULL) return(1);
00395 
00396   /* Get the image dimensions from header */
00397   dimNr=h->dime.dim[0]; if(dimNr<2) return(2);
00398   dimx=h->dime.dim[1];
00399   dimy=h->dime.dim[2];
00400   if(dimNr>2) dimz=h->dime.dim[3];
00401   if(dimNr>3) dimt=h->dime.dim[4]; if(frame>dimt) return(3);
00402   pxlNr=dimx*dimy*dimz; if(pxlNr<1) return(4);
00403 
00404   /* Allocate memory for the binary data */
00405   if(h->dime.bitpix<8) return(5); /* We don't support bit data */
00406   rawSize=pxlNr*(h->dime.bitpix/8); if(rawSize<1) return(5);
00407   if(ANALYZE_TEST>0) printf("  pxlNr=%d  rawSize=%d\n", pxlNr, rawSize);
00408   mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11);
00409 
00410   /* Seek the start of current frame data */
00411   start_pos=(frame-1)*rawSize;
00412   n=(int)h->dime.vox_offset; if((n>0 && frame==1) || (n<0)) start_pos+=abs(n);
00413   if(ANALYZE_TEST>2) printf("start_pos=%d\n", start_pos);
00414   fseek(fp, start_pos, SEEK_SET);
00415   if(ftell(fp)!=start_pos) {
00416     if(ANALYZE_TEST>5) printf("could not move to start_pos\n");
00417     free(mdata); return(7);
00418   }
00419 
00420   /* Read the data */
00421   mptr=mdata;
00422   if((n=fread(mptr, rawSize, 1, fp)) < 1) {
00423     if(ANALYZE_TEST>5)
00424       printf("could read only %d bytes when request was %d\n", n, rawSize);
00425     free(mdata); return(8);
00426   }
00427 
00428   /* Convert byte order if necessary */
00429   little=little_endian(); mptr=mdata;
00430   if(little!=h->little) {
00431     if(ANALYZE_TEST>0) printf("byte conversion\n");
00432     switch(h->dime.bitpix) {
00433       case 8: /* no conversion needed */ break;
00434       case 16: swabip(mptr, rawSize); break;
00435       case 32: swawbip(mptr, rawSize); break;
00436       case 64: swawbip(mptr, rawSize); break;
00437       default: 
00438         if(ANALYZE_TEST>5)
00439           printf("unsupported anahdr.dime.bitpix := %d\n", h->dime.bitpix);
00440         free(mdata); return(5);
00441     }
00442   }
00443 
00444   /* Get scale factor */
00445   f=1.0;
00446   if(h->dime.funused1>0.0) f*=h->dime.funused1;
00447 
00448   /* Copy data to float pixel values */
00449   mptr=mdata; fptr=data;
00450   switch(h->dime.datatype) {
00451     case ANALYZE_DT_UNSIGNED_CHAR:
00452       if(h->dime.bitpix!=8) {
00453         if(ANALYZE_TEST>5)
00454           printf("invalid combination of datatype and bitpix (%d, %d)\n",
00455             h->dime.datatype, h->dime.bitpix);
00456         free(mdata); return(5);
00457       }
00458       for(i=0; i<pxlNr; i++, mptr++, fptr++) *fptr=f*(float)(*mptr);
00459       break;
00460     case ANALYZE_DT_SIGNED_SHORT:
00461       if(h->dime.bitpix!=16) {
00462         if(ANALYZE_TEST>5)
00463           printf("invalid combination of datatype and bitpix (%d, %d)\n",
00464             h->dime.datatype, h->dime.bitpix);
00465         free(mdata); return(5);
00466       }
00467       for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
00468         sptr=(short int*)mptr; *fptr=f*(float)(*sptr);
00469       }
00470       break;
00471     case ANALYZE_DT_SIGNED_INT:
00472       if(h->dime.bitpix!=16 && h->dime.bitpix!=32) {
00473         if(ANALYZE_TEST>5)
00474           printf("invalid combination of datatype and bitpix (%d, %d)\n",
00475             h->dime.datatype, h->dime.bitpix);
00476         free(mdata); return(5);
00477       }
00478       if(h->dime.bitpix==16) {
00479         for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
00480           iptr=(int*)mptr; *fptr=f*(float)(*iptr);
00481         }
00482       } else if(h->dime.bitpix==32) {
00483         for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
00484           iptr=(int*)mptr; *fptr=f*(float)(*iptr);
00485         }
00486       }
00487       break;
00488     case ANALYZE_DT_FLOAT:
00489       if(h->dime.bitpix!=16 && h->dime.bitpix!=32) {
00490         if(ANALYZE_TEST>5)
00491           printf("invalid combination of datatype and bitpix (%d, %d)\n",
00492             h->dime.datatype, h->dime.bitpix);
00493         free(mdata); return(5);
00494       }
00495       if(h->dime.bitpix==16) {
00496         memcpy(fptr, mptr, pxlNr*4);
00497         for(i=0; i<pxlNr; i++, fptr++) *fptr*=f;
00498       } else if(h->dime.bitpix==32) {
00499         memcpy(fptr, mptr, pxlNr*4);
00500         for(i=0; i<pxlNr; i++, fptr++) *fptr*=f;
00501       }
00502       break;
00503     case ANALYZE_DT_COMPLEX:
00504       if(h->dime.bitpix!=32) {
00505         if(ANALYZE_TEST>5)
00506           printf("invalid combination of datatype and bitpix (%d, %d)\n",
00507             h->dime.datatype, h->dime.bitpix);
00508         free(mdata); return(5);
00509       }
00510       if(h->dime.bitpix==32) {
00511         memcpy(fptr, mptr, pxlNr*4);
00512         for(i=0; i<pxlNr; i++, fptr++) *fptr*=f;
00513       }
00514       break;
00515     case ANALYZE_DT_DOUBLE:
00516       if(h->dime.bitpix!=32) {
00517         if(ANALYZE_TEST>5)
00518           printf("invalid combination of datatype and bitpix (%d, %d)\n",
00519             h->dime.datatype, h->dime.bitpix);
00520         free(mdata); return(5);
00521       }
00522       for(i=0; i<pxlNr; i++, mptr+=8, fptr++) {
00523         memcpy(&d, mptr, 8); *fptr=f*d;
00524       }
00525       break;
00526     default:
00527       if(ANALYZE_TEST>5)
00528         printf("unsupported anahdr.dime.datatype := %d\n", h->dime.datatype);
00529       free(mdata); return(5);
00530   }
00531 
00532   free(mdata);
00533   if(ANALYZE_TEST>1) printf("anaReadImagedata() succeeded\n");
00534   return(0);
00535 }
00536 /*****************************************************************************/
00537 
00538 /*****************************************************************************/
00545 int anaFlipping() {
00546   int ret;
00547   char *cptr;
00548 
00549   /* Is there an environment variable name for flipping? */
00550   cptr=getenv("ANALYZE_FLIP");
00551   if(cptr==NULL) cptr=getenv("ANALYZE_FLIPPING");
00552   if(cptr==NULL) cptr=getenv("analyze_flip");
00553   if(cptr==NULL) cptr=getenv("analyze_flipping");
00554   if(cptr==NULL) {
00555     if(ANALYZE_TEST>1) printf("ANALYZE_FLIP = not defined\n");
00556     ret=ANALYZE_FLIP_DEFAULT; /* if not, then use default value */
00557   } else {
00558     if(ANALYZE_TEST>1) printf("ANALYZE_FLIP = '%s'\n", cptr);
00559     if(*cptr=='y' || *cptr=='Y' || *cptr=='1') ret=1;
00560     else if(*cptr=='n' || *cptr=='N' || *cptr=='0') ret=0;
00561     else ret=ANALYZE_FLIP_DEFAULT;
00562   }
00563   if(ANALYZE_TEST) printf("anaFlipping()=%d\n", ret);
00564   return(ret);
00565 }
00566 /*****************************************************************************/
00567 
00568 /*****************************************************************************/
00576 int anaRemove(const char *dbname) {
00577   char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
00578 
00579   if(ANALYZE_TEST) printf("anaRemove(%s)\n", dbname);
00580   if(anaDatabaseExists(dbname, hdrfile, datfile, siffile)==0) return 0;
00581   if(ANALYZE_TEST>2) printf("  removing %s and %s\n", hdrfile, datfile);
00582   if(remove(hdrfile)!=0) return 1;
00583   if(remove(datfile)!=0) return 2;
00584   return 0;
00585 }
00586 /*****************************************************************************/
00587 
00588 /*****************************************************************************/
00595 void anaRemoveFNameExtension(char *fname) {
00596   char *cptr;
00597   cptr=strrchr(fname, '.'); if(cptr==NULL) return;
00598   if(strcasecmp(cptr, ".")==0 || strcasecmp(cptr, ".img")==0 ||
00599      strcasecmp(cptr, ".hdr")==0 || strcasecmp(cptr, ".sif")==0)
00600   *cptr=(char)0;
00601 }
00602 /*****************************************************************************/
00603 
00604 /*****************************************************************************/
00619 int anaDatabaseExists(const char *dbname, char *hdrfile, char *imgfile, char *siffile) {
00620   char temp[FILENAME_MAX], database[FILENAME_MAX];
00621   int checked=0;
00622 
00623   if(ANALYZE_TEST)
00624     printf("\nanaDatabaseExists(%s, *hdrfile, *imgfile, *siffile)\n", dbname);
00625 
00626   /* Check the input */
00627   if(hdrfile!=NULL) strcpy(hdrfile, "");
00628   if(imgfile!=NULL) strcpy(imgfile, "");
00629   if(siffile!=NULL) strcpy(siffile, "");
00630   if(dbname==NULL || strlen(dbname)==0) return(0);
00631 
00632   strcpy(database, dbname);
00633   while(1) {
00634     /* Header file? */
00635     strcpy(temp, database); strcat(temp, ".hdr");
00636     if(access(temp, 0) != -1) {
00637       /* Also image file? */
00638       strcpy(temp, database); strcat(temp, ".img");
00639       if(access(temp, 0) != -1) {
00640         if(hdrfile!=NULL) sprintf(hdrfile, "%s.hdr", database);
00641         if(imgfile!=NULL) sprintf(imgfile, "%s.img", database);
00642         /* Even SIF? */
00643         if(anaMakeSIFName(database, temp)==0) { /* yes! */
00644           if(siffile!=NULL) strcpy(siffile, temp); return(2);
00645         }
00646         /* Image and header files did exist anyway */
00647         return(1);
00648       }
00649     }
00650     if(checked==1) break;
00651     /* Try to remove extension */
00652     anaRemoveFNameExtension(database);
00653     checked=1;
00654   } /* try again */
00655   return(0);
00656 }
00657 /*****************************************************************************/
00658 
00659 /*****************************************************************************/
00667 int anaMakeSIFName(const char *dbname, char *siffile) {
00668   if(dbname==NULL || siffile==NULL) return(1);
00669   sprintf(siffile, "%s.sif", dbname); if(access(siffile, 0) != -1) return(0);
00670   sprintf(siffile, "%s.SIF", dbname); if(access(siffile, 0) != -1) return(0);
00671   sprintf(siffile, "%s.img.sif", dbname); if(access(siffile, 0) != -1) return(0);
00672   sprintf(siffile, "%s.IMG.SIF", dbname); if(access(siffile, 0) != -1) return(0);
00673   sprintf(siffile, "%s.sif", dbname); return(2);
00674 }
00675 /*****************************************************************************/
00676 
00677 /*****************************************************************************/
00678