/*! * Writing ECAT 6.3 32-bit ints. * 32-bit int format is same in VAX and i386 * * @param bufi pointer to 4-byte long input (integer data) * @param bufo pointer to 4-byte long output * @param tovax 1 for VAX format * @param islittle 1 for little endian */ void ecat63wInt(int *bufi, void *bufo, int tovax, int islittle) { int i; /* Swap both words and bytes on SUN */ memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4); memcpy(bufo, &i, 4); }
/*! * Write ECAT 6.3 matrix data to a specified file position. * Data does not need to be allocated for full blocks. * Data must be represented in current machines byte order, and it is * always saved in big endian byte order. * Give also nr of pixels and byte size of one pixel. * * @param fp target file pointer * @param strtblk starting image block [>=1] * @param data pointer to data that is written * @param pxlNr number of items to be written [>=1] * @param pxlSize size of one data item in bytes [>=1] * @return 0 if ok, 1 invalid input, 2 failed to find starting block, * 3 failed to write data */ int ecat63WriteMatdata(FILE *fp, int strtblk, char *data, int pxlNr, int pxlSize) { unsigned char buf[MatBLKSIZE]; char *dptr; int i, blkNr, dataSize, byteNr; if(ECAT63_TEST) printf("ecat63WriteMatdata(fp, %d, data, %d, %d)\n", strtblk, pxlNr, pxlSize); if(fp==NULL || strtblk<1 || data==NULL || pxlNr<1 || pxlSize<1) return(1); memset(buf, 0, MatBLKSIZE); dataSize=pxlNr*pxlSize; if(dataSize<1) return(1); /* block nr taken by all pixels */ blkNr=(dataSize+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(1); if(ECAT63_TEST>1) printf(" blkNr=%d\n", blkNr); /* Search the place for writing */ fseek(fp, (strtblk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(strtblk-1)*MatBLKSIZE) return(2); /* Save blocks one at a time */ for(i=0, dptr=data; i<blkNr && dataSize>0; i++) { byteNr=(dataSize<MatBLKSIZE)?dataSize:MatBLKSIZE; memcpy(buf, dptr, byteNr); /* Change matrix byte order in big endian platforms */ if(!little_endian()) { if(pxlSize==2) swabip(buf, byteNr); else if(pxlSize==4) swawbip(buf, byteNr); } /* Write block */ if(fwrite(buf, 1, MatBLKSIZE, fp)!=MatBLKSIZE) return(3); /* Prepare for the next block */ dptr+=byteNr; dataSize-=byteNr; } /* next block */ return(0); }
/*! * Create a new ECAT 6.3 file and return file pointer * or NULL in case of an error. * If file exists, it is renamed as fname% if possible. * Directory list is written in big endian byte order. * * @param fname file name * @param h Ecat 6.3 main header * @return opened file pointer, or NULL in case of failure */ FILE *ecat63Create(const char *fname, ECAT63_mainheader *h) { FILE *fp; char tmp[FILENAME_MAX]; int buf[MatBLKSIZE/4]; if(ECAT63_TEST) printf("ecat63Create()\n"); /* Check the arguments */ if(fname==NULL || h==NULL) return(NULL); /* Check if file exists; backup, if necessary */ if(access(fname, 0) != -1) { strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION); if(access(tmp, 0) != -1) remove(tmp); if(ECAT63_TEST) printf("Renaming %s -> %s\n", fname, tmp); rename(fname, tmp); } /* Open file */ fp=fopen(fname, "wb+"); if(fp==NULL) return(fp); /* Write main header */ if(ecat63WriteMainheader(fp, h)) return(NULL); /* Construct an empty matrix list ; convert to little endian if necessary */ memset(buf, 0, MatBLKSIZE); buf[0]=31; buf[1]=2; if(!little_endian()) swawbip(buf, MatBLKSIZE); /* Write data buffer */ fseek(fp, (MatFirstDirBlk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(MatFirstDirBlk-1)*MatBLKSIZE) return(NULL); if(fwrite(buf, 4, MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(NULL); /* OK, then return file pointer */ return(fp); }
/*! * Reading and writing ECAT 6.3 32-bit ints. * 32-bit int format is same in VAX and i386 * * @param bufi pointer to 32-bit long data block * @param isvax 1 for VAX format * @param islittle 1 for littel endian * @return read data as interger number */ int ecat63rInt(void *bufi, int isvax, int islittle) { int i; /* Swap both words and bytes on SUN */ memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4); return(i); }
/*! * Writing ECAT 6.3 floats * * @param bufi pointer to 4-byte long input (float data) * @param bufo pointer to 4-byte long output * @param tovax 1 for VAX format * @param islittle 1 for little endian */ void ecat63wFloat(float *bufi, void *bufo, int tovax, int islittle) { unsigned int ul; memcpy(&ul, bufi, 4); if(ul==0) {memcpy(bufo, bufi, 4); return;} if(tovax) { /* If VAX format is needed */ ul+=(2L<<23); /* increase exp by 2 */ /* Swap words on i386 and bytes on SUN */ if(islittle) swawip(&ul, 4); else swabip(&ul, 4); } else { if(!islittle) swawbip(&ul, 4); /* Switch words and bytes on SUN */ } memcpy(bufo, &ul, 4); }
/*! * Reading ECAT 6.3 floats * * @param bufi pointer to 32-bit long data block * @param isvax 1 for VAX format * @param islittle 1 for little endian * @return read float value */ float ecat63rFloat(void *bufi, int isvax, int islittle) { union {unsigned int ul; float f;} t; memcpy(&t.ul, bufi, 4); if(t.ul==0) {return(0.0);} if(isvax) { /* if input is in VAX format */ /* Swap words on i386 and bytes on SUN */ if(islittle) swawip(&t.ul, 4); else swabip(&t.ul, 4); t.ul-=(2L<<23); /* subtract 2 from exp */ } else { /* input is in i386 format */ if(!islittle) swawbip(&t.ul, 4); /* Switch words and bytes on SUN */ } return(t.f); }
/*! * Read ECAT 6.3 matrix data and convert byte order if necessary * Remember to allocate memory for full blocks! * There are differences here when compared to ecat7.c * * @param fp file pointer from where data is read * @param strtblk starting block [>= 1] * @param blkNr number of block to be read [>= 0] * @param data pointer to block where data is read * @param dtype data type code * @return 0 if ok, 1 invalid input, 2 failed to read data, * 9 failed to find starting block from file, */ int ecat63ReadMatdata(FILE *fp, int strtblk, int blkNr, char *data, int dtype) { int i, n, little, err=0; char *cptr; float f; if(ECAT63_TEST) printf("ecat63ReadMatdata(fp, %d, %d, data, %d)\n", strtblk, blkNr, dtype); /* Check the arguments */ if(blkNr<=0 || strtblk<1 || data==NULL) return(1); /* Seek the first data block */ fseek(fp, (strtblk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(strtblk-1)*MatBLKSIZE) return(9); /* Read the data blocks */ if(fread(data, MatBLKSIZE, blkNr, fp) < blkNr) return(2); /* Translate data if necessary */ little=little_endian(); switch(dtype) { case BYTE_TYPE: /* byte format...no translation necessary */ break; case VAX_I2: /* byte conversion necessary on big endian platform */ if(!little) {cptr=data; swabip(cptr, blkNr*MatBLKSIZE);} break; case VAX_I4: for(i=0, cptr=data; i<blkNr*MatBLKSIZE; i+=4, cptr+=4) { n=ecat63rInt(cptr, 1, little); memcpy(cptr, &n, 4); } break; case VAX_R4: for(i=0, cptr=data; i<blkNr*MatBLKSIZE; i+=4, cptr+=4) { f=ecat63rFloat(cptr, 1, little); memcpy(cptr, &f, 4); } break; case IEEE_R4: /* IEEE float ; byte conversion necessary on big end platforms */ case SUN_I4: /* SUN int ; byte conversion necessary on big end platforms */ if(!little) swawbip(data, blkNr*MatBLKSIZE); break; case SUN_I2: /* SUN short ; byte conversion necessary on big end platforms */ if(!little) swabip(data, blkNr*MatBLKSIZE); break; default: /* if something else, for now think it as an error */ err=2; break; } return(err); }
int anaReadHeader(const char *filename, ANALYZE_DSR *h) { unsigned char buf1[ANALYZE_HEADER_KEY_SIZE]; unsigned char buf2[ANALYZE_HEADER_IMGDIM_SIZE]; unsigned char buf3[ANALYZE_HEADER_HISTORY_SIZE]; int little; /* 1 if current platform is little endian (i386), else 0 */ FILE *fp; int ret, nr, s1, s2, same_order; if(ANALYZE_TEST) printf("anaReadHeader(%s, *dsr)\n", filename); /* Check arguments */ if(strlen(filename)<1 || h==NULL) { printf("could not open file : %s, or the ANALYZE_DSR is not allocated", filename); return 1; } little = little_endian(); /* Open file */ fp=fopen(filename, "rb"); if(fp==NULL) { printf("could not open file : %s", filename); return 2; } /* Get file size */ nr=0; while((ret=fgetc(fp))!=EOF) nr++; rewind(fp); if(nr<1) { fclose(fp); return(3); } /* Read Analyze header key */ if(fread(buf1, ANALYZE_HEADER_KEY_SIZE, 1, fp)<1) return(3); /* Read Analyze header image dimension */ if(fread(buf2, ANALYZE_HEADER_IMGDIM_SIZE, 1, fp)<1) return(3); /* Read Analyze header image data history */ memset(buf3, 0, sizeof(data_history)); ret=fread(buf3, ANALYZE_HEADER_HISTORY_SIZE, 1, fp); if(ANALYZE_TEST>1 && ret<1) printf(" complete data_history not found.\n"); /* Close file */ fclose(fp); /* Compare file size from header contents to the calculated value */ /* to determine whether Analyze file is in little or big endian */ memcpy(&s1, buf1+0, 4); s2=s1; swawbip(&s2, 4); if( abs(s1 - nr) < abs(s2 - nr)) { same_order=1; } else { same_order=0; } if(ANALYZE_TEST>1) printf("same byte order: %d (s1=%d s2=%d nr=%d)\n", same_order, s1, s2, nr); if(same_order) h->little=little; else {if(little) h->little=0; else h->little=1;} /* Set key header structure contents */ if(!same_order) swawbip(buf1+0, 4); memcpy(&h->hk.sizeof_hdr, buf1+0, 4); memcpy(h->hk.data_type, buf1+4, 10); memcpy(h->hk.db_name, buf1+14, 18); if(!same_order) swawbip(buf1+32, 4); memcpy(&h->hk.extents, buf1+32, 4); if(!same_order) swabip(buf1+36, 2); memcpy(&h->hk.session_error, buf1+36, 2); memcpy(&h->hk.regular, buf1+38, 1); memcpy(&h->hk.hkey_un0, buf1+39, 1); /* Set image dimension header structure contents */ if(!same_order) swabip(buf2+0, 16); memcpy(h->dime.dim, buf2+0, 16); if(!same_order) swabip(buf2+16, 2); memcpy(&h->dime.unused8, buf2+16, 2); if(!same_order) swabip(buf2+18, 2); memcpy(&h->dime.unused9, buf2+18, 2); if(!same_order) swabip(buf2+20, 2); memcpy(&h->dime.unused10, buf2+20, 2); if(!same_order) swabip(buf2+22, 2); memcpy(&h->dime.unused11, buf2+22, 2); if(!same_order) swabip(buf2+24, 2); memcpy(&h->dime.unused12, buf2+24, 2); if(!same_order) swabip(buf2+26, 2); memcpy(&h->dime.unused13, buf2+26, 2); if(!same_order) swabip(buf2+28, 2); memcpy(&h->dime.unused14, buf2+28, 2); if(!same_order) swabip(buf2+30, 2); memcpy(&h->dime.datatype, buf2+30, 2); if(!same_order) swabip(buf2+32, 2); memcpy(&h->dime.bitpix, buf2+32, 2); if(!same_order) swabip(buf2+34, 2); memcpy(&h->dime.dim_un0, buf2+34, 2); if(!same_order) swawbip(buf2+36, 32); memcpy(h->dime.pixdim, buf2+36, 32); if(!same_order) swawbip(buf2+68, 4); memcpy(&h->dime.vox_offset, buf2+68, 4); if(!same_order) swawbip(buf2+72, 4); memcpy(&h->dime.funused1, buf2+72, 4); if(!same_order) swawbip(buf2+76, 4); memcpy(&h->dime.funused2, buf2+76, 4); if(!same_order) swawbip(buf2+80, 4); memcpy(&h->dime.funused3, buf2+80, 4); if(!same_order) swawbip(buf2+84, 4); memcpy(&h->dime.cal_max, buf2+84, 4); if(!same_order) swawbip(buf2+88, 4); memcpy(&h->dime.cal_min, buf2+88, 4); if(!same_order) swawbip(buf2+92, 4); memcpy(&h->dime.compressed, buf2+92, 4); if(!same_order) swawbip(buf2+96, 4); memcpy(&h->dime.verified, buf2+96, 4); if(!same_order) swawbip(buf2+100, 4); memcpy(&h->dime.glmax, buf2+100, 4); if(!same_order) swawbip(buf2+104, 4); memcpy(&h->dime.glmin, buf2+104, 4); /* Set data history header structure contents */ memcpy(h->hist.descrip, buf3+0, 80); memcpy(h->hist.aux_file, buf3+80, 24); memcpy(&h->hist.orient, buf3+104, 1); memcpy(h->hist.originator, buf3+105, 10); memcpy(h->hist.generated, buf3+115, 10); memcpy(h->hist.scannum, buf3+125, 10); memcpy(h->hist.patient_id, buf3+135, 10); memcpy(h->hist.exp_date, buf3+145, 10); memcpy(h->hist.exp_time, buf3+155, 10); memcpy(h->hist.hist_un0, buf3+165, 3); if(!same_order) swawbip(buf3+168, 4); memcpy(&h->hist.views, buf3+168, 4); if(!same_order) swawbip(buf3+172, 4); memcpy(&h->hist.vols_added, buf3+172, 4); if(!same_order) swawbip(buf3+176, 4); memcpy(&h->hist.start_field, buf3+176,4); if(!same_order) swawbip(buf3+180, 4); memcpy(&h->hist.field_skip, buf3+180, 4); if(!same_order) swawbip(buf3+184, 4); memcpy(&h->hist.omax, buf3+184, 4); if(!same_order) swawbip(buf3+188, 4); memcpy(&h->hist.omin, buf3+188, 4); if(!same_order) swawbip(buf3+192, 4); memcpy(&h->hist.smax, buf3+192, 4); if(!same_order) swawbip(buf3+196, 4); memcpy(&h->hist.smin, buf3+196, 4); /* Check header contents */ if(h->hk.extents!=16384 && h->hk.extents!=0) { if(ANALYZE_TEST>1) printf("hk.extents := %d\n", h->hk.extents); return(11); } if(h->hk.regular!='r') { if(ANALYZE_TEST>1) printf("hk.regular := %c\n", h->hk.regular); return(12); } return(0); }
int anaReadImagedata(const char *filename, const ANALYZE_DSR *h, int frame, char *data) { int dimNr, dimx, dimy, dimz=1, dimt=1, pxlNr=0; int i, n, little, start_pos, rawSize; char *mdata, *mptr; char *fptr; float f; short int *sptr; int *iptr; double d; FILE *fp; /* Open file */ fp=fopen(filename, "rb"); if(fp==NULL) { printf("could not open Image File: %s", filename); return 2; } if(ANALYZE_TEST) printf("anaReadImagedata(fp, h, %d, data)\n", frame); /* Check the arguments */ if(frame<=0 || h==NULL || data==NULL) { printf("frame must be positive integer, Analyze header filled and the data allocated"); return 1; } /* Get the image dimensions from header */ dimNr=h->dime.dim[0]; if(dimNr<2) return(2); dimx=h->dime.dim[1]; dimy=h->dime.dim[2]; if(dimNr>2) dimz=h->dime.dim[3]; if(dimNr>3) dimt=h->dime.dim[4]; if(frame>dimt) return(3); pxlNr=dimx*dimy*dimz; if(pxlNr<1) return(4); /* Allocate memory for the binary data */ if(h->dime.bitpix<8) return(5); /* We don't support bit data */ rawSize=pxlNr*(h->dime.bitpix/8); if(rawSize<1) return(5); if(ANALYZE_TEST>0) printf(" pxlNr=%d rawSize=%d\n", pxlNr, rawSize); mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11); /* Seek the start of current frame data */ start_pos=(frame-1)*rawSize; n=(int)h->dime.vox_offset; if((n>0 && frame==1) || (n<0)) start_pos+=abs(n); if(ANALYZE_TEST>2) printf("start_pos=%d\n", start_pos); fseek(fp, start_pos, SEEK_SET); if(ftell(fp)!=start_pos) { if(ANALYZE_TEST>5) printf("could not move to start_pos\n"); free(mdata); return(7); } /* Read the data */ mptr=mdata; if((n=fread(mptr, rawSize, 1, fp)) < 1) { if(ANALYZE_TEST>5) printf("could read only %d bytes when request was %d\n", n, rawSize); free(mdata); return(8); } /* Convert byte order if necessary */ little=little_endian(); mptr=mdata; if(little!=h->little) { if(ANALYZE_TEST>0) printf("byte conversion\n"); switch(h->dime.bitpix) { case 8: /* no conversion needed */ break; case 16: swabip(mptr, rawSize); break; case 32: swawbip(mptr, rawSize); break; case 64: swawbip(mptr, rawSize); break; default: if(ANALYZE_TEST>5) printf("unsupported anahdr.dime.bitpix := %d\n", h->dime.bitpix); free(mdata); return(5); } } /* Get scale factor */ f=1.0; if(h->dime.funused1>0.0) f*=h->dime.funused1; /* Copy data to float pixel values */ mptr=mdata; fptr=data; switch(h->dime.datatype) { case ANALYZE_DT_UNSIGNED_CHAR: if(h->dime.bitpix!=8) { if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n", h->dime.datatype, h->dime.bitpix); free(mdata); return(5); } for(i=0; i<pxlNr; i++, mptr++, fptr++) *fptr=f*(char)(*mptr); break; case ANALYZE_DT_SIGNED_SHORT: if(h->dime.bitpix!=16) { if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n", h->dime.datatype, h->dime.bitpix); free(mdata); return(5); } for(i=0; i<pxlNr; i++, mptr+=2, fptr++) { sptr=(short int*)mptr; *fptr=f*(float)(*sptr); } break; case ANALYZE_DT_SIGNED_INT: if(h->dime.bitpix!=16 && h->dime.bitpix!=32) { if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n", h->dime.datatype, h->dime.bitpix); free(mdata); return(5); } if(h->dime.bitpix==16) { for(i=0; i<pxlNr; i++, mptr+=4, fptr++) { iptr=(int*)mptr; *fptr=f*(float)(*iptr); } } else if(h->dime.bitpix==32) { for(i=0; i<pxlNr; i++, mptr+=4, fptr++) { iptr=(int*)mptr; *fptr=f*(float)(*iptr); } } break; case ANALYZE_DT_FLOAT: if(h->dime.bitpix!=16 && h->dime.bitpix!=32) { if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n", h->dime.datatype, h->dime.bitpix); free(mdata); return(5); } if(h->dime.bitpix==16) { memcpy(fptr, mptr, pxlNr*4); for(i=0; i<pxlNr; i++, fptr++) *fptr*=f; } else if(h->dime.bitpix==32) { memcpy(fptr, mptr, pxlNr*4); for(i=0; i<pxlNr; i++, fptr++) *fptr*=f; } break; case ANALYZE_DT_COMPLEX: if(h->dime.bitpix!=32) { if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n", h->dime.datatype, h->dime.bitpix); free(mdata); return(5); } if(h->dime.bitpix==32) { memcpy(fptr, mptr, pxlNr*4); for(i=0; i<pxlNr; i++, fptr++) *fptr*=f; } break; case ANALYZE_DT_DOUBLE: if(h->dime.bitpix!=32) { if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n", h->dime.datatype, h->dime.bitpix); free(mdata); return(5); } for(i=0; i<pxlNr; i++, mptr+=8, fptr++) { memcpy(&d, mptr, 8); *fptr=f*d; } break; default: if(ANALYZE_TEST>5) printf("unsupported anahdr.dime.datatype := %d\n", h->dime.datatype); free(mdata); return(5); } fclose(fp); free(mdata); if(ANALYZE_TEST>1) printf("anaReadImagedata() succeeded\n"); return(0); }
int anaWriteHeader( const char *filename, const ANALYZE_DSR *h ) { unsigned char buf1[ANALYZE_HEADER_KEY_SIZE]; unsigned char buf2[ANALYZE_HEADER_IMGDIM_SIZE]; unsigned char buf3[ANALYZE_HEADER_HISTORY_SIZE]; FILE *fp; int same_order, little; if(ANALYZE_TEST) printf("anaWriteHeader(%s, *dsr)\n", filename); /* Check arguments */ if(strlen(filename)<1 || h==NULL) return(1); little=little_endian(); if(little==h->little) same_order=1; else same_order=0; /* Copy header contents into buffers */ /* Header key */ memset(buf1, 0, ANALYZE_HEADER_KEY_SIZE); memcpy(buf1+0, &h->hk.sizeof_hdr, 4); if(!same_order) swawbip(buf1+0, 4); memcpy(buf1+4, &h->hk.data_type, 10); memcpy(buf1+14, &h->hk.db_name, 18); memcpy(buf1+32, &h->hk.extents, 4); if(!same_order) swawbip(buf1+32, 4); memcpy(buf1+36, &h->hk.session_error, 2); if(!same_order) swabip(buf1+36, 2); memcpy(buf1+38, &h->hk.regular, 1); memcpy(buf1+39, &h->hk.hkey_un0, 1); /* Image dimension */ memset(buf2, 0, ANALYZE_HEADER_IMGDIM_SIZE); memcpy(buf2+0, h->dime.dim, 16); if(!same_order) swabip(buf2+0, 16); memcpy(buf2+16, &h->dime.unused8, 2); if(!same_order) swabip(buf2+16, 2); memcpy(buf2+18, &h->dime.unused9, 2); if(!same_order) swabip(buf2+18, 2); memcpy(buf2+20, &h->dime.unused10, 2); if(!same_order) swabip(buf2+20, 2); memcpy(buf2+22, &h->dime.unused11, 2); if(!same_order) swabip(buf2+22, 2); memcpy(buf2+24, &h->dime.unused12, 2); if(!same_order) swabip(buf2+24, 2); memcpy(buf2+26, &h->dime.unused13, 2); if(!same_order) swabip(buf2+26, 2); memcpy(buf2+28, &h->dime.unused14, 2); if(!same_order) swabip(buf2+28, 2); memcpy(buf2+30, &h->dime.datatype, 2); if(!same_order) swabip(buf2+30, 2); memcpy(buf2+32, &h->dime.bitpix, 2); if(!same_order) swabip(buf2+32, 2); memcpy(buf2+34, &h->dime.dim_un0, 2); if(!same_order) swabip(buf2+34, 2); memcpy(buf2+36, h->dime.pixdim, 32); if(!same_order) swawbip(buf2+36, 32); memcpy(buf2+68, &h->dime.vox_offset, 4); if(!same_order) swawbip(buf2+68, 4); memcpy(buf2+72, &h->dime.funused1, 4); if(!same_order) swawbip(buf2+72, 4); memcpy(buf2+76, &h->dime.funused2, 4); if(!same_order) swawbip(buf2+76, 4); memcpy(buf2+80, &h->dime.funused3, 4); if(!same_order) swawbip(buf2+80, 4); memcpy(buf2+84, &h->dime.cal_max, 4); if(!same_order) swawbip(buf2+84, 4); memcpy(buf2+88, &h->dime.cal_min, 4); if(!same_order) swawbip(buf2+88, 4); memcpy(buf2+92, &h->dime.compressed, 4); if(!same_order) swawbip(buf2+92, 4); memcpy(buf2+96, &h->dime.verified, 4); if(!same_order) swawbip(buf2+96, 4); memcpy(buf2+100, &h->dime.glmax, 4); if(!same_order) swawbip(buf2+100, 4); memcpy(buf2+104, &h->dime.glmin, 4); if(!same_order) swawbip(buf2+104, 4); /* Data history */ memset(buf3, 0, ANALYZE_HEADER_HISTORY_SIZE); memcpy(buf3+0, &h->hist.descrip, 80); memcpy(buf3+80, &h->hist.aux_file, 24); memcpy(buf3+104, &h->hist.orient, 1); memcpy(buf3+105, &h->hist.originator, 10); memcpy(buf3+115, &h->hist.generated, 10); memcpy(buf3+125, &h->hist.scannum, 10); memcpy(buf3+135, &h->hist.patient_id, 10); memcpy(buf3+145, &h->hist.exp_date, 10); memcpy(buf3+155, &h->hist.exp_time, 10); memcpy(buf3+165, &h->hist.hist_un0, 3); memcpy(buf3+168, &h->hist.views, 4); if(!same_order) swawbip(buf3+168, 4); memcpy(buf3+172, &h->hist.vols_added,4); if(!same_order) swawbip(buf3+172, 4); memcpy(buf3+176, &h->hist.start_field,4); if(!same_order) swawbip(buf3+176,4); memcpy(buf3+180, &h->hist.field_skip,4); if(!same_order) swawbip(buf3+180, 4); memcpy(buf3+184, &h->hist.omax, 4); if(!same_order) swawbip(buf3+184, 4); memcpy(buf3+188, &h->hist.omin, 4); if(!same_order) swawbip(buf3+188, 4); memcpy(buf3+192, &h->hist.smax, 4); if(!same_order) swawbip(buf3+192, 4); memcpy(buf3+196, &h->hist.smin, 4); if(!same_order) swawbip(buf3+196, 4); /* Open header file for write */ fp=fopen(filename, "wb"); if(fp==NULL) return(2); /* Write header key */ if(fwrite(buf1, 1, ANALYZE_HEADER_KEY_SIZE, fp) != ANALYZE_HEADER_KEY_SIZE) { fclose(fp); return(3); } /* Write image dimension */ if(fwrite(buf2, 1, ANALYZE_HEADER_IMGDIM_SIZE, fp) != ANALYZE_HEADER_IMGDIM_SIZE) { fclose(fp); return(4); } /* Write data history */ if(fwrite(buf3, 1, ANALYZE_HEADER_HISTORY_SIZE, fp) != ANALYZE_HEADER_HISTORY_SIZE) { fclose(fp); return(5); } fclose(fp); return(0); }
/** Reads microPET image data, scaling values to floats if necessary. * Reads only one frame at a time! \returns 0 when successful, otherwise <>0. */ int upetReadImagedata( /** file opened previously in binary mode */ FILE *fp, /** microPET header in IFT struct */ IFT *ift, /** frame number to read [1..number of frames] */ int frame, /** pointer to image float data allocated previously */ float *data ) { int dimx, dimy, dimz=1, dimt=1, pxlNr=0; int i, fi, n, data_type, data_bytes, little, start_pos, rawSize; char *mdata, *mptr; float f, cf, bf, *fptr; short int *sptr; int *iptr; char key[MAX_MICROPET_LINE_LEN], value[MAX_MICROPET_LINE_LEN]; if(MICROPET_TEST) printf("upetReadImagedata(fp, ift, %d, data)\n", frame); /* Check the arguments */ if(frame<=0 || fp==NULL || ift==NULL || data==NULL) return(1); /* Get the image dimensions from header */ i=iftGetIntValue(ift, 0, "total_frames", &dimt); if(i<0 || dimt<1) return 4; i=iftGetIntValue(ift, 0, "x_dimension", &dimx); if(i<0 || dimx<1) return 4; i=iftGetIntValue(ift, 0, "y_dimension", &dimy); if(i<0 || dimy<1) return 4; i=iftGetIntValue(ift, 0, "z_dimension", &dimz); if(i<0 || dimz<1) return 4; pxlNr=dimx*dimy*dimz; if(pxlNr<1) return(4); if(frame>dimt) return(3); // do not change this return value /* Get the data type */ i=iftGetIntValue(ift, 0, "data_type", &data_type); if(i<0 || data_type<1) return 5; switch(data_type) { case 1: data_bytes=1; little=little_endian(); break; case 2: data_bytes=2; little=1; break; case 3: data_bytes=4; little=1; break; case 4: data_bytes=4; little=1; break; case 5: data_bytes=4; little=0; break; case 6: data_bytes=2; little=0; break; case 7: data_bytes=4; little=0; break; default: return 5; } rawSize=data_bytes*pxlNr; if(MICROPET_TEST>0) { printf(" data_type=%d\n data_bytes=%d\n", data_type, data_bytes); printf(" pxlNr=%d\n rawSize=%d\n", pxlNr, rawSize); } /* Allocate memory for the binary data */ mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11); /* Seek the start of current frame data */ start_pos=(frame-1)*rawSize; if(MICROPET_TEST>2) printf(" start_pos=%d\n", start_pos); fseek(fp, start_pos, SEEK_SET); if(ftell(fp)!=start_pos) { if(MICROPET_TEST>5) printf("could not move to start_pos\n"); free(mdata); return(7); } /* Read the data */ mptr=mdata; if((n=fread(mptr, rawSize, 1, fp)) < 1) { if(MICROPET_TEST>5) printf("could read only %d bytes when request was %d\n", n, rawSize); free(mdata); return(8); } /* Convert byte order if necessary */ mptr=mdata; if(little!=little_endian()) { if(MICROPET_TEST>0) {printf("byte conversion\n"); fflush(stdout);} switch(data_bytes) { case 1: /* no conversion needed */ break; case 2: swabip(mptr, rawSize); break; case 4: swawbip(mptr, rawSize); break; default: if(MICROPET_TEST>5) printf("unsupported data_type := %d\n", data_type); free(mdata); return(5); } } /* Get scale factor for this frame */ strcpy(key, "frame"); sprintf(value, "%d", frame-1); fi=iftGetFullmatchFrom(ift, 0, key, value); if(fi<0) {free(mdata); return(6);} i=iftGetFloatValue(ift, fi+1, "scale_factor", &f); if(i<0 || f<=0.0) {free(mdata); return(6);} if(MICROPET_TEST>5) printf(" scale_factor := %g\n", f); /* calibration factor */ i=iftGetFloatValue(ift, 0, "calibration_factor", &cf); if(i<0 || cf<0.0) {free(mdata); return 7;} if(MICROPET_TEST>5) printf(" calibration_factor := %g\n", cf); /* branching_fraction */ i=iftGetFloatValue(ift, 0, "isotope_branching_fraction", &bf); if(i<0 || bf<0.0) {free(mdata); return 7;} if(MICROPET_TEST>5) printf(" branching_fraction := %g\n", bf); if(cf>0.0) {f=cf; if(bf>0.0) f/=bf;} if(MICROPET_TEST>5) printf(" f := %g\n", f); /* Copy data to float pixel values */ mptr=mdata; fptr=data; switch(data_type) { case 1: // unsigned char for(i=0; i<pxlNr; i++, mptr++, fptr++) *fptr=f*(float)(*mptr); break; case 2: // short int case 6: for(i=0; i<pxlNr; i++, mptr+=2, fptr++) { sptr=(short int*)mptr; *fptr=f*(float)(*sptr); } break; case 3: // int case 7: for(i=0; i<pxlNr; i++, mptr+=4, fptr++) { iptr=(int*)mptr; *fptr=f*(float)(*iptr); } break; case 4: // float case 5: memcpy(fptr, mptr, pxlNr*data_bytes); for(i=0; i<pxlNr; i++, fptr++) *fptr*=f; break; default: if(MICROPET_TEST>5) printf("unsupported data_type := %d\n", data_type); free(mdata); return(5); } free(mdata); if(MICROPET_TEST>1) printf("anaReadImagedata() succeeded\n"); return(0); }