TPCCLIB
Loading...
Searching...
No Matches
libtpcimgio.h File Reference

Header file for libtpcimgio. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <strings.h>
#include <ctype.h>
#include <float.h>
#include <unistd.h>
#include <locale.h>
#include <time.h>
#include "libtpcmisc.h"

Go to the source code of this file.

Data Structures

struct  ANALYZE_HEADER_KEY
 
struct  ANALYZE_HEADER_IMGDIM
 
struct  ANALYZE_HEADER_HISTORY
 
struct  ANALYZE_DSR
 
struct  ECAT7_mainheader
 
struct  ECAT7_imageheader
 
struct  ECAT7_scanheader
 
struct  ECAT7_2Dscanheader
 
struct  ECAT7_2Dnormheader
 
struct  ECAT7_attenheader
 
struct  ECAT7_normheader
 
struct  ECAT7_polmapheader
 
struct  ECAT7_MatDir
 
struct  ECAT7_MATRIXLIST
 
struct  ECAT7_Matval
 
struct  MatDir
 
struct  MATRIXLIST
 
struct  Matval
 
struct  ECAT63_mainheader
 
struct  ECAT63_imageheader
 
struct  ECAT63_scanheader
 
struct  ECAT63_normheader
 
struct  ECAT63_attnheader
 
struct  MatDirNode
 
struct  MatDirList
 
struct  MatrixData
 
struct  Matrix_file
 
struct  SIF
 
struct  IMG_PIXEL
 
struct  IMG_PIXELS
 
struct  IMG_RANGE
 
struct  VOXEL_4D
 
struct  IMG
 
struct  VOL_PIXEL
 
struct  VOL_RANGE
 
struct  VOL
 
struct  SVOL
 
struct  NIFTI_1_HEADER
 
struct  NIFTI_EXTENDER
 
struct  NIFTI_DSR
 
struct  ECAT_MATRIX
 
struct  ECAT_HEADERS
 
struct  DCMTAG
 
struct  DCMITEM
 
struct  DCMFILE
 
struct  DCMMATRIX
 
struct  DCMML
 

Macros

#define BACKUP_EXTENSION   ".bak"
 
#define ANALYZE_DT_NONE   0
 
#define ANALYZE_DT_UNKNOWN   0
 
#define ANALYZE_DT_BINARY   1
 
#define ANALYZE_DT_UNSIGNED_CHAR   2
 
#define ANALYZE_DT_SIGNED_SHORT   4
 
#define ANALYZE_DT_SIGNED_INT   8
 
#define ANALYZE_DT_FLOAT   16
 
#define ANALYZE_DT_COMPLEX   32
 
#define ANALYZE_DT_DOUBLE   64
 
#define ANALYZE_DT_RGB   128
 
#define ANALYZE_DT_ALL   255
 
#define MatBLKSIZE   512
 
#define MatFirstDirBlk   2
 
#define ECAT7_BYTE   1
 
#define ECAT7_VAXI2   2
 
#define ECAT7_VAXI4   3
 
#define ECAT7_VAXR4   4
 
#define ECAT7_IEEER4   5
 
#define ECAT7_SUNI2   6
 
#define ECAT7_SUNI4   7
 
#define M68K_I2   SUN_I2
 
#define M68K_I4   SUN_I4
 
#define ECAT7_UNKNOWN   0
 
#define ECAT7_2DSCAN   1
 
#define ECAT7_IMAGE16   2
 
#define ECAT7_ATTEN   3
 
#define ECAT7_2DNORM   4
 
#define ECAT7_POLARMAP   5
 
#define ECAT7_VOLUME8   6
 
#define ECAT7_VOLUME16   7
 
#define ECAT7_PROJ   8
 
#define ECAT7_PROJ16   9
 
#define ECAT7_IMAGE8   10
 
#define ECAT7_3DSCAN   11
 
#define ECAT7_3DSCAN8   12
 
#define ECAT7_3DNORM   13
 
#define ECAT7_3DSCANFIT   14
 
#define ECAT7_Feet_First_Prone   0
 
#define ECAT7_Head_First_Prone   1
 
#define ECAT7_Feet_First_Supine   2
 
#define ECAT7_Head_First_Supine   3
 
#define ECAT7_Feet_First_Decubitus_Right   4
 
#define ECAT7_Head_First_Decubitus_Right   5
 
#define ECAT7_Feet_First_Decubitus_Left   6
 
#define ECAT7_Head_First_Decubitus_Left   7
 
#define ECAT7_Unknown_Orientation   8
 
#define MatBLKSIZE   512
 
#define MatFirstDirBlk   2
 
#define BYTE_TYPE   1
 
#define VAX_I2   2
 
#define VAX_I4   3
 
#define VAX_R4   4
 
#define IEEE_R4   5
 
#define SUN_I2   6
 
#define SUN_I4   7
 
#define RAW_DATA   1
 
#define IMAGE_DATA   2
 
#define ATTN_DATA   3
 
#define NORM_DATA   4
 
#define ECAT63_SYSTEM_TYPE_DEFAULT   931
 
#define IMG_STATUS_UNINITIALIZED   0
 
#define IMG_STATUS_INITIALIZED   1
 
#define IMG_STATUS_OCCUPIED   2
 
#define IMG_STATUS_ERROR   3
 
#define IMG_ERR_OK   0
 
#define IMG_ERR_CALLING   1
 
#define IMG_ERR_OOM   2
 
#define IMG_TYPE_UNKNOWN   0
 
#define IMG_TYPE_IMAGE   1
 
#define IMG_TYPE_RAW   2
 
#define IMG_TYPE_POLARMAP   3
 
#define IMG_TYPE_ATTN   4
 
#define IMG_UNKNOWN   0
 
#define IMG_E63   1
 
#define IMG_E7   2
 
#define IMG_E7_2D   3
 
#define IMG_POLARMAP   9
 
#define IMG_ANA   11
 
#define IMG_ANA_L   12 /* little endian variant */
 
#define IMG_INTERFILE   21
 
#define IMG_NIFTI_1D   31 /* dual file format */
 
#define IMG_NIFTI_1S   32 /* single file format */
 
#define IMG_MICROPET   41
 
#define IMG_FLAT   61
 
#define IMG_DICOM   100
 
#define IMG_DC_UNKNOWN   0
 
#define IMG_DC_CORRECTED   1
 
#define IMG_DC_NONCORRECTED   2
 
#define IMG_MODALITY_UNKNOWN   0
 
#define IMG_MODALITY_PET   1
 
#define IMG_MODALITY_MRI   2
 
#define IMG_MODALITY_CT   3
 
#define IMG_MODALITY_SPECT   4
 
#define SCANNER_UNKNOWN   0
 
#define SCANNER_ECAT931   12
 
#define SCANNER_ADVANCE   12096
 
#define SCANNER_HRPLUS   3
 
#define SCANNER_HRRT   4
 
#define SCANNER_MRI   5
 
#define SCANNER_STEVCT_PET   6
 
#define SCANNER_STEVCT_CT   7
 
#define SCANNER_DMI_PET   8
 
#define SCANNER_PRIMATE   2000
 
#define SCANNER_RODENT   2001
 
#define SCANNER_MICROPET2   2002
 
#define SCANNER_FOCUS_220   2500
 
#define SCANNER_FOCUS_120   2501
 
#define SCANNER_INVEON_DEDICATED_PET   5000
 
#define SCANNER_INVEON_MM_PET   5500
 
#define SCANNER_MR_PET_HEAD_INSERT   6000
 
#define SCANNER_TUEBINGEN_PET_MR   8000
 
#define MAX_POLARMAP_NUM_RINGS   32
 
#define MAX_MICROPET_LINE_LEN   1024
 
#define NIFTI_HEADER_SIZE   348
 
#define NIFTI_HEADER_EXTENDER_SIZE   4
 
#define NIFTI_UNITS_UNKNOWN   0
 
#define NIFTI_UNITS_METER   1
 
#define NIFTI_UNITS_MM   2
 
#define NIFTI_UNITS_MICRON   4
 
#define NIFTI_UNITS_SEC   8
 
#define NIFTI_UNITS_MSEC   16
 
#define NIFTI_UNITS_USEC   24
 
#define NIFTI_UNITS_HERTZ   32
 
#define NIFTI_UNITS_PPM   40
 
#define NIFTI_UNITS_RADS   48
 
#define NIFTI_DT_NONE   0
 
#define NIFTI_DT_UNKNOWN   0
 
#define NIFTI_DT_BINARY   1
 
#define NIFTI_DT_UNSIGNED_CHAR   2
 
#define NIFTI_DT_SIGNED_SHORT   4
 
#define NIFTI_DT_SIGNED_INT   8
 
#define NIFTI_DT_FLOAT   16
 
#define NIFTI_DT_COMPLEX   32
 
#define NIFTI_DT_DOUBLE   64
 
#define NIFTI_DT_RGB   128
 
#define NIFTI_DT_ALL   255
 
#define NIFTI_DT_SIGNED_CHAR   256
 
#define NIFTI_DT_UNSIGNED_SHORT   512
 
#define NIFTI_DT_UNSIGNED_INT   768
 
#define NIFTI_DT_LONG_LONG   1024
 
#define NIFTI_DT_UNSIGNED_LONG_LONG   1280
 
#define NIFTI_DT_LONG_DOUBLE   1536
 
#define NIFTI_DT_DOUBLE_PAIR   1792
 
#define NIFTI_DT_LONG_DOUBLE_PAIR   2048
 
#define NIFTI_DT_RGBA   2304
 
#define NIFTI_INTENT_NONE   0
 
#define NIFTI_INTENT_CORREL   2
 
#define NIFTI_INTENT_TTEST   3
 
#define NIFTI_INTENT_FTEST   4
 
#define NIFTI_INTENT_ZSCORE   5
 
#define NIFTI_INTENT_CHISQ   6
 
#define NIFTI_INTENT_BETA   7
 
#define NIFTI_INTENT_BINOM   8
 
#define NIFTI_INTENT_GAMMA   9
 
#define NIFTI_INTENT_POISSON   10
 
#define NIFTI_INTENT_NORMAL   11
 
#define NIFTI_INTENT_FTEST_NONC   12
 
#define NIFTI_INTENT_CHISQ_NONC   13
 
#define NIFTI_INTENT_LOGISTIC   14
 
#define NIFTI_INTENT_LAPLACE   15
 
#define NIFTI_INTENT_UNIFORM   16
 
#define NIFTI_INTENT_TTEST_NONC   17
 
#define NIFTI_INTENT_WEIBULL   18
 
#define NIFTI_INTENT_CHI   19
 
#define NIFTI_INTENT_INVGAUSS   20
 
#define NIFTI_INTENT_EXTVAL   21
 
#define NIFTI_INTENT_PVAL   22
 
#define NIFTI_INTENT_LOGPVAL   23
 
#define NIFTI_INTENT_LOG10PVAL   24
 
#define NIFTI_INTENT_ESTIMATE   1001
 
#define NIFTI_INTENT_LABEL   1002
 
#define NIFTI_INTENT_NEURONAME   1003
 
#define NIFTI_INTENT_GENMATRIX   1004
 
#define NIFTI_INTENT_SYMMATRIX   1005
 
#define NIFTI_INTENT_DISPVECT   1006
 
#define NIFTI_INTENT_VECTOR   1007
 
#define NIFTI_INTENT_POINTSET   1008
 
#define NIFTI_INTENT_TRIANGLE   1009
 
#define NIFTI_INTENT_QUATERNION   1010
 
#define NIFTI_INTENT_DIMLESS   1011
 
#define NIFTI_XFORM_UNKNOWN   0
 
#define NIFTI_XFORM_SCANNER_ANAT   1
 
#define NIFTI_XFORM_ALIGNED_ANAT   2
 
#define NIFTI_XFORM_TALAIRACH   3
 
#define NIFTI_XFORM_MNI_152   4
 

Enumerations

enum  {
  STATUS_OK , STATUS_FAULT , STATUS_NOMEMORY , STATUS_NOFILE ,
  STATUS_UNKNOWNFORMAT , STATUS_UNSUPPORTED , STATUS_MISSINGMATRIX , STATUS_NOWRITEPERM ,
  STATUS_DISKFULL , STATUS_NOMATLIST , STATUS_INVALIDMATLIST , STATUS_VARMATSIZE ,
  STATUS_NOMAINHEADER , STATUS_NOSUBHEADER , STATUS_NOMATRIX , STATUS_UNSUPPORTEDAXIALCOMP ,
  STATUS_NOIMGDATAFILE , STATUS_NOHEADERFILE , STATUS_INVALIDHEADER , STATUS_NOIMGDATA ,
  STATUS_NOSIFDATA , STATUS_WRONGSIFDATA , STATUS_CANTWRITEIMGFILE , STATUS_CANTWRITEHEADERFILE ,
  STATUS_WRONGFILETYPE , STATUS_CANNOTERASE , STATUS_CANNOTREAD , STATUS_CANNOTWRITE ,
  STATUS_UNSUPPORTEDPOLARMAP , STATUS_INVALIDPOLARMAP
}
 
enum  dcmtruid {
  DCM_TRUID_UNKNOWN , DCM_TRUID_LEI , DCM_TRUID_LEE , DCM_TRUID_BEE ,
  DCM_TRUID_JPEG50 , DCM_TRUID_JPEG51 , DCM_TRUID_JPEG70 , DCM_TRUID_JPEG80 ,
  DCM_TRUID_JPEG81 , DCM_TRUID_JPEG90 , DCM_TRUID_JPEG91 , DCM_TRUID_JPEG92 ,
  DCM_TRUID_JPEG93 , DCM_TRUID_MPEG100 , DCM_TRUID_MPEG102 , DCM_TRUID_MPEG103 ,
  DCM_TRUID_RLE , DCM_TRUID_RFC , DCM_TRUID_XML , DCM_TRUID_INVALID
}
 
enum  dcmvr {
  DCM_VR_AE , DCM_VR_AS , DCM_VR_AT , DCM_VR_CS ,
  DCM_VR_DA , DCM_VR_DS , DCM_VR_DT , DCM_VR_FL ,
  DCM_VR_FD , DCM_VR_IS , DCM_VR_LO , DCM_VR_LT ,
  DCM_VR_OB , DCM_VR_OD , DCM_VR_OF , DCM_VR_OL ,
  DCM_VR_OW , DCM_VR_PN , DCM_VR_SH , DCM_VR_SL ,
  DCM_VR_SQ , DCM_VR_SS , DCM_VR_ST , DCM_VR_TM ,
  DCM_VR_UC , DCM_VR_UI , DCM_VR_UL , DCM_VR_UN ,
  DCM_VR_UR , DCM_VR_US , DCM_VR_UT , DCM_VR_INVALID
}
 

Functions

int anaExists (const char *dbname)
 
int anaExistsNew (const char *dbname, char *hdrfile, char *imgile, char *siffile)
 
int anaRemove (const char *dbname)
 
void anaRemoveFNameExtension (char *fname)
 
int anaDatabaseExists (const char *dbname, char *hdrfile, char *imgfile, char *siffile)
 
int anaMakeSIFName (const char *dbname, char *siffile)
 
int anaFlipping ()
 
int anaReadHeader (char *filename, ANALYZE_DSR *h)
 
int anaReadImagedata (FILE *fp, ANALYZE_DSR *h, int frame, float *data)
 
int anaWriteHeader (char *filename, ANALYZE_DSR *h)
 
int anaPrintHeader (ANALYZE_DSR *h, FILE *fp)
 
int anaEditHeader (ANALYZE_DSR *h, char *field, char *value)
 
int ecat7ReadMainheader (FILE *fp, ECAT7_mainheader *h)
 
int ecat7ReadImageheader (FILE *fp, int blk, ECAT7_imageheader *h)
 
int ecat7ReadAttenheader (FILE *fp, int blk, ECAT7_attenheader *h)
 
int ecat7ReadPolmapheader (FILE *fp, int blk, ECAT7_polmapheader *h)
 
int ecat7ReadNormheader (FILE *fp, int blk, ECAT7_normheader *h)
 
int ecat7ReadScanheader (FILE *fp, int blk, ECAT7_scanheader *h)
 
int ecat7Read2DScanheader (FILE *fp, int blk, ECAT7_2Dscanheader *h)
 
int ecat7Read2DNormheader (FILE *fp, int blk, ECAT7_2Dnormheader *h)
 
int ecat7ReadMatrixdata (FILE *fp, int start_block, int block_nr, char *data, int dtype)
 
float ecat7rFloat (void *bufi, int isvax, int islittle)
 
int ecat7rInt (void *bufi, int isvax, int islittle)
 
int ecat7ReadImageMatrix (FILE *fp, int first_block, int last_block, ECAT7_imageheader *h, float **fdata)
 
int ecat7Read2DScanMatrix (FILE *fp, int first_block, int last_block, ECAT7_2Dscanheader *h, float **fdata)
 
int ecat7ReadScanMatrix (FILE *fp, int first_block, int last_block, ECAT7_scanheader *h, float **fdata)
 
int ecat7ReadPolarmapMatrix (FILE *fp, int first_block, int last_block, ECAT7_polmapheader *h, float **fdata)
 
int ecat7pxlbytes (short int data_type)
 
void ecat7InitMatlist (ECAT7_MATRIXLIST *mlist)
 
void ecat7EmptyMatlist (ECAT7_MATRIXLIST *mlist)
 
int ecat7ReadMatlist (FILE *fp, ECAT7_MATRIXLIST *ml, int verbose)
 
void ecat7PrintMatlist (ECAT7_MATRIXLIST *ml)
 
int ecat7EnterMatrix (FILE *fp, int matrix_id, int block_nr)
 
int ecat7_val_to_id (int frame, int plane, int gate, int data, int bed)
 
void ecat7_id_to_val (int matrix_id, ECAT7_Matval *matval)
 
void ecat7SortMatlistByPlane (ECAT7_MATRIXLIST *ml)
 
void ecat7SortMatlistByFrame (ECAT7_MATRIXLIST *ml)
 
int ecat7CheckMatlist (ECAT7_MATRIXLIST *ml)
 
int ecat7DeleteLateFrames (ECAT7_MATRIXLIST *ml, int frame_nr)
 
int ecat7GetPlaneAndFrameNr (ECAT7_MATRIXLIST *mlist, ECAT7_mainheader *h, int *plane_nr, int *frame_nr)
 
int ecat7GetMatrixBlockSize (ECAT7_MATRIXLIST *mlist, int *blk_nr)
 
int ecat7GetNums (ECAT7_MATRIXLIST *ml, ECAT7_mainheader *mh, FILE *fp, short int *num_planes, short int *num_frames, short int *num_gates, short int *num_bed_pos)
 
int ecat7GatherMatlist (ECAT7_MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)
 
int ecat7WriteMainheader (FILE *fp, ECAT7_mainheader *h)
 
int ecat7WriteImageheader (FILE *fp, int blk, ECAT7_imageheader *h)
 
int ecat7WriteAttenheader (FILE *fp, int blk, ECAT7_attenheader *h)
 
int ecat7WritePolmapheader (FILE *fp, int blk, ECAT7_polmapheader *h)
 
int ecat7WriteNormheader (FILE *fp, int blk, ECAT7_normheader *h)
 
int ecat7WriteScanheader (FILE *fp, int blk, ECAT7_scanheader *h)
 
int ecat7Write2DScanheader (FILE *fp, int blk, ECAT7_2Dscanheader *h)
 
int ecat7Write2DNormheader (FILE *fp, int blk, ECAT7_2Dnormheader *h)
 
int ecat7WritePolarmapMatrix (FILE *fp, int matrix_id, ECAT7_polmapheader *h, float *fdata)
 
int ecat7WriteMatrixdata (FILE *fp, int start_block, char *data, long long pxl_nr, int pxl_size)
 
FILE * ecat7Create (const char *fname, ECAT7_mainheader *h)
 
int ecat7WriteImageMatrix (FILE *fp, int matrix_id, ECAT7_imageheader *h, float *fdata)
 
int ecat7Write2DScanMatrix (FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata)
 
int ecat7WriteScanMatrix (FILE *fp, int matrix_id, ECAT7_scanheader *h, float *fdata)
 
int ecat7_is_scaling_needed (float amax, float *data, long long nr)
 
void ecat7PrintMainheader (ECAT7_mainheader *h, FILE *fp)
 
void ecat7PrintImageheader (ECAT7_imageheader *h, FILE *fp)
 
void ecat7PrintScanheader (ECAT7_scanheader *h, FILE *fp)
 
void ecat7PrintAttenheader (ECAT7_attenheader *h, FILE *fp)
 
void ecat7PrintPolmapheader (ECAT7_polmapheader *h, FILE *fp)
 
void ecat7PrintNormheader (ECAT7_normheader *h, FILE *fp)
 
void ecat7Print2DScanheader (ECAT7_2Dscanheader *h, FILE *fp)
 
void ecat7Print2DNormheader (ECAT7_2Dnormheader *h, FILE *fp)
 
int ecat7PrintSubheader (ECAT7_mainheader mh, FILE *fp, int plane, int frame, FILE *ofp)
 
char * ecat7filetype (short int file_type)
 
char * ecat7acquisitiontype (short int acquisition_type)
 
char * ecat7datatype (short int data_type)
 
int ecat7EditMHeader (ECAT7_mainheader *h, char *field, char *value, int verbose)
 
int ecat7EditSHeader (ECAT7_scanheader *h, char *field, char *value, int verbose)
 
int ecat7EditVHeader (ECAT7_imageheader *h, char *field, char *value, int verbose)
 
int ecat63ReadMainheader (FILE *fp, ECAT63_mainheader *h)
 
int ecat63ReadImageheader (FILE *fp, int blk, ECAT63_imageheader *h, int verbose, char *errmsg)
 
int ecat63ReadScanheader (FILE *fp, int blk, ECAT63_scanheader *h, int verbose, char *errmsg)
 
int ecat63ReadAttnheader (FILE *fp, int blk, ECAT63_attnheader *h, int verbose, char *errmsg)
 
int ecat63ReadNormheader (FILE *fp, int blk, ECAT63_normheader *h, int verbose, char *errmsg)
 
int ecat63ReadMatdata (FILE *fp, int strtblk, int blkNr, char *data, int dtype)
 
int ecat63ReadImageMatrix (FILE *fp, int strtblk, int lastblk, ECAT63_imageheader *h, float **f)
 
int ecat63ReadScanMatrix (FILE *fp, int strtblk, int lastblk, ECAT63_scanheader *h, float **f)
 
int ecat63ReadAttnMatrix (FILE *fp, int strtblk, int lastblk, ECAT63_attnheader *h, float **f)
 
float ecat63rFloat (void *bufi, int isvax, int islittle)
 
int ecat63rInt (void *bufi, int isvax, int islittle)
 
int ecat63pxlbytes (short int data_type)
 
void ecat63InitMatlist (MATRIXLIST *mlist)
 
void ecat63EmptyMatlist (MATRIXLIST *mlist)
 
int ecat63ReadMatlist (FILE *fp, MATRIXLIST *ml, int verbose)
 
void ecat63PrintMatlist (MATRIXLIST *ml)
 
int mat_numcod (int frame, int plane, int gate, int data, int bed)
 
void mat_numdoc (int matnum, Matval *matval)
 
int ecat63Matenter (FILE *fp, int matnum, int blkNr)
 
void ecat63SortMatlistByPlane (MATRIXLIST *ml)
 
void ecat63SortMatlistByFrame (MATRIXLIST *ml)
 
int ecat63CheckMatlist (MATRIXLIST *ml)
 
int ecat63DeleteLateFrames (MATRIXLIST *ml, int frame_nr)
 
int ecat63GetMatrixBlockSize (MATRIXLIST *mlist, int *blk_nr)
 
int ecat63GetPlaneAndFrameNr (MATRIXLIST *mlist, ECAT63_mainheader *h, int *plane_nr, int *frame_nr)
 
int ecat63GetNums (MATRIXLIST *ml, short int *num_planes, short int *num_frames, short int *num_gates, short int *num_bed_pos)
 
int ecat63GatherMatlist (MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)
 
int ecat63WriteMainheader (FILE *fp, ECAT63_mainheader *h)
 
int ecat63WriteImageheader (FILE *fp, int block, ECAT63_imageheader *h)
 
int ecat63WriteScanheader (FILE *fp, int block, ECAT63_scanheader *h)
 
int ecat63WriteAttnheader (FILE *fp, int block, ECAT63_attnheader *h)
 
int ecat63WriteNormheader (FILE *fp, int block, ECAT63_normheader *h)
 
FILE * ecat63Create (const char *fname, ECAT63_mainheader *h)
 
int ecat63WriteMatdata (FILE *fp, int strtblk, char *data, long long pxlNr, int pxlSize)
 
int ecat63WriteScan (FILE *fp, int matnum, ECAT63_scanheader *h, void *data)
 
int ecat63WriteImage (FILE *fp, int matnum, ECAT63_imageheader *h, void *data)
 
int ecat63WriteNorm (FILE *fp, int matnum, ECAT63_normheader *h, void *data)
 
int ecat63WriteAttn (FILE *fp, int matnum, ECAT63_attnheader *h, void *data)
 
int ecat63WriteImageMatrix (FILE *fp, int matnum, ECAT63_imageheader *h, float *fdata)
 
int ecat63WriteScanMatrix (FILE *fp, int matnum, ECAT63_scanheader *h, float *fdata)
 
void ecat63wFloat (float *bufi, void *bufo, int tovax, int islittle)
 
void ecat63wInt (int *bufi, void *bufo, int tovax, int islittle)
 
int ecat63_is_scaling_needed (float amax, float *data, long long nr)
 
struct tm * ecat63ScanstarttimeToTm (const ECAT63_mainheader *h, struct tm *tm)
 Convert scan_start_time in ECAT 6.3 main header into a struct tm.
 
time_t ecat63Scanstarttime (const ECAT63_mainheader *h)
 Get calendar time from ECAT 6.3 main header.
 
void ecat63PrintMainheader (ECAT63_mainheader *h, FILE *fp)
 
void ecat63PrintImageheader (ECAT63_imageheader *h, FILE *fp)
 
void ecat63PrintScanheader (ECAT63_scanheader *h, FILE *fp)
 
void ecat63PrintAttnheader (ECAT63_attnheader *h, FILE *fp)
 
void ecat63PrintNormheader (ECAT63_normheader *h, FILE *fp)
 
int ecat6PrintSubheader (ECAT63_mainheader mh, FILE *fp, int plane, int frame, FILE *ofp)
 
char * ecat63Datatype (short int dtype)
 
char * ecat63Unit (short int dunit)
 
void float2parts (float *buf)
 
char * ecat63ScanstarttimeInt (const ECAT63_mainheader *h, char *buf)
 Convert scan_start_time in ECAT 6.3 main header into a null-terminated string of the form YYYY-MM-DD hh:mm:ss, with length of 19 characters and the null.
 
int ecat63CopyMainheader (ECAT63_mainheader *h1, ECAT63_mainheader *h2)
 
int ecat63CopyScanheader (ECAT63_scanheader *h1, ECAT63_scanheader *h2)
 
int ecat63EditMHeader (ECAT63_mainheader *h, char *field, char *value, int verbose)
 
void imgInit (IMG *image)
 
void imgEmpty (IMG *image)
 
int imgAllocate (IMG *image, int planes, int rows, int columns, int frames)
 
int imgAllocateWithHeader (IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
 
int imgDup (IMG *img1, IMG *img2)
 
char * imgStatus (int status_index)
 
void imgSetStatus (IMG *img, int status_index)
 
void imgInfo (IMG *image)
 
int imgCopyhdr (IMG *image1, IMG *image2)
 
int imgExtractRange (IMG *img1, IMG_RANGE r, IMG *img2)
 
int imgExistentTimes (IMG *img)
 
int imgExistentCounts (IMG *img)
 
unsigned long long imgNaNs (IMG *img, int fix)
 
int sif2img (SIF *sif, IMG *img, int copy_header, int copy_frames, int copy_counts, int verbose)
 
int img2sif (IMG *img, SIF *sif, int copy_header, int copy_frames, int copy_counts, int verbose)
 
int imgDecayCorrection (IMG *img, int mode)
 
char * imgIsotope (IMG *img)
 
int imgSetDecayCorrFactors (IMG *image, int mode)
 
int imgBranchingCorrection (IMG *image, int mode, int verbose, char *status)
 
int imgRead (const char *fname, IMG *img)
 
int imgWrite (const char *fname, IMG *img)
 
int imgReadHeader (const char *fname, IMG *img, int format)
 
int imgReadFrame (const char *fname, int frame_to_read, IMG *img, int frame_index)
 
int imgWriteFrame (const char *fname, int frame_to_write, IMG *img, int frame_index)
 
void imgFormatFromFName (IMG *img, const char *fname)
 
int imgFormatDetermine (const char *fname, char *basename, char *hdrfile, char *imgfile, char *siffile, int *file_format, int *scanner, int *type, int *modality, int verbose)
 
int ecat63ReadAllToImg (const char *fname, IMG *img)
 
int ecat63WriteAllImg (const char *fname, IMG *img)
 
int ecat63ReadPlaneToImg (const char *fname, IMG *img)
 
int ecat63AddImg (const char *fname, IMG *img)
 
void imgGetEcat63MHeader (IMG *img, ECAT63_mainheader *h)
 
void imgSetEcat63MHeader (IMG *img, ECAT63_mainheader *h)
 
int imgEcat63Supported (ECAT63_mainheader *h)
 
int imgGetEcat63Fileformat (ECAT63_mainheader *h)
 
int imgReadEcat63Header (const char *fname, IMG *img)
 
int imgReadEcat63FirstFrame (const char *fname, IMG *img)
 
int imgReadEcat63Frame (const char *fname, int frame_to_read, IMG *img, int frame_index)
 
int imgWriteEcat63Frame (const char *fname, int frame_to_write, IMG *img, int frame_index)
 
void imgSetEcat63SHeader (IMG *img, void *h)
 
int imgReadEcat7 (const char *fname, IMG *img)
 
int imgWriteEcat7 (const char *fname, IMG *img)
 
int imgWrite2DEcat7 (const char *fname, IMG *img)
 
int imgWritePolarmap (const char *fname, IMG *img)
 
void imgGetEcat7MHeader (IMG *img, ECAT7_mainheader *h)
 
void imgSetEcat7MHeader (IMG *img, ECAT7_mainheader *h)
 
int imgReadEcat7Header (const char *fname, IMG *img)
 
int imgEcat7Supported (ECAT7_mainheader *h)
 
int imgReadEcat7Frame (const char *fname, int frame_to_read, IMG *img, int frame_index)
 
int imgReadEcat7FirstFrame (const char *fname, IMG *img)
 
int imgGetEcat7Fileformat (ECAT7_mainheader *h)
 
int imgWriteEcat7Frame (const char *fname, int frame_to_write, IMG *img, int frame_index)
 
void imgSetEcat7SHeader (IMG *img, void *h)
 
int imgReadAnalyze (const char *dbname, IMG *img)
 
int imgWriteAnalyze (const char *dbname, IMG *img)
 
int imgReadAnalyzeHeader (const char *dbname, IMG *img)
 
int imgGetAnalyzeHeader (IMG *img, ANALYZE_DSR *h)
 
int imgSetAnalyzeHeader (IMG *img, const char *dbname, ANALYZE_DSR *h, float fmin, float fmax)
 
int imgReadAnalyzeFrame (const char *dbname, int frame_to_read, IMG *img, int frame_index)
 
int imgReadAnalyzeFirstFrame (const char *fname, IMG *img)
 
int imgWriteAnalyzeFrame (const char *fname, int frame_to_write, IMG *img, int frame_index, float fmin, float fmax)
 
int imgMicropetToEcat7 (char *upetname, char *ecatfile, int verbose)
 
int imgMicropetPETToEcat7 (FILE *fph, FILE *fpi, char *ecatfile, int verbose)
 
int imgMicropetCTToEcat7 (FILE *fph, FILE *fpi, char *ecatfile, int verbose)
 
int imgGetMicropetMainHeader (FILE *fp, IMG *img, float *calibration_factor, int verbose)
 
int imgGetMicropetFrameHeader (FILE *fp, IMG *img, int frame_index, int verbose)
 
int imgGetMicropetSIF (FILE *fp, SIF *sif)
 
int imgGetMicropetHeader (IMG *img)
 
int imgReadMicropetHeader (const char *dbname, IMG *img)
 
int imgReadMicropetFrame (const char *fname, int frame_to_read, IMG *img, int frame_index)
 
int imgReadMicropetFirstFrame (const char *fname, IMG *img)
 
int imgReadMicropet (const char *fname, IMG *img)
 
int imgReadNifti (const char *filename, IMG *img, int verbose)
 
int imgReadNiftiFirstFrame (const char *filename, IMG *img, int verbose)
 
int imgReadNiftiHeader (const char *filename, IMG *img, int verbose)
 
int imgGetNiftiHeader (IMG *img, NIFTI_DSR *h, int verbose)
 
int imgReadNiftiFrame (const char *filename, int frame_to_read, IMG *img, int frame_index, int verbose)
 
int imgSetNiftiHeader (IMG *img, const char *dbname, NIFTI_DSR *dsr, float fmin, float fmax, int verbose)
 
int imgWriteNiftiFrame (const char *dbname, int frame_to_write, IMG *img, int frame_index, float fmin, float fmax, int verbose)
 
int imgWriteNifti (const char *dbname, IMG *img, int save_sif, int verbose)
 
int imgMatch (IMG *img1, IMG *img2, float accuracy)
 
int imgMatchMatrix (IMG *img1, IMG *img2, double accuracy)
 
int imgMatchHeader (IMG *img1, IMG *img2)
 
int imgMatchTransform (IMG *img1, IMG *img2)
 
int imgMatchFrames (IMG *img1, IMG *img2)
 
int imgMatchPlanes (IMG *img1, IMG *img2)
 
int imgMaxDifference (IMG *img1, IMG *img2, VOXEL_4D *absdiff, float *abs_max, VOXEL_4D *reldiff, float *rel_max)
 
int imgSS (IMG *img1, IMG *img2, double *ss)
 
int imgMatchMatrixSize (IMG *img1, IMG *img2)
 
int imgMax (IMG *img, float *maxvalue)
 
int imgAbsMax (IMG *img, float *maxvalue)
 
int imgRangeMinMax (IMG *img, IMG_RANGE *r, IMG_PIXEL *maxp, float *maxv, IMG_PIXEL *minp, float *minv)
 
int imgMinMax (IMG *img, float *minvalue, float *maxvalue)
 
int imgFrameMinMax (IMG *img, int frame, float *minvalue, float *maxvalue)
 
int imgReadMinMax (const char *fname, float *fmin, float *fmax)
 
int imgSmoothMax (IMG *img, float *maxvalue, IMG_PIXEL *p)
 
int imgGetPeak (IMG *img, float beforeTime, IMG_PIXEL *p, int verbose)
 
int imgGetMaxFrame (IMG *img, IMG *mimg, int verbose)
 
int imgGetMaxTime (IMG *img, IMG *mimg, const int w, int verbose)
 
int imgAvg (IMG *img, IMG_RANGE *r, float *avg)
 
float f_kth_smallest (float *data, long long int n, long long int k)
 
float fmedian (float *data, long long int n)
 
float fmean (float *data, long long int n, float *sd)
 
void fMinMaxFin (float *data, long long int n, float *fmin, float *fmax)
 
int imgUnitId (char *unit)
 
void imgUnitFromEcat (IMG *img, int ecat_unit)
 
void imgUnitFromEcat7 (IMG *img, ECAT7_mainheader *h)
 
int imgUnitToEcat6 (IMG *img)
 
void imgUnitToEcat7 (IMG *img, ECAT7_mainheader *h)
 
char * imgUnit (int dunit)
 
int imgSetUnit (IMG *img, char *unit)
 
int interfile_read (char headerName[256], char searchWord[256], char returnValue[256], char errorMessage[300])
 
int interfileIsHeader (const char *hdrfile, char *imgfile)
 
int interfileExists (const char *fname, char *hdrfile, char *imgfile, int verbose)
 
int upetHeaderReadParameter (FILE *fp, char *parameter, char *value)
 
int upetIsHeader (char *hdrfile)
 
int upetExists (const char *upetname, char *hdrfile, char *imgfile, int verbose)
 
int upetGetImageDimensions (FILE *fp, int *z, int *x, int *y, int *f)
 
int upetScanStart (FILE *fp, time_t *scant)
 
int upetReadImagedata (FILE *fp, IFT *ift, int frame, float *data)
 
int niftiExists (const char *dbname, char *hdrfile, char *imgile, char *siffile, NIFTI_DSR *header, int verbose, char *status)
 
int niftiCreateFNames (const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
 
int niftiRemove (const char *dbname, int fileformat, int verbose)
 
int niftiReadHeader (char *filename, NIFTI_DSR *h, int verbose, char *status)
 
int niftiPrintHeader (NIFTI_DSR *h, FILE *fp)
 
void niftiRemoveFNameExtension (char *fname)
 
int niftiReadImagedata (FILE *fp, NIFTI_DSR *h, int frame, float *data, int verbose, char *status)
 
int niftiWriteHeader (char *filename, NIFTI_DSR *dsr, int verbose, char *status)
 
int sifRead (char *filename, SIF *data)
 
int sifWrite (SIF *data, char *filename)
 
void sifPrint (SIF *data)
 
void sifEmpty (SIF *data)
 
void sifInit (SIF *data)
 
int sifSetmem (SIF *data, int frameNr)
 
void sifWeight (SIF *data, double halflife)
 Calculate weights for frames in SIF data based on true counts. Weights are normalized to have an average of 1.0.
 
void sifWeightByFrames (SIF *data, double halflife)
 Calculate weights for frames in SIF data based on frame lengths. Weights are normalized to have an average of 1.0.
 
void sifWeightNorm (SIF *data)
 
void sifModerateTrues (SIF *sif, double limit)
 
void sifModerateWeights (SIF *sif, double limit)
 
int sifExistentCounts (SIF *sif)
 
void ematInitiate (ECAT_MATRIX *emat)
 
void ehdrInitiate (ECAT_HEADERS *ehdr)
 
void ematEmpty (ECAT_MATRIX *emat)
 
void ehdrEmpty (ECAT_HEADERS *ehdr)
 
int ehdrAllocate (ECAT_HEADERS *ehdr, int nr)
 
int ecat7MHeaderToIFT (ECAT7_mainheader *h, IFT *ift, int verbose)
 
int ecat7MainheaderFromIFT (ECAT7_mainheader *h, IFT *ift, int verbose)
 
int ecat7ImageheaderToIFT (ECAT7_imageheader *h, IFT *ift, int verbose)
 
int ecat7ScanheaderToIFT (ECAT7_scanheader *h, IFT *ift, int verbose)
 
int ecat7ReadSubheaderToIFT (FILE *fp, ECAT7_mainheader *h, int strtblk, IFT *ift, int verbose)
 
int ecat7WriteSubheaderFromIFT (FILE *fp, ECAT7_mainheader *h, int strtblk, IFT *ift, int verbose)
 
int ecat7ReadHeaders (const char *fname, ECAT_HEADERS *ehdr, int verbose)
 
int ecat7WriteHeaders (const char *fname, ECAT_HEADERS *ehdr, int verbose)
 
int string_to_xyzf (const char *str, IMG_PIXEL *v)
 
int irdReorder (IMG_RANGE *img_range)
 
int irdRead (char *irdfile, IMG_RANGE *img_range, char *status)
 
int irdCheck (IMG_RANGE *r, IMG *img)
 
void volInit (VOL *vol)
 
void volEmpty (VOL *vol)
 
int volAllocate (VOL *vol, int planes, int rows, int columns)
 
int img2vol (IMG *img, VOL *vol, int frame)
 
int vol2img (VOL *vol, IMG *img, int frame)
 
void volInfo (VOL *vol, FILE *fp)
 
void volContents (VOL *vol, VOL_RANGE r, FILE *fp)
 
int volMax (VOL *vol, VOL_RANGE *r, VOL_PIXEL *maxp, float *maxv, VOL_PIXEL *minp, float *minv)
 
int volAvg (VOL *vol, VOL_RANGE *r, float *avg)
 
void svolInit (SVOL *svol)
 
void svolEmpty (SVOL *svol)
 
int svolAllocate (SVOL *svol, int planes, int rows, int columns)
 
int img2svol (IMG *img, SVOL *svol, int frame)
 
int svol2img (SVOL *svol, IMG *img, int frame)
 
void svolInfo (SVOL *svol, FILE *fp)
 
int vrdReorder (VOL_RANGE *vol_range)
 
int vrdVxlNr (VOL_RANGE *vol_range)
 
int vrd2vol (VOL_RANGE *r, VOL *vol, float in, float out, char *status)
 
int vrdRead (char *vdffile, VOL_RANGE *vol_range, char *status)
 
int string_to_xyz (char *str, int *x, int *y, int *z)
 
void pxlInit (IMG_PIXELS *pxl)
 
void pxlFree (IMG_PIXELS *pxl)
 
int pxlAllocate (IMG_PIXELS *pxl, long long int pxlNr)
 
int pxlAllocateMore (IMG_PIXELS *pxl, long long int pxlNr)
 
int pxlMakeRoom (IMG_PIXELS *list, long long int i, long long int n)
 
int pxlAdd (IMG_PIXELS *list, IMG_PIXEL *pxl)
 
int pxlGet (IMG_PIXELS *list, long long int i, IMG_PIXEL *pxl)
 
long long int pxlAddFromMask (IMG_PIXELS *list, IMG *img)
 
void pxlMove (IMG_PIXELS *list, long long int from, long long int to)
 
int pxlRm (IMG_PIXELS *list, long long int index)
 
long long int pxlRmDuplicates (IMG_PIXELS *list)
 
int pxlWrite (IMG_PIXELS *pxl, FILE *fp, char *status)
 
int pxlRead (IMG_PIXELS *pxl, const char *fname, char *status)
 
int dcmVerifyMagic (const char *filename, FILE *fp)
 
unsigned char dcmVRReserved (dcmvr id)
 
dcmvr dcmVRId (const char *s)
 
char * dcmVRName (dcmvr id)
 
size_t dcmVRVLength (dcmvr id)
 
char * dcmVRDescr (dcmvr id)
 
char * dcmDA2intl (const char *orig, char *intl)
 
char * dcmTM2intl (const char *orig, char *intl)
 
char * dcmDT2intl (const char *orig, char *intl)
 
unsigned int dcmSOPIdentify (const char *s)
 
char * dcmSOPName (unsigned int i)
 
char * dcmSOPUID (unsigned int i)
 
char * dcmSOPUIDName (const char *s)
 
dcmtruid dcmTrUID (const char *s)
 
char * dcmTrUIDDescr (dcmtruid id)
 
char * dcmTrUIDString (dcmtruid id)
 
dcmtruid dcmReadTransferSyntaxUID (FILE *fp)
 
int dcmReadFileTag (FILE *fp, DCMTAG *tag)
 
int dcmWriteFileTag (FILE *fp, DCMTAG *tag)
 
int dcmWriteFileSQDelimItem (FILE *fp)
 
int dcmWriteFileSQItemDelimTag (FILE *fp)
 
dcmvr dcmReadFileVR (FILE *fp, char *vrstr)
 
unsigned int dcmReadFileVL (FILE *fp, unsigned int n)
 
int dcmReadFileVRVL (FILE *fp, dcmvr *vr, unsigned int *vl, unsigned int *n)
 
int dcmWriteFileVRVL (FILE *fp, dcmvr vr, unsigned int vl, unsigned int *n)
 
void dcmfileInit (DCMFILE *d)
 
void dcmitemFree (DCMITEM *d)
 
void dcmfileFree (DCMFILE *d)
 
unsigned short int dcmfileMaxDepth (DCMFILE *df)
 
unsigned short int dcmitemMaxDepth (DCMITEM *d)
 
unsigned short int dcmitemParentNr (DCMITEM *d)
 
char * dcmValueString (DCMITEM *d)
 
long int dcmitemGetInt (DCMITEM *d)
 
double dcmitemGetReal (DCMITEM *d)
 
DCMITEMdcmFindTag (DCMITEM *d, const short int omit, DCMTAG *tag, const int verbose)
 
void dcmitemPrint (DCMITEM *d)
 
void dcmTagSet (DCMTAG *tag, unsigned short int group, unsigned short int element)
 
int dcmAddItem (DCMFILE *dcm, DCMITEM *d, short int aschild, DCMTAG tag, dcmvr vr, unsigned int vl, char *rd, const int verbose)
 
int dcmFileReadNextElement (DCMFILE *dcm, DCMITEM *prev_item, DCMITEM *parent_item, const short int sub, const short int headerOnly, int verbose)
 
int dcmFileRead (const char *filename, DCMFILE *dcm, const short int headerOnly, int verbose)
 
int dcmFileWrite (const char *filename, DCMFILE *dcm, int verbose)
 

Variables

int ANALYZE_TEST
 
char ecat7errmsg [128]
 
int ECAT7_TEST
 
char ecat63errmsg [128]
 
int ECAT63_TEST
 
char siferrmsg [128]
 
int SIF_TEST
 
int IMG_TEST
 
int VOL_TEST
 
int MICROPET_TEST
 

Detailed Description

Header file for libtpcimgio.

Author
Vesa Oikonen

Definition in file libtpcimgio.h.

Macro Definition Documentation

◆ ANALYZE_DT_ALL

#define ANALYZE_DT_ALL   255

Analyze 7.5 datatype

Definition at line 67 of file libtpcimgio.h.

◆ ANALYZE_DT_BINARY

#define ANALYZE_DT_BINARY   1

Analyze 7.5 datatype, 1 bit

Definition at line 51 of file libtpcimgio.h.

Referenced by anaReadImagedata().

◆ ANALYZE_DT_COMPLEX

#define ANALYZE_DT_COMPLEX   32

Analyze 7.5 datatype, 64 bits (two floats)

Definition at line 61 of file libtpcimgio.h.

Referenced by anaReadImagedata().

◆ ANALYZE_DT_DOUBLE

#define ANALYZE_DT_DOUBLE   64

Analyze 7.5 datatype, 64 bits

Definition at line 63 of file libtpcimgio.h.

Referenced by anaReadImagedata().

◆ ANALYZE_DT_FLOAT

#define ANALYZE_DT_FLOAT   16

Analyze 7.5 datatype, 32 bits

Definition at line 59 of file libtpcimgio.h.

Referenced by anaReadImagedata().

◆ ANALYZE_DT_NONE

#define ANALYZE_DT_NONE   0

Analyze 7.5 datatype

Definition at line 47 of file libtpcimgio.h.

◆ ANALYZE_DT_RGB

#define ANALYZE_DT_RGB   128

Analyze 7.5 datatype

Definition at line 65 of file libtpcimgio.h.

Referenced by anaReadImagedata().

◆ ANALYZE_DT_SIGNED_INT

#define ANALYZE_DT_SIGNED_INT   8

Analyze 7.5 datatype, 32 bits

Definition at line 57 of file libtpcimgio.h.

Referenced by anaReadImagedata().

◆ ANALYZE_DT_SIGNED_SHORT

#define ANALYZE_DT_SIGNED_SHORT   4

Analyze 7.5 datatype, 16 bits

Definition at line 55 of file libtpcimgio.h.

Referenced by anaReadImagedata(), imgSetAnalyzeHeader(), and imgWriteAnalyze().

◆ ANALYZE_DT_UNKNOWN

#define ANALYZE_DT_UNKNOWN   0

Analyze 7.5 datatype

Definition at line 49 of file libtpcimgio.h.

◆ ANALYZE_DT_UNSIGNED_CHAR

#define ANALYZE_DT_UNSIGNED_CHAR   2

Analyze 7.5 datatype, 8 bits

Definition at line 53 of file libtpcimgio.h.

Referenced by anaReadImagedata().

◆ ATTN_DATA

◆ BACKUP_EXTENSION

#define BACKUP_EXTENSION   ".bak"

Backup file extension

Definition at line 32 of file libtpcimgio.h.

◆ BYTE_TYPE

◆ ECAT63_SYSTEM_TYPE_DEFAULT

#define ECAT63_SYSTEM_TYPE_DEFAULT   931

Default system type in ECAT 6.3 file header

Definition at line 959 of file libtpcimgio.h.

Referenced by ecat63AddImg(), ecat63WriteAllImg(), and imgSetEcat63MHeader().

◆ ECAT7_2DNORM

#define ECAT7_2DNORM   4

◆ ECAT7_2DSCAN

◆ ECAT7_3DNORM

#define ECAT7_3DNORM   13

ECAT7 matrix filetype

Definition at line 269 of file libtpcimgio.h.

Referenced by ecat7PrintSubheader(), ecat7ReadSubheaderToIFT(), and ecat7WriteSubheaderFromIFT().

◆ ECAT7_3DSCAN

◆ ECAT7_3DSCAN8

◆ ECAT7_3DSCANFIT

◆ ECAT7_ATTEN

#define ECAT7_ATTEN   3

◆ ECAT7_BYTE

#define ECAT7_BYTE   1

◆ ECAT7_Feet_First_Decubitus_Left

#define ECAT7_Feet_First_Decubitus_Left   6

ECAT7 patient orientation

Definition at line 286 of file libtpcimgio.h.

◆ ECAT7_Feet_First_Decubitus_Right

#define ECAT7_Feet_First_Decubitus_Right   4

ECAT7 patient orientation

Definition at line 282 of file libtpcimgio.h.

◆ ECAT7_Feet_First_Prone

#define ECAT7_Feet_First_Prone   0

ECAT7 patient orientation

Definition at line 274 of file libtpcimgio.h.

◆ ECAT7_Feet_First_Supine

#define ECAT7_Feet_First_Supine   2

ECAT7 patient orientation

Definition at line 278 of file libtpcimgio.h.

◆ ECAT7_Head_First_Decubitus_Left

#define ECAT7_Head_First_Decubitus_Left   7

ECAT7 patient orientation

Definition at line 288 of file libtpcimgio.h.

◆ ECAT7_Head_First_Decubitus_Right

#define ECAT7_Head_First_Decubitus_Right   5

ECAT7 patient orientation

Definition at line 284 of file libtpcimgio.h.

◆ ECAT7_Head_First_Prone

#define ECAT7_Head_First_Prone   1

ECAT7 patient orientation

Definition at line 276 of file libtpcimgio.h.

◆ ECAT7_Head_First_Supine

#define ECAT7_Head_First_Supine   3

ECAT7 patient orientation

Definition at line 280 of file libtpcimgio.h.

Referenced by ecatCopy63to7mainheader().

◆ ECAT7_IEEER4

◆ ECAT7_IMAGE16

◆ ECAT7_IMAGE8

◆ ECAT7_POLARMAP

◆ ECAT7_PROJ

#define ECAT7_PROJ   8

ECAT7 matrix filetype

Definition at line 259 of file libtpcimgio.h.

◆ ECAT7_PROJ16

#define ECAT7_PROJ16   9

ECAT7 matrix filetype

Definition at line 261 of file libtpcimgio.h.

◆ ECAT7_SUNI2

◆ ECAT7_SUNI4

◆ ECAT7_UNKNOWN

#define ECAT7_UNKNOWN   0

ECAT7 matrix filetype

Definition at line 243 of file libtpcimgio.h.

◆ ECAT7_Unknown_Orientation

#define ECAT7_Unknown_Orientation   8

ECAT7 patient orientation

Definition at line 290 of file libtpcimgio.h.

◆ ECAT7_VAXI2

◆ ECAT7_VAXI4

◆ ECAT7_VAXR4

◆ ECAT7_VOLUME16

◆ ECAT7_VOLUME8

◆ IEEE_R4

◆ IMAGE_DATA

◆ IMG_ANA

#define IMG_ANA   11

◆ IMG_ANA_L

#define IMG_ANA_L   12 /* little endian variant */

Definition for file format: little endian variant

Definition at line 1514 of file libtpcimgio.h.

Referenced by imgGetAnalyzeHeader(), imgReadAnalyze(), imgReadFrame(), imgReadHeader(), imgSetAnalyzeHeader(), imgWrite(), imgWriteAnalyze(), imgWriteAnalyzeFrame(), and imgWriteFrame().

◆ IMG_DC_CORRECTED

◆ IMG_DC_NONCORRECTED

◆ IMG_DC_UNKNOWN

#define IMG_DC_UNKNOWN   0

◆ IMG_DICOM

#define IMG_DICOM   100

Definition for file format

Definition at line 1526 of file libtpcimgio.h.

Referenced by imgFormatDetermine(), and imgFormatFromFName().

◆ IMG_E63

◆ IMG_E7

◆ IMG_E7_2D

◆ IMG_ERR_CALLING

#define IMG_ERR_CALLING   1

Definition for img error status message

Definition at line 1486 of file libtpcimgio.h.

◆ IMG_ERR_OK

#define IMG_ERR_OK   0

Definition for img error status message

Definition at line 1484 of file libtpcimgio.h.

◆ IMG_ERR_OOM

#define IMG_ERR_OOM   2

Definition for img error status message

Definition at line 1488 of file libtpcimgio.h.

◆ IMG_FLAT

#define IMG_FLAT   61

Definition for file format

Definition at line 1524 of file libtpcimgio.h.

◆ IMG_INTERFILE

#define IMG_INTERFILE   21

Definition for file format

Definition at line 1516 of file libtpcimgio.h.

Referenced by imgFormatDetermine(), and imgFormatFromFName().

◆ IMG_MICROPET

#define IMG_MICROPET   41

Definition for file format

Definition at line 1522 of file libtpcimgio.h.

Referenced by imgFormatDetermine(), imgGetMicropetHeader(), imgReadFrame(), and imgReadHeader().

◆ IMG_MODALITY_CT

#define IMG_MODALITY_CT   3

Definition for modality

Definition at line 1542 of file libtpcimgio.h.

◆ IMG_MODALITY_MRI

#define IMG_MODALITY_MRI   2

Definition for modality

Definition at line 1540 of file libtpcimgio.h.

◆ IMG_MODALITY_PET

#define IMG_MODALITY_PET   1

Definition for modality

Definition at line 1538 of file libtpcimgio.h.

◆ IMG_MODALITY_SPECT

#define IMG_MODALITY_SPECT   4

Definition for modality

Definition at line 1544 of file libtpcimgio.h.

◆ IMG_MODALITY_UNKNOWN

#define IMG_MODALITY_UNKNOWN   0

Definition for modality

Definition at line 1536 of file libtpcimgio.h.

Referenced by imgFormatDetermine().

◆ IMG_NIFTI_1D

#define IMG_NIFTI_1D   31 /* dual file format */

◆ IMG_NIFTI_1S

#define IMG_NIFTI_1S   32 /* single file format */

◆ IMG_POLARMAP

#define IMG_POLARMAP   9

◆ IMG_STATUS_ERROR

#define IMG_STATUS_ERROR   3

Definition for img struct status

Definition at line 1481 of file libtpcimgio.h.

Referenced by imgInfo(), svolInfo(), and volInfo().

◆ IMG_STATUS_INITIALIZED

◆ IMG_STATUS_OCCUPIED

#define IMG_STATUS_OCCUPIED   2

Definition for img struct status

Definition at line 1479 of file libtpcimgio.h.

Referenced by dftAllocateWithIMG(), ecat63AddImg(), ecat63ReadPlaneToImg(), ecat63WriteAllImg(), idiSimulateTubeImg(), idiSimulateTubeImgPlane(), idiSimulateTubeVol(), img2cube(), img2svol(), img2vol(), img_k1_using_ki(), img_logan(), img_patlak(), imgAbs(), imgAbsMax(), imgAllocate(), imgArithm(), imgArithmConst(), imgArithmFrame(), imgAUMC(), imgAverageAUC(), imgAverageMaskTAC(), imgAvg(), imgBorderAverageTAC(), imgBranchingCorrection(), imgCircleMask(), imgDecayCorrection(), imgDeleteFrameOverlap(), imgDeleteFrameOverlap_old(), imgEmpty(), imgExistentCounts(), imgExistentTimes(), imgExtractRange(), imgFBP(), imgFrameGapFill(), imgFrameIntegral(), imgFrameMinMax(), imgFramesCheck(), imgGetAnalyzeHeader(), imgGetConcWeightedPeakPos(), imgGetFrameDiff(), imgGetFrameDyn(), imgGetMaxFrame(), imgGetMaxTime(), imgGetMicropetHeader(), imgGetNiftiHeader(), imgGetPeak(), imgInv(), imgLn(), imgLog10(), imgMaskFloodFill(), imgMaskPixelTACs(), imgMaskRegionLabeling(), imgMaskTAC(), imgMax(), imgMRP(), imgMRT(), imgNoiseTemplate(), imgOutlierFilter(), imgRangeMinMax(), imgRangeWeightedMax(), imgRawCountsPerTime(), imgReadAnalyzeFrame(), imgReadEcat63Frame(), imgReadEcat7Frame(), imgReadFrame(), imgReadMicropetFrame(), imgReadNiftiFrame(), imgRegionGrowingByThreshold(), imgReprojection(), imgsegmClusterExpand(), imgsegmFindMaxOutsideClusters(), imgsegmMaskToCluster(), imgsegmSimilar(), imgsegmThreshold(), imgsegmThresholdByMask(), imgsegmThresholdMask(), imgSetAnalyzeHeader(), imgSetDecayCorrFactors(), imgSetNiftiHeader(), imgSetScanner(), imgSetWeights(), imgSimulateRing(), imgSimulateSphere(), imgSmoothMax(), imgSmoothOverFrames(), imgThresholdByMask(), imgThresholding(), imgThresholdingLowHigh(), imgThresholdMaskCount(), imgTimeIntegral(), imgVoiMaskTAC(), imgWrite(), imgWrite2DEcat7(), imgWriteAnalyze(), imgWriteAnalyzeFrame(), imgWriteEcat63Frame(), imgWriteEcat7(), imgWriteEcat7Frame(), imgWriteFrame(), imgWriteNifti(), imgWriteNiftiFrame(), imgWritePolarmap(), sifAllocateWithIMG(), svol2img(), svolAllocate(), svolEmpty(), tiffWriteImg(), vol2img(), volAllocate(), volAvg(), volContents(), volEmpty(), volMax(), and vrd2vol().

◆ IMG_STATUS_UNINITIALIZED

#define IMG_STATUS_UNINITIALIZED   0

Definition for img struct status

Definition at line 1475 of file libtpcimgio.h.

Referenced by ecat63ReadPlaneToImg(), img2svol(), img2vol(), imgAllocate(), imgExtractRange(), imgInfo(), svolAllocate(), svolInfo(), volAllocate(), and volInfo().

◆ IMG_TYPE_ATTN

#define IMG_TYPE_ATTN   4

Definition for 'image type' attenuation data

Definition at line 1499 of file libtpcimgio.h.

Referenced by ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), and imgReadEcat63Header().

◆ IMG_TYPE_IMAGE

◆ IMG_TYPE_POLARMAP

#define IMG_TYPE_POLARMAP   3

◆ IMG_TYPE_RAW

◆ IMG_TYPE_UNKNOWN

#define IMG_TYPE_UNKNOWN   0

Definition for image type

Definition at line 1491 of file libtpcimgio.h.

Referenced by imgFormatDetermine(), and imgMatchHeader().

◆ IMG_UNKNOWN

◆ M68K_I2

#define M68K_I2   SUN_I2

ECAT matrix data type

Definition at line 238 of file libtpcimgio.h.

◆ M68K_I4

#define M68K_I4   SUN_I4

ECAT matrix data type

Definition at line 240 of file libtpcimgio.h.

◆ MatBLKSIZE [1/2]

◆ MatBLKSIZE [2/2]

#define MatBLKSIZE   512

ECAT matrix block size

ECAT 6.3 matrix block size

Definition at line 210 of file libtpcimgio.h.

◆ MatFirstDirBlk [1/2]

◆ MatFirstDirBlk [2/2]

#define MatFirstDirBlk   2

ECAT matrix directory start block

ECAT 6.3 first directory block

Definition at line 214 of file libtpcimgio.h.

◆ MAX_MICROPET_LINE_LEN

◆ MAX_POLARMAP_NUM_RINGS

#define MAX_POLARMAP_NUM_RINGS   32

Maximum nr of rings in polar map (based on ECAT 7 polar map header)

Definition at line 1586 of file libtpcimgio.h.

Referenced by imgCopyhdr(), imgEmpty(), imgInit(), and imgReadEcat7Header().

◆ NIFTI_DT_ALL

#define NIFTI_DT_ALL   255

NIFTI1 datatype (same as Analyze datatypes)

Definition at line 2051 of file libtpcimgio.h.

◆ NIFTI_DT_BINARY

#define NIFTI_DT_BINARY   1

NIFTI1 datatype 1 bit (same as Analyze datatypes)

Definition at line 2035 of file libtpcimgio.h.

Referenced by niftiReadImagedata().

◆ NIFTI_DT_COMPLEX

#define NIFTI_DT_COMPLEX   32

NIFTI1 datatype 64 bits (same as Analyze datatypes)

Definition at line 2045 of file libtpcimgio.h.

Referenced by niftiReadImagedata().

◆ NIFTI_DT_DOUBLE

#define NIFTI_DT_DOUBLE   64

NIFTI1 datatype 64 bits (same as Analyze datatypes)

Definition at line 2047 of file libtpcimgio.h.

Referenced by niftiReadImagedata().

◆ NIFTI_DT_DOUBLE_PAIR

#define NIFTI_DT_DOUBLE_PAIR   1792

NIFTI1 datatype 128 bits

Definition at line 2065 of file libtpcimgio.h.

◆ NIFTI_DT_FLOAT

#define NIFTI_DT_FLOAT   16

NIFTI1 datatype 32 bits (same as Analyze datatypes)

Definition at line 2043 of file libtpcimgio.h.

Referenced by imgSetNiftiHeader(), and niftiReadImagedata().

◆ NIFTI_DT_LONG_DOUBLE

#define NIFTI_DT_LONG_DOUBLE   1536

NIFTI1 datatype 128 bits

Definition at line 2063 of file libtpcimgio.h.

◆ NIFTI_DT_LONG_DOUBLE_PAIR

#define NIFTI_DT_LONG_DOUBLE_PAIR   2048

NIFTI1 datatype 256 bits

Definition at line 2067 of file libtpcimgio.h.

◆ NIFTI_DT_LONG_LONG

#define NIFTI_DT_LONG_LONG   1024

NIFTI1 datatype 64 bits

Definition at line 2059 of file libtpcimgio.h.

◆ NIFTI_DT_NONE

#define NIFTI_DT_NONE   0

NIFTI1 datatype (same as Analyze datatypes)

Definition at line 2031 of file libtpcimgio.h.

◆ NIFTI_DT_RGB

#define NIFTI_DT_RGB   128

NIFTI1 datatype 24 bits (same as Analyze datatypes)

Definition at line 2049 of file libtpcimgio.h.

Referenced by niftiReadImagedata().

◆ NIFTI_DT_RGBA

#define NIFTI_DT_RGBA   2304

NIFTI1 datatype 32 bits

Definition at line 2069 of file libtpcimgio.h.

◆ NIFTI_DT_SIGNED_CHAR

#define NIFTI_DT_SIGNED_CHAR   256

NIFTI1 datatype 8 bits

Definition at line 2053 of file libtpcimgio.h.

◆ NIFTI_DT_SIGNED_INT

#define NIFTI_DT_SIGNED_INT   8

NIFTI1 datatype 32 bits (same as Analyze datatypes)

Definition at line 2041 of file libtpcimgio.h.

Referenced by niftiReadImagedata().

◆ NIFTI_DT_SIGNED_SHORT

#define NIFTI_DT_SIGNED_SHORT   4

NIFTI1 datatype 16 bits (same as Analyze datatypes)

Definition at line 2039 of file libtpcimgio.h.

Referenced by niftiReadImagedata().

◆ NIFTI_DT_UNKNOWN

#define NIFTI_DT_UNKNOWN   0

NIFTI1 datatype (same as Analyze datatypes)

Definition at line 2033 of file libtpcimgio.h.

Referenced by niftiReadImagedata().

◆ NIFTI_DT_UNSIGNED_CHAR

#define NIFTI_DT_UNSIGNED_CHAR   2

NIFTI1 datatype 8 bits (same as Analyze datatypes)

Definition at line 2037 of file libtpcimgio.h.

Referenced by niftiReadImagedata().

◆ NIFTI_DT_UNSIGNED_INT

#define NIFTI_DT_UNSIGNED_INT   768

NIFTI1 datatype 32 bits

Definition at line 2057 of file libtpcimgio.h.

◆ NIFTI_DT_UNSIGNED_LONG_LONG

#define NIFTI_DT_UNSIGNED_LONG_LONG   1280

NIFTI1 datatype 64 bits

Definition at line 2061 of file libtpcimgio.h.

◆ NIFTI_DT_UNSIGNED_SHORT

#define NIFTI_DT_UNSIGNED_SHORT   512

NIFTI1 datatype 16 bits

Definition at line 2055 of file libtpcimgio.h.

Referenced by niftiReadImagedata().

◆ NIFTI_HEADER_EXTENDER_SIZE

#define NIFTI_HEADER_EXTENDER_SIZE   4

NIFTI1 header size

Definition at line 2006 of file libtpcimgio.h.

Referenced by niftiWriteHeader().

◆ NIFTI_HEADER_SIZE

#define NIFTI_HEADER_SIZE   348

NIFTI1 header size

Definition at line 2004 of file libtpcimgio.h.

Referenced by imgSetNiftiHeader(), niftiReadHeader(), and niftiWriteHeader().

◆ NIFTI_INTENT_BETA

#define NIFTI_INTENT_BETA   7

NIFTI1 intent statistics

Definition at line 2085 of file libtpcimgio.h.

◆ NIFTI_INTENT_BINOM

#define NIFTI_INTENT_BINOM   8

NIFTI1 intent statistics

Definition at line 2087 of file libtpcimgio.h.

◆ NIFTI_INTENT_CHI

#define NIFTI_INTENT_CHI   19

NIFTI1 intent statistics

Definition at line 2109 of file libtpcimgio.h.

◆ NIFTI_INTENT_CHISQ

#define NIFTI_INTENT_CHISQ   6

NIFTI1 intent statistics

Definition at line 2083 of file libtpcimgio.h.

◆ NIFTI_INTENT_CHISQ_NONC

#define NIFTI_INTENT_CHISQ_NONC   13

NIFTI1 intent statistics

Definition at line 2097 of file libtpcimgio.h.

◆ NIFTI_INTENT_CORREL

#define NIFTI_INTENT_CORREL   2

NIFTI1 intent statistics

Definition at line 2075 of file libtpcimgio.h.

◆ NIFTI_INTENT_DIMLESS

#define NIFTI_INTENT_DIMLESS   1011

NIFTI1 intent other

Definition at line 2141 of file libtpcimgio.h.

◆ NIFTI_INTENT_DISPVECT

#define NIFTI_INTENT_DISPVECT   1006

NIFTI1 intent other

Definition at line 2131 of file libtpcimgio.h.

◆ NIFTI_INTENT_ESTIMATE

#define NIFTI_INTENT_ESTIMATE   1001

NIFTI1 intent other

Definition at line 2121 of file libtpcimgio.h.

◆ NIFTI_INTENT_EXTVAL

#define NIFTI_INTENT_EXTVAL   21

NIFTI1 intent statistics

Definition at line 2113 of file libtpcimgio.h.

◆ NIFTI_INTENT_FTEST

#define NIFTI_INTENT_FTEST   4

NIFTI1 intent statistics

Definition at line 2079 of file libtpcimgio.h.

◆ NIFTI_INTENT_FTEST_NONC

#define NIFTI_INTENT_FTEST_NONC   12

NIFTI1 intent statistics

Definition at line 2095 of file libtpcimgio.h.

◆ NIFTI_INTENT_GAMMA

#define NIFTI_INTENT_GAMMA   9

NIFTI1 intent statistics

Definition at line 2089 of file libtpcimgio.h.

◆ NIFTI_INTENT_GENMATRIX

#define NIFTI_INTENT_GENMATRIX   1004

NIFTI1 intent other

Definition at line 2127 of file libtpcimgio.h.

◆ NIFTI_INTENT_INVGAUSS

#define NIFTI_INTENT_INVGAUSS   20

NIFTI1 intent statistics

Definition at line 2111 of file libtpcimgio.h.

◆ NIFTI_INTENT_LABEL

#define NIFTI_INTENT_LABEL   1002

NIFTI1 intent other

Definition at line 2123 of file libtpcimgio.h.

◆ NIFTI_INTENT_LAPLACE

#define NIFTI_INTENT_LAPLACE   15

NIFTI1 intent statistics

Definition at line 2101 of file libtpcimgio.h.

◆ NIFTI_INTENT_LOG10PVAL

#define NIFTI_INTENT_LOG10PVAL   24

NIFTI1 intent statistics

Definition at line 2119 of file libtpcimgio.h.

◆ NIFTI_INTENT_LOGISTIC

#define NIFTI_INTENT_LOGISTIC   14

NIFTI1 intent statistics

Definition at line 2099 of file libtpcimgio.h.

◆ NIFTI_INTENT_LOGPVAL

#define NIFTI_INTENT_LOGPVAL   23

NIFTI1 intent statistics

Definition at line 2117 of file libtpcimgio.h.

◆ NIFTI_INTENT_NEURONAME

#define NIFTI_INTENT_NEURONAME   1003

NIFTI1 intent other

Definition at line 2125 of file libtpcimgio.h.

◆ NIFTI_INTENT_NONE

#define NIFTI_INTENT_NONE   0

NIFTI1 intent dataset

Definition at line 2073 of file libtpcimgio.h.

Referenced by imgSetNiftiHeader().

◆ NIFTI_INTENT_NORMAL

#define NIFTI_INTENT_NORMAL   11

NIFTI1 intent statistics

Definition at line 2093 of file libtpcimgio.h.

◆ NIFTI_INTENT_POINTSET

#define NIFTI_INTENT_POINTSET   1008

NIFTI1 intent other

Definition at line 2135 of file libtpcimgio.h.

◆ NIFTI_INTENT_POISSON

#define NIFTI_INTENT_POISSON   10

NIFTI1 intent statistics

Definition at line 2091 of file libtpcimgio.h.

◆ NIFTI_INTENT_PVAL

#define NIFTI_INTENT_PVAL   22

NIFTI1 intent statistics

Definition at line 2115 of file libtpcimgio.h.

◆ NIFTI_INTENT_QUATERNION

#define NIFTI_INTENT_QUATERNION   1010

NIFTI1 intent other

Definition at line 2139 of file libtpcimgio.h.

◆ NIFTI_INTENT_SYMMATRIX

#define NIFTI_INTENT_SYMMATRIX   1005

NIFTI1 intent other

Definition at line 2129 of file libtpcimgio.h.

◆ NIFTI_INTENT_TRIANGLE

#define NIFTI_INTENT_TRIANGLE   1009

NIFTI1 intent other

Definition at line 2137 of file libtpcimgio.h.

◆ NIFTI_INTENT_TTEST

#define NIFTI_INTENT_TTEST   3

NIFTI1 intent statistics

Definition at line 2077 of file libtpcimgio.h.

◆ NIFTI_INTENT_TTEST_NONC

#define NIFTI_INTENT_TTEST_NONC   17

NIFTI1 intent statistics

Definition at line 2105 of file libtpcimgio.h.

◆ NIFTI_INTENT_UNIFORM

#define NIFTI_INTENT_UNIFORM   16

NIFTI1 intent statistics

Definition at line 2103 of file libtpcimgio.h.

◆ NIFTI_INTENT_VECTOR

#define NIFTI_INTENT_VECTOR   1007

NIFTI1 intent other

Definition at line 2133 of file libtpcimgio.h.

◆ NIFTI_INTENT_WEIBULL

#define NIFTI_INTENT_WEIBULL   18

NIFTI1 intent statistics

Definition at line 2107 of file libtpcimgio.h.

◆ NIFTI_INTENT_ZSCORE

#define NIFTI_INTENT_ZSCORE   5

NIFTI1 intent statistics

Definition at line 2081 of file libtpcimgio.h.

◆ NIFTI_UNITS_HERTZ

#define NIFTI_UNITS_HERTZ   32

NIFTI1 units: Hertz

Definition at line 2023 of file libtpcimgio.h.

◆ NIFTI_UNITS_METER

#define NIFTI_UNITS_METER   1

NIFTI1 units: meter

Definition at line 2011 of file libtpcimgio.h.

Referenced by imgGetNiftiHeader().

◆ NIFTI_UNITS_MICRON

#define NIFTI_UNITS_MICRON   4

NIFTI1 units: micrometer

Definition at line 2015 of file libtpcimgio.h.

Referenced by imgGetNiftiHeader().

◆ NIFTI_UNITS_MM

#define NIFTI_UNITS_MM   2

NIFTI1 units: millimetre

Definition at line 2013 of file libtpcimgio.h.

Referenced by imgGetNiftiHeader(), and imgSetNiftiHeader().

◆ NIFTI_UNITS_MSEC

#define NIFTI_UNITS_MSEC   16

NIFTI1 units: milliseconds

Definition at line 2019 of file libtpcimgio.h.

◆ NIFTI_UNITS_PPM

#define NIFTI_UNITS_PPM   40

NIFTI1 units: parts per million

Definition at line 2025 of file libtpcimgio.h.

◆ NIFTI_UNITS_RADS

#define NIFTI_UNITS_RADS   48

NIFTI1 units: radians per second

Definition at line 2027 of file libtpcimgio.h.

◆ NIFTI_UNITS_SEC

#define NIFTI_UNITS_SEC   8

NIFTI1 units: seconds

Definition at line 2017 of file libtpcimgio.h.

Referenced by imgSetNiftiHeader().

◆ NIFTI_UNITS_UNKNOWN

#define NIFTI_UNITS_UNKNOWN   0

NIFTI1 units: unknown

Definition at line 2009 of file libtpcimgio.h.

◆ NIFTI_UNITS_USEC

#define NIFTI_UNITS_USEC   24

NIFTI1 units: microseconds

Definition at line 2021 of file libtpcimgio.h.

◆ NIFTI_XFORM_ALIGNED_ANAT

#define NIFTI_XFORM_ALIGNED_ANAT   2

NIFTI1 Coordinate System: Coordinates aligned to another file or "truth".

Definition at line 2148 of file libtpcimgio.h.

◆ NIFTI_XFORM_MNI_152

#define NIFTI_XFORM_MNI_152   4

NIFTI1 Coordinate System: Coordinates aligned to the MNI space.

Definition at line 2152 of file libtpcimgio.h.

◆ NIFTI_XFORM_SCANNER_ANAT

#define NIFTI_XFORM_SCANNER_ANAT   1

NIFTI1 Coordinate System: Scanner-based anatomical coordinates.

Definition at line 2146 of file libtpcimgio.h.

Referenced by ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), imgReadAnalyze(), imgReadEcat63Frame(), imgReadEcat7(), and imgReadEcat7Header().

◆ NIFTI_XFORM_TALAIRACH

#define NIFTI_XFORM_TALAIRACH   3

NIFTI1 Coordinate System: Coordinates aligned to the Talairach space.

Definition at line 2150 of file libtpcimgio.h.

◆ NIFTI_XFORM_UNKNOWN

#define NIFTI_XFORM_UNKNOWN   0

NIFTI1 Coordinate System: Arbitrary coordinates.

Definition at line 2144 of file libtpcimgio.h.

Referenced by ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), imgEmpty(), imgInit(), imgReadAnalyze(), imgReadEcat63Frame(), imgReadEcat7(), and imgReadEcat7Header().

◆ NORM_DATA

◆ RAW_DATA

◆ SCANNER_ADVANCE

#define SCANNER_ADVANCE   12096

Definition for scanner model (system type)

Definition at line 1551 of file libtpcimgio.h.

Referenced by imgSetScanner().

◆ SCANNER_DMI_PET

#define SCANNER_DMI_PET   8

Definition for scanner model (system type): nonstandard

Definition at line 1564 of file libtpcimgio.h.

◆ SCANNER_ECAT931

#define SCANNER_ECAT931   12

Definition for scanner model (system type)

Definition at line 1549 of file libtpcimgio.h.

Referenced by imgSetScanner().

◆ SCANNER_FOCUS_120

#define SCANNER_FOCUS_120   2501

Definition for scanner model (system type): nonstandard

Definition at line 1575 of file libtpcimgio.h.

◆ SCANNER_FOCUS_220

#define SCANNER_FOCUS_220   2500

Definition for scanner model (system type): nonstandard

Definition at line 1573 of file libtpcimgio.h.

◆ SCANNER_HRPLUS

#define SCANNER_HRPLUS   3

Definition for scanner model (system type)

Definition at line 1553 of file libtpcimgio.h.

Referenced by imgSetScanner().

◆ SCANNER_HRRT

#define SCANNER_HRRT   4

Definition for scanner model (system type)

Definition at line 1555 of file libtpcimgio.h.

Referenced by imgSetScanner().

◆ SCANNER_INVEON_DEDICATED_PET

#define SCANNER_INVEON_DEDICATED_PET   5000

Definition for scanner model (system type): nonstandard

Definition at line 1577 of file libtpcimgio.h.

◆ SCANNER_INVEON_MM_PET

#define SCANNER_INVEON_MM_PET   5500

Definition for scanner model (system type): nonstandard

Definition at line 1579 of file libtpcimgio.h.

◆ SCANNER_MICROPET2

#define SCANNER_MICROPET2   2002

Definition for scanner model (system type): nonstandard

Definition at line 1571 of file libtpcimgio.h.

◆ SCANNER_MR_PET_HEAD_INSERT

#define SCANNER_MR_PET_HEAD_INSERT   6000

Definition for scanner model (system type): nonstandard

Definition at line 1581 of file libtpcimgio.h.

◆ SCANNER_MRI

#define SCANNER_MRI   5

Definition for scanner model (system type): nonstandard

Definition at line 1558 of file libtpcimgio.h.

◆ SCANNER_PRIMATE

#define SCANNER_PRIMATE   2000

Definition for scanner model (system type): nonstandard

Definition at line 1567 of file libtpcimgio.h.

◆ SCANNER_RODENT

#define SCANNER_RODENT   2001

Definition for scanner model (system type): nonstandard

Definition at line 1569 of file libtpcimgio.h.

◆ SCANNER_STEVCT_CT

#define SCANNER_STEVCT_CT   7

Definition for scanner model (system type): nonstandard

Definition at line 1562 of file libtpcimgio.h.

◆ SCANNER_STEVCT_PET

#define SCANNER_STEVCT_PET   6

Definition for scanner model (system type): nonstandard

Definition at line 1560 of file libtpcimgio.h.

Referenced by imgSetScanner().

◆ SCANNER_TUEBINGEN_PET_MR

#define SCANNER_TUEBINGEN_PET_MR   8000

Definition for scanner model (system type): nonstandard

Definition at line 1583 of file libtpcimgio.h.

◆ SCANNER_UNKNOWN

#define SCANNER_UNKNOWN   0

Definition for scanner model (system type)

Definition at line 1547 of file libtpcimgio.h.

Referenced by imgFormatDetermine().

◆ SUN_I2

◆ SUN_I4

◆ VAX_I2

◆ VAX_I4

◆ VAX_R4

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Definitions for IMG struct status message

Definition at line 1589 of file libtpcimgio.h.

1589 {STATUS_OK,STATUS_FAULT,STATUS_NOMEMORY,STATUS_NOFILE,STATUS_UNKNOWNFORMAT,
1590 STATUS_UNSUPPORTED,STATUS_MISSINGMATRIX,STATUS_NOWRITEPERM,STATUS_DISKFULL,
1591 STATUS_NOMATLIST,STATUS_INVALIDMATLIST,STATUS_VARMATSIZE,STATUS_NOMAINHEADER,
1592 STATUS_NOSUBHEADER, STATUS_NOMATRIX, STATUS_UNSUPPORTEDAXIALCOMP,
1593 STATUS_NOIMGDATAFILE, STATUS_NOHEADERFILE, STATUS_INVALIDHEADER,
1594 STATUS_NOIMGDATA, STATUS_NOSIFDATA, STATUS_WRONGSIFDATA,
1595 STATUS_CANTWRITEIMGFILE, STATUS_CANTWRITEHEADERFILE, STATUS_WRONGFILETYPE,
1596 STATUS_CANNOTERASE, STATUS_CANNOTREAD, STATUS_CANNOTWRITE,
1597 STATUS_UNSUPPORTEDPOLARMAP, STATUS_INVALIDPOLARMAP};

◆ dcmtruid

enum dcmtruid

DICOM Transfer Syntax UID.

In case of implicit VR, elements do NOT contain VR ! Reference: DICOM PS3.5 2017a chapter 10.

Items must be the same and in the same order as the dcm_truid list.

Enumerator
DCM_TRUID_UNKNOWN 

Unknown Transfer Syntax UID

DCM_TRUID_LEI 

Little Endian Implicit VR (DICOM default)

DCM_TRUID_LEE 

Little Endian Explicit VR.

DCM_TRUID_BEE 

Big Endian Explicit VR.

DCM_TRUID_JPEG50 

Lossy JPEG 8-bit compression.

DCM_TRUID_JPEG51 

Lossy JPEG 12-bit compression.

DCM_TRUID_JPEG70 

Lossless JPEG.

DCM_TRUID_JPEG80 

Lossless JPEG-LS.

DCM_TRUID_JPEG81 

Lossy JPEG-LS.

DCM_TRUID_JPEG90 

Lossless JPEG 2000.

DCM_TRUID_JPEG91 

JPEG 2000.

DCM_TRUID_JPEG92 

Lossless multicomponent JPEG 2000.

DCM_TRUID_JPEG93 

Multicomponent JPEG 2000.

DCM_TRUID_MPEG100 

MPEG-2.

DCM_TRUID_MPEG102 

MPEG-4.

DCM_TRUID_MPEG103 

MPEG-4 BD-compatible.

DCM_TRUID_RLE 

Lossless RLE.

DCM_TRUID_RFC 

RFC 2557.

DCM_TRUID_XML 

XML encoding.

DCM_TRUID_INVALID 

Invalid Transfer Syntax UID.

Definition at line 2818 of file libtpcimgio.h.

2818 {
2839} dcmtruid;
dcmtruid
@ DCM_TRUID_LEI
Little Endian Implicit VR (DICOM default)
@ DCM_TRUID_JPEG81
Lossy JPEG-LS.
@ DCM_TRUID_JPEG93
Multicomponent JPEG 2000.
@ DCM_TRUID_MPEG100
MPEG-2.
@ DCM_TRUID_JPEG92
Lossless multicomponent JPEG 2000.
@ DCM_TRUID_JPEG91
JPEG 2000.
@ DCM_TRUID_JPEG70
Lossless JPEG.
@ DCM_TRUID_XML
XML encoding.
@ DCM_TRUID_INVALID
Invalid Transfer Syntax UID.
@ DCM_TRUID_MPEG103
MPEG-4 BD-compatible.
@ DCM_TRUID_RFC
RFC 2557.
@ DCM_TRUID_JPEG80
Lossless JPEG-LS.
@ DCM_TRUID_UNKNOWN
Unknown Transfer Syntax UID
@ DCM_TRUID_BEE
Big Endian Explicit VR.
@ DCM_TRUID_JPEG51
Lossy JPEG 12-bit compression.
@ DCM_TRUID_RLE
Lossless RLE.
@ DCM_TRUID_LEE
Little Endian Explicit VR.
@ DCM_TRUID_JPEG90
Lossless JPEG 2000.
@ DCM_TRUID_JPEG50
Lossy JPEG 8-bit compression.
@ DCM_TRUID_MPEG102
MPEG-4.

◆ dcmvr

enum dcmvr

DICOM value representation (VR).

Reference: DICOM PS3.5 2017a chapter 6.2.

Items must be the same and in the same order as the dcm_vr list.

Enumerator
DCM_VR_AE 

DICOM application entity, max 16 bytes.

DCM_VR_AS 

DICOM age string, 4 bytes fixed.

DCM_VR_AT 

DICOM attribute tag, 4 bytes fixed.

DCM_VR_CS 

DICOM code (control) string, max 16 bytes.

DCM_VR_DA 

DICOM date in format YYYYMMDD, 8 bytes fixed.

Note
In old standard 10 bytes fixed, in format YYYY.MM.DD
DCM_VR_DS 

DICOM decimal string, max 16 bytes.

DCM_VR_DT 

DICOM date time, max 26 bytes.

DCM_VR_FL 

DICOM floating point single precision, 4 bytes fixed.

DCM_VR_FD 

DICOM floating point double precision, 8 bytes fixed.

DCM_VR_IS 

DICOM integer string, max 12 bytes.

DCM_VR_LO 

DICOM long string, max 64 chars.

DCM_VR_LT 

DICOM long text, max 10240 chars.

DCM_VR_OB 

DICOM other byte string, even bytes, endian insensitive.

DCM_VR_OD 

DICOM other double (64-bit) stream, endian sensitive.

DCM_VR_OF 

DICOM other float (32-bit) stream, endian sensitive.

DCM_VR_OL 

DICOM other long (32-bit) stream, endian sensitive.

DCM_VR_OW 

DICOM other word (16-bit) stream, even bytes, endian sensitive.

DCM_VR_PN 

DICOM person name, max 64 chars per component group.

DCM_VR_SH 

DICOM short string, max 16 chars.

DCM_VR_SL 

DICOM signed long (32-bit integer), 4 bytes fixed.

DCM_VR_SQ 

DICOM sequence of zero or more elements (used for nested data).

DCM_VR_SS 

DICOM signed short (16-bit integer), 2 bytes fixed.

DCM_VR_ST 

DICOM short text, max 1024 chars.

DCM_VR_TM 

DICOM time HHMMSS.FFFFFF, max 14 bytes.

Note
In old standard 16 bytes max.
DCM_VR_UC 

DICOM unlimited characters.

DCM_VR_UI 

DICOM unique identifier (UID), max 64 bytes.

DCM_VR_UL 

DICOM unsigned long (32-bit) integer, 4 bytes fixed.

DCM_VR_UN 

DICOM unknown, any valid length of another VR.

DCM_VR_UR 

DICOM URI or URL, string of characters.

DCM_VR_US 

DICOM unsigned short (16-bit) integer, 2 bytes fixed.

DCM_VR_UT 

DICOM unlimited text, character string.

DCM_VR_INVALID 

Invalid DICOM value representation.

Definition at line 2847 of file libtpcimgio.h.

2847 {
2848 DCM_VR_AE,
2849 DCM_VR_AS,
2850 DCM_VR_AT,
2851 DCM_VR_CS,
2852 DCM_VR_DA,
2853 DCM_VR_DS,
2854 DCM_VR_DT,
2855 DCM_VR_FL,
2856 DCM_VR_FD,
2857 DCM_VR_IS,
2858 DCM_VR_LO,
2859 DCM_VR_LT,
2860 DCM_VR_OB,
2861 DCM_VR_OD,
2862 DCM_VR_OF,
2863 DCM_VR_OL,
2864 DCM_VR_OW,
2865 DCM_VR_PN,
2866 DCM_VR_SH,
2867 DCM_VR_SL,
2868 DCM_VR_SQ,
2869 DCM_VR_SS,
2870 DCM_VR_ST,
2871 DCM_VR_TM,
2872 DCM_VR_UC,
2873 DCM_VR_UI,
2874 DCM_VR_UL,
2875 DCM_VR_UN,
2876 DCM_VR_UR,
2877 DCM_VR_US,
2878 DCM_VR_UT,
2880} dcmvr;
dcmvr
@ DCM_VR_INVALID
Invalid DICOM value representation.
@ DCM_VR_DT
DICOM date time, max 26 bytes.
@ DCM_VR_UI
DICOM unique identifier (UID), max 64 bytes.
@ DCM_VR_FD
DICOM floating point double precision, 8 bytes fixed.
@ DCM_VR_UC
DICOM unlimited characters.
@ DCM_VR_PN
DICOM person name, max 64 chars per component group.
@ DCM_VR_CS
DICOM code (control) string, max 16 bytes.
@ DCM_VR_SS
DICOM signed short (16-bit integer), 2 bytes fixed.
@ DCM_VR_SH
DICOM short string, max 16 chars.
@ DCM_VR_OF
DICOM other float (32-bit) stream, endian sensitive.
@ DCM_VR_UT
DICOM unlimited text, character string.
@ DCM_VR_US
DICOM unsigned short (16-bit) integer, 2 bytes fixed.
@ DCM_VR_TM
DICOM time HHMMSS.FFFFFF, max 14 bytes.
@ DCM_VR_OB
DICOM other byte string, even bytes, endian insensitive.
@ DCM_VR_AS
DICOM age string, 4 bytes fixed.
@ DCM_VR_ST
DICOM short text, max 1024 chars.
@ DCM_VR_AT
DICOM attribute tag, 4 bytes fixed.
@ DCM_VR_LT
DICOM long text, max 10240 chars.
@ DCM_VR_DA
DICOM date in format YYYYMMDD, 8 bytes fixed.
@ DCM_VR_UL
DICOM unsigned long (32-bit) integer, 4 bytes fixed.
@ DCM_VR_UN
DICOM unknown, any valid length of another VR.
@ DCM_VR_DS
DICOM decimal string, max 16 bytes.
@ DCM_VR_OW
DICOM other word (16-bit) stream, even bytes, endian sensitive.
@ DCM_VR_IS
DICOM integer string, max 12 bytes.
@ DCM_VR_AE
DICOM application entity, max 16 bytes.
@ DCM_VR_UR
DICOM URI or URL, string of characters.
@ DCM_VR_LO
DICOM long string, max 64 chars.
@ DCM_VR_SQ
DICOM sequence of zero or more elements (used for nested data).
@ DCM_VR_FL
DICOM floating point single precision, 4 bytes fixed.
@ DCM_VR_SL
DICOM signed long (32-bit integer), 4 bytes fixed.
@ DCM_VR_OL
DICOM other long (32-bit) stream, endian sensitive.
@ DCM_VR_OD
DICOM other double (64-bit) stream, endian sensitive.

Function Documentation

◆ anaDatabaseExists()

int anaDatabaseExists ( const char * dbname,
char * hdrfile,
char * imgfile,
char * siffile )
extern

Check if Analyze database files exist (*.hdr, *.img, and optionally *.sif).

Returns
Returns 0, if files do not exist, 1 if .img and .hdr do exist, and 2, if also .sif exists.
See also
anaExists, anaRemove, anaRemoveFNameExtension
Parameters
dbnameanalyze database name that is tested. String may contain standard extensions .hdr, .img or .sif
hdrfilepointer to an allocated string, where existing header filename is written. If not found, then set to "". NULL can be entered, if not needed.
imgfilepointer to an allocated string, where existing image filename is written. If not found, then set to "". NULL can be entered, if not needed.
siffilepointer to an allocated string, where existing sif filename is written. If not found, then set to "". NULL can be entered, if not needed.

Definition at line 704 of file analyze.c.

717 {
718 char temp[FILENAME_MAX], database[FILENAME_MAX];
719 int checked=0;
720
721 if(ANALYZE_TEST)
722 printf("\nanaDatabaseExists(%s, *hdrfile, *imgfile, *siffile)\n", dbname);
723
724 /* Check the input */
725 if(hdrfile!=NULL) strcpy(hdrfile, "");
726 if(imgfile!=NULL) strcpy(imgfile, "");
727 if(siffile!=NULL) strcpy(siffile, "");
728 if(dbname==NULL || strlen(dbname)==0) return(0);
729
730 strcpy(database, dbname);
731 while(1) {
732 /* Header file? */
733 strcpy(temp, database); strcat(temp, ".hdr");
734 if(access(temp, 0) != -1) {
735 /* Also image file? */
736 strcpy(temp, database); strcat(temp, ".img");
737 if(access(temp, 0) != -1) {
738 if(hdrfile!=NULL) sprintf(hdrfile, "%s.hdr", database);
739 if(imgfile!=NULL) sprintf(imgfile, "%s.img", database);
740 /* Even SIF? */
741 if(anaMakeSIFName(database, temp)==0) { /* yes! */
742 if(siffile!=NULL) strcpy(siffile, temp);
743 return(2);
744 }
745 /* Image and header files did exist anyway */
746 return(1);
747 }
748 }
749 if(checked==1) break;
750 /* Try to remove extension */
751 anaRemoveFNameExtension(database);
752 checked=1;
753 } /* try again */
754 return(0);
755}
int anaMakeSIFName(const char *dbname, char *siffile)
Definition analyze.c:763
void anaRemoveFNameExtension(char *fname)
Definition analyze.c:687
int ANALYZE_TEST
Definition analyze.c:8

Referenced by anaRemove(), imgFormatDetermine(), imgReadAnalyzeFrame(), imgReadAnalyzeHeader(), and imgWriteAnalyzeFrame().

◆ anaEditHeader()

int anaEditHeader ( ANALYZE_DSR * h,
char * field,
char * value )
extern

Edits Analyze 7.5 header.

Returns
Returns 0, if ok, and 1 or 2, if field name or or value is invalid.
See also
anaReadHeader, imgSetAnalyzeHeader, imgReadAnalyzeHeader
Parameters
hPointer to Analyze header struct.
fieldHeader field name.
valueNew value for the header field.

Definition at line 783 of file analyze.c.

790 {
791 int ii;
792 short int si;
793 float f;
794
795 si=atoi(value); ii=atoi(value); f=atof(value);
796 /* Header keys */
797 if(strcmp(field, "header_key.sizeof_hdr")==0 || strcmp(field, "sizeof_hdr")==0) {
798 h->hk.sizeof_hdr=ii;
799 } else if(strcmp(field, "header_key.data_type")==0 || strcmp(field, "data_type")==0) {
800 strlcpy(h->hk.data_type, value, 10);
801 } else if(strcmp(field, "header_key.db_name")==0 || strcmp(field, "db_name")==0) {
802 strlcpy(h->hk.db_name, value, 18);
803 } else if(strcmp(field, "header_key.extents")==0 || strcmp(field, "extents")==0) {
804 h->hk.extents=ii;
805 } else if(strcmp(field, "header_key.session_error")==0 || strcmp(field, "session_error")==0) {
806 h->hk.session_error=si;
807 } else if(strcmp(field, "header_key.regular")==0 || strcmp(field, "regular")==0) {
808 h->hk.regular=value[0];
809 } else if(strcmp(field, "header_key.hkey_un0")==0 || strcmp(field, "hkey_un0")==0) {
810 h->hk.hkey_un0=value[0];
811 /* Header imgdim */
812 } else if(strcmp(field, "header_image_dimension.dim")==0 || strcmp(field, "dim")==0) {
813 sscanf(value, "%hd %hd %hd %hd %hd %hd %hd %hd",
814 h->dime.dim+0, h->dime.dim+1, h->dime.dim+2, h->dime.dim+3,
815 h->dime.dim+4, h->dime.dim+5, h->dime.dim+6, h->dime.dim+7
816 );
817 } else if(strcmp(field, "header_image_dimension.unused8")==0 || strcmp(field, "unused8")==0) {
818 h->dime.unused8=si;
819 } else if(strcmp(field, "header_image_dimension.unused9")==0 || strcmp(field, "unused9")==0) {
820 h->dime.unused9=si;
821 } else if(strcmp(field, "header_image_dimension.unused10")==0 || strcmp(field, "unused10")==0) {
822 h->dime.unused10=si;
823 } else if(strcmp(field, "header_image_dimension.unused11")==0 || strcmp(field, "unused11")==0) {
824 h->dime.unused11=si;
825 } else if(strcmp(field, "header_image_dimension.unused12")==0 || strcmp(field, "unused12")==0) {
826 h->dime.unused12=si;
827 } else if(strcmp(field, "header_image_dimension.unused13")==0 || strcmp(field, "unused13")==0) {
828 h->dime.unused13=si;
829 } else if(strcmp(field, "header_image_dimension.unused14")==0 || strcmp(field, "unused14")==0) {
830 h->dime.unused14=si;
831 } else if(strcmp(field, "header_image_dimension.datatype")==0 || strcmp(field, "datatype")==0) {
832 h->dime.datatype=si;
833 } else if(strcmp(field, "header_image_dimension.bitpix")==0 || strcmp(field, "bitpix")==0) {
834 h->dime.bitpix=si;
835 } else if(strcmp(field, "header_image_dimension.dim_un0")==0 || strcmp(field, "dim_un0")==0) {
836 h->dime.dim_un0=si;
837 } else if(strcmp(field, "header_image_dimension.pixdim")==0 || strcmp(field, "pixdim")==0) {
838 sscanf(value, "%f %f %f %f %f %f %f %f",
839 h->dime.pixdim+0, h->dime.pixdim+1, h->dime.pixdim+2, h->dime.pixdim+3,
840 h->dime.pixdim+4, h->dime.pixdim+5, h->dime.pixdim+6, h->dime.pixdim+7
841 );
842 } else if(strcmp(field, "header_image_dimension.vox_offset")==0 || strcmp(field, "vox_offset")==0) {
843 h->dime.vox_offset=f;
844 } else if(strcmp(field, "header_image_dimension.funused1")==0 || strcmp(field, "funused1")==0) {
845 h->dime.funused1=f;
846 } else if(strcmp(field, "header_image_dimension.funused2")==0 || strcmp(field, "funused2")==0) {
847 h->dime.funused2=f;
848 } else if(strcmp(field, "header_image_dimension.funused3")==0 || strcmp(field, "funused3")==0) {
849 h->dime.funused3=f;
850 } else if(strcmp(field, "header_image_dimension.cal_max")==0 || strcmp(field, "cal_max")==0) {
851 h->dime.cal_max=f;
852 } else if(strcmp(field, "header_image_dimension.cal_min")==0 || strcmp(field, "cal_min")==0) {
853 h->dime.cal_min=f;
854 } else if(strcmp(field, "header_image_dimension.compressed")==0 || strcmp(field, "compressed")==0) {
855 h->dime.compressed=f;
856 } else if(strcmp(field, "header_image_dimension.verified")==0 || strcmp(field, "verified")==0) {
857 h->dime.verified=f;
858 } else if(strcmp(field, "header_image_dimension.glmax")==0 || strcmp(field, "glmax")==0) {
859 h->dime.glmax=ii;
860 } else if(strcmp(field, "header_image_dimension.glmin")==0 || strcmp(field, "glmin")==0) {
861 h->dime.glmin=ii;
862 /* Header history */
863 } else if(strcmp(field, "header_data_history.descrip")==0 || strcmp(field, "descrip")==0) {
864 strlcpy(h->hist.descrip, value, 80);
865 } else if(strcmp(field, "header_data_history.aux_file")==0 || strcmp(field, "aux_file")==0) {
866 strlcpy(h->hist.aux_file, value, 24);
867 } else if(strcmp(field, "header_data_history.orient")==0 || strcmp(field, "orient")==0) {
868 h->hist.orient=value[0];
869 } else if(strcmp(field, "header_data_history.originator")==0 || strcmp(field, "originator")==0) {
870 strlcpy(h->hist.originator, value, 10);
871 } else if(strcmp(field, "header_data_history.generated")==0 || strcmp(field, "generated")==0) {
872 strlcpy(h->hist.generated, value, 10);
873 } else if(strcmp(field, "header_data_history.scannum")==0 || strcmp(field, "scannum")==0) {
874 strlcpy(h->hist.scannum, value, 10);
875 } else if(strcmp(field, "header_data_history.patient_id")==0 || strcmp(field, "patient_id")==0) {
876 strlcpy(h->hist.patient_id, value, 10);
877 } else if(strcmp(field, "header_data_history.exp_date")==0 || strcmp(field, "exp_date")==0) {
878 strlcpy(h->hist.exp_date, value, 10);
879 } else if(strcmp(field, "header_data_history.exp_time")==0 || strcmp(field, "exp_time")==0) {
880 strlcpy(h->hist.exp_time, value, 10);
881 } else if(strcmp(field, "header_data_history.hist_un0")==0 || strcmp(field, "hist_un0")==0) {
882 memcpy(h->hist.hist_un0, value, 3);
883 } else if(strcmp(field, "header_data_history.views")==0 || strcmp(field, "views")==0) {
884 h->hist.views=ii;
885 } else if(strcmp(field, "header_data_history.vols_added")==0 || strcmp(field, "vols_added")==0) {
886 h->hist.vols_added=ii;
887 } else if(strcmp(field, "header_data_history.start_field")==0 || strcmp(field, "start_field")==0) {
888 h->hist.start_field=ii;
889 } else if(strcmp(field, "header_data_history.field_skip")==0 || strcmp(field, "field_skip")==0) {
890 h->hist.field_skip=ii;
891 } else if(strcmp(field, "header_data_history.omax")==0 || strcmp(field, "omax")==0) {
892 h->hist.omax=ii;
893 } else if(strcmp(field, "header_data_history.omin")==0 || strcmp(field, "omin")==0) {
894 h->hist.omin=ii;
895 } else if(strcmp(field, "header_data_history.smax")==0 || strcmp(field, "smax")==0) {
896 h->hist.smax=ii;
897 } else if(strcmp(field, "header_data_history.smin")==0 || strcmp(field, "smin")==0) {
898 h->hist.smin=ii;
899 } else
900 return(1);
901
902 return(0);
903}
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
ANALYZE_HEADER_HISTORY hist
ANALYZE_HEADER_KEY hk
ANALYZE_HEADER_IMGDIM dime
short int session_error
Definition libtpcimgio.h:84

◆ anaExists()

int anaExists ( const char * dbname)
extern

Check if Analyze files exist.

Parameters
dbnamebasename of Analyze 7.5 file.
Returns
0, if they do not, 1 if .img and .hdr do exist, and 2, if also .sif exists.

Definition at line 20 of file analyze.c.

22 {
23 char temp[FILENAME_MAX];
24
25 if(dbname==NULL || strlen(dbname)==0) return(0);
26 /* Header file? */
27 strlcpy(temp, dbname, FILENAME_MAX); strlcat(temp, ".hdr", FILENAME_MAX);
28 if(access(temp, 0) == -1) return(0);
29 /* Image data? */
30 strlcpy(temp, dbname, FILENAME_MAX); strlcat(temp, ".img", FILENAME_MAX);
31 if(access(temp, 0) == -1) return(0);
32 /* SIF? */
33 strlcat(temp, ".sif", FILENAME_MAX); if(access(temp, 0) != -1) return(2);
34 strlcpy(temp, dbname, FILENAME_MAX); strlcat(temp, ".sif", FILENAME_MAX);
35 if(access(temp, 0) != -1) return(2);
36 return(1);
37}
size_t strlcat(char *dst, const char *src, size_t dstsize)
Definition strext.c:206

◆ anaExistsNew()

int anaExistsNew ( const char * filename,
char * hdrfile,
char * imgfile,
char * siffile )
extern

Check if specified filename is a Analyze file.

Returns
Returns 0 if it is not, 1 if it is, and both image and header is found, and 2, if sif file is found too.
Parameters
filenameFilename, either header file, image file, or base name without extensions. this string is never modified.
hdrfileIf filename refers to a Analyze file, then header filename will be written in this char pointer (space needs to allocated by caller); NULL if not needed.
imgfileIf filename refers to a Analyze file, then image filename will be written in this char pointer (space needs to allocated by caller); NULL if not needed.
siffileIf filename refers to a Analyze file, and if SIF exists, then SIF filename will be written in this char pointer (space needs to allocated by caller); NULL if not needed.

Definition at line 45 of file analyze.c.

61 {
62 char *cptr, basefile[FILENAME_MAX], temp[FILENAME_MAX];
64 int ret;
65
66 if(filename==NULL || strlen(filename)==0) return(0);
67 if(ANALYZE_TEST>1) printf("\nanaExistsNew(%s, *str, *str, *str)\n", filename);
68
69 /* Construct the base file name wo extensions */
70 strcpy(basefile, filename);
71 cptr=strrchr(basefile, '.');
72 if(cptr!=NULL) {
73 if(strncasecmp(cptr, ".HDR", 4)==0 || strncasecmp(cptr, ".IMG", 4)==0 )
74 *cptr=(char)0;
75 }
76 cptr=strrchr(basefile, '.');
77 if(cptr!=NULL) {
78 if(strncasecmp(cptr, ".IMG", 4)==0 )
79 *cptr=(char)0;
80 }
81 if(ANALYZE_TEST>2) printf("\n basefile := %s\n", basefile);
82
83 /* Header file exists? */
84 strcpy(temp, basefile); strcat(temp, ".hdr");
85 if(access(temp, 0) == -1) {
86 strcpy(temp, basefile); strcat(temp, ".img.hdr");
87 if(access(temp, 0) == -1) {
88 if(ANALYZE_TEST) printf("\n hdr file not found or accessible.\n");
89 return(0);
90 }
91 }
92 /* Is this Analyze header file? */
93 if((ret=anaReadHeader(temp, &h))!=0) {
94 if(ANALYZE_TEST) printf("\n %s was not identified as Analyze header file (%d).\n", temp, ret);
95 return(0);
96 }
97 /* Preserve header filename */
98 if(hdrfile!=NULL) strcpy(hdrfile, temp);
99
100 /* Image file exists? */
101 strcpy(temp, basefile); strcat(temp, ".img");
102 if(access(temp, 0) == -1) {
103 if(ANALYZE_TEST) printf("\n %s not found or accessible.\n", temp);
104 return(0);
105 }
106 /* Preserve image filename */
107 if(imgfile!=NULL) strcpy(imgfile, temp);
108
109 /* SIF exists? */
110 strcpy(temp, basefile); strcat(temp, ".sif");
111 if(access(temp, 0) == -1) {
112 strcpy(temp, basefile); strcat(temp, ".img.sif");
113 if(access(temp, 0) == -1) {
114 if(ANALYZE_TEST) printf("\n SIF not found or accessible.\n");
115 if(siffile!=NULL) strcpy(siffile, "");
116 return(1); // but otherwise ok
117 }
118 }
119 /* Preserve SIF filename */
120 if(siffile!=NULL) strcpy(siffile, temp);
121 return(2);
122}
int anaReadHeader(char *filename, ANALYZE_DSR *h)
Definition analyze.c:131

Referenced by imgRead(), and imgReadAnalyze().

◆ anaFlipping()

int anaFlipping ( )
extern

Check whether Analyze image is flipped in z-direction when it is read from/written to file (x,y-flipping is done always).

Returns
1 if Analyze data is flipped.
See also
anaReadHeader, anaEditHeader, anaReadImagedata

Definition at line 635 of file analyze.c.

635 {
636 int ret;
637 char *cptr;
638
639 /* Is there an environment variable name for flipping? */
640 cptr=getenv("ANALYZE_FLIP");
641 if(cptr==NULL) cptr=getenv("ANALYZE_FLIPPING");
642 if(cptr==NULL) cptr=getenv("analyze_flip");
643 if(cptr==NULL) cptr=getenv("analyze_flipping");
644 if(cptr==NULL) {
645 if(ANALYZE_TEST>1) printf("ANALYZE_FLIP = not defined\n");
646 ret=ANALYZE_FLIP_DEFAULT; /* if not, then use default value */
647 } else {
648 if(ANALYZE_TEST>1) printf("ANALYZE_FLIP = '%s'\n", cptr);
649 if(*cptr=='y' || *cptr=='Y' || *cptr=='1') ret=1;
650 else if(*cptr=='n' || *cptr=='N' || *cptr=='0') ret=0;
651 else ret=ANALYZE_FLIP_DEFAULT;
652 }
653 if(ANALYZE_TEST) printf("anaFlipping()=%d\n", ret);
654 return(ret);
655}

Referenced by imgAnalyzeToEcat(), imgReadAnalyze(), imgReadAnalyzeFrame(), imgWriteAnalyze(), and imgWriteAnalyzeFrame().

◆ anaMakeSIFName()

int anaMakeSIFName ( const char * dbname,
char * siffile )
extern

Make SIF filename from Analyze 7.5 database name.

Returns
Returns 0 if SIF file is accessible, 1 if invalid input, 2 if sif name not found.
See also
anaDatabaseExists, anaExists
Parameters
dbnameAnalyze 7.5 database name (including possible path but not extension.
siffilePointer to allocated space for SIF filename.

Definition at line 763 of file analyze.c.

768 {
769 if(dbname==NULL || siffile==NULL) return(1);
770 sprintf(siffile, "%s.sif", dbname); if(access(siffile, 0) != -1) return(0);
771 sprintf(siffile, "%s.SIF", dbname); if(access(siffile, 0) != -1) return(0);
772 sprintf(siffile, "%s.img.sif", dbname); if(access(siffile, 0) != -1) return(0);
773 sprintf(siffile, "%s.IMG.SIF", dbname); if(access(siffile, 0) != -1) return(0);
774 sprintf(siffile, "%s.sif", dbname); return(2);
775}

Referenced by anaDatabaseExists().

◆ anaPrintHeader()

int anaPrintHeader ( ANALYZE_DSR * h,
FILE * fp )
extern

Print the contents of Analyze header to specified file pointer.

Returns
Returns 0 if ok, 1 if invalid input
See also
anaReadHeader
Parameters
hPointer to Analyze header structure.
fpOutput file pointer.

Definition at line 380 of file analyze.c.

385 {
386 if(fp==NULL || h==NULL) return(1);
387 fprintf(fp, "original_byte_order := %d (1=little, 0=big)\n", h->little);
388 /* Key */
389 fprintf(fp, "header_key.sizeof_hdr := %d\n", h->hk.sizeof_hdr);
390 fprintf(fp, "header_key.data_type := %.10s\n", h->hk.data_type);
391 fprintf(fp, "header_key.db_name := %.18s\n", h->hk.db_name);
392 fprintf(fp, "header_key.extents := %d\n", h->hk.extents);
393 fprintf(fp, "header_key.session_error := %d\n", h->hk.session_error);
394 fprintf(fp, "header_key.regular := %d (%c)\n",
395 (int)h->hk.regular, h->hk.regular);
396 fprintf(fp, "header_key.hkey_un0 := %d\n", (int)h->hk.hkey_un0);
397 /* Image dimension */
398 fprintf(fp, "header_image_dimension.dim :=");
399 for(int i=0; i<8; i++) fprintf(fp, " %d", h->dime.dim[i]);
400 fprintf(fp, "\n");
401 fprintf(fp, "header_image_dimension.unused8 := %d\n", h->dime.unused8);
402 fprintf(fp, "header_image_dimension.unused9 := %d\n", h->dime.unused9);
403 fprintf(fp, "header_image_dimension.unused10 := %d\n", h->dime.unused10);
404 fprintf(fp, "header_image_dimension.unused11 := %d\n", h->dime.unused11);
405 fprintf(fp, "header_image_dimension.unused12 := %d\n", h->dime.unused12);
406 fprintf(fp, "header_image_dimension.unused13 := %d\n", h->dime.unused13);
407 fprintf(fp, "header_image_dimension.unused14 := %d\n", h->dime.unused14);
408 fprintf(fp, "header_image_dimension.datatype := %d\n", h->dime.datatype);
409 fprintf(fp, "header_image_dimension.bitpix := %d\n", h->dime.bitpix);
410 fprintf(fp, "header_image_dimension.dim_un0 := %d\n", h->dime.dim_un0);
411 fprintf(fp, "header_image_dimension.pixdim :=");
412 for(int i=0; i<8; i++) fprintf(fp, " %g", h->dime.pixdim[i]);
413 fprintf(fp, "\n");
414 fprintf(fp, "header_image_dimension.vox_offset := %g\n", h->dime.vox_offset);
415 fprintf(fp, "header_image_dimension.funused1 := %g\n", h->dime.funused1);
416 fprintf(fp, "header_image_dimension.funused2 := %g\n", h->dime.funused2);
417 fprintf(fp, "header_image_dimension.funused3 := %g\n", h->dime.funused3);
418 fprintf(fp, "header_image_dimension.cal_max := %g\n", h->dime.cal_max);
419 fprintf(fp, "header_image_dimension.cal_min := %g\n", h->dime.cal_min);
420 fprintf(fp, "header_image_dimension.compressed := %g\n", h->dime.compressed);
421 fprintf(fp, "header_image_dimension.verified := %g\n", h->dime.verified);
422 fprintf(fp, "header_image_dimension.glmax := %d\n", h->dime.glmax);
423 fprintf(fp, "header_image_dimension.glmin := %d\n", h->dime.glmin);
424 /* Data history */
425 fprintf(fp, "header_data_history.descrip := %s.80\n", h->hist.descrip);
426 fprintf(fp, "header_data_history.aux_file := %.24s\n", h->hist.aux_file);
427 fprintf(fp, "header_data_history.orient := %d\n", (int)h->hist.orient);
428 fprintf(fp, "header_data_history.originator := %.10s\n", h->hist.originator);
429 fprintf(fp, "header_data_history.generated := %.10s\n", h->hist.generated);
430 fprintf(fp, "header_data_history.scannum := %.10s\n", h->hist.scannum);
431 fprintf(fp, "header_data_history.patient_id := %.10s\n", h->hist.patient_id);
432 fprintf(fp, "header_data_history.exp_date := %.10s\n", h->hist.exp_date);
433 fprintf(fp, "header_data_history.exp_time := %.10s\n", h->hist.exp_time);
434 fprintf(fp, "header_data_history.hist_un0 := %.3s\n", h->hist.hist_un0);
435 fprintf(fp, "header_data_history.views := %d\n", h->hist.views);
436 fprintf(fp, "header_data_history.vols_added := %d\n", h->hist.vols_added);
437 fprintf(fp, "header_data_history.start_field := %d\n", h->hist.start_field);
438 fprintf(fp, "header_data_history.field_skip := %d\n", h->hist.field_skip);
439 fprintf(fp, "header_data_history.omax := %d\n", h->hist.omax);
440 fprintf(fp, "header_data_history.omin := %d\n", h->hist.omin);
441 fprintf(fp, "header_data_history.smax := %d\n", h->hist.smax);
442 fprintf(fp, "header_data_history.smin := %d\n", h->hist.smin);
443
444 return(0);
445}

Referenced by imgReadAnalyze().

◆ anaReadHeader()

int anaReadHeader ( char * filename,
ANALYZE_DSR * h )
extern

Read analyze header contents.

Returns
0, if ok, 1 if invalid input, 2 if file cannot be opened, 3 if header could not be read, 4 if header image dimension could not be read.
See also
anaWriteHeader, anaPrintHeader, anaEditHeader, imgReadAnalyzeHeader, imgGetAnalyzeHeader
Parameters
filenameName of file to read (including path and extension).
hPointer to previously allocated header structure.

Definition at line 131 of file analyze.c.

136 {
137 unsigned char buf1[ANALYZE_HEADER_KEY_SIZE];
138 unsigned char buf2[ANALYZE_HEADER_IMGDIM_SIZE];
139 unsigned char buf3[ANALYZE_HEADER_HISTORY_SIZE];
140 int little; /* 1 if current platform is little endian (i386), else 0 */
141 FILE *fp;
142 int ret, nr=0, s1, s2, same_order;
143
144 if(ANALYZE_TEST) printf("anaReadHeader(%s, *dsr)\n", filename);
145
146 /* Check arguments */
147 if(strlen(filename)<1 || h==NULL) return(1);
148 little=little_endian();
149 /* Open file */
150 fp=fopen(filename, "rb"); if(fp==NULL) return(2);
151 /* Get file size */
152 nr=0; while((ret=fgetc(fp))!=EOF) nr++; rewind(fp);
153 if(nr<1) {fclose(fp); return(3);}
154 /* Read Analyze header key */
155 if(fread(buf1, ANALYZE_HEADER_KEY_SIZE, 1, fp)<1) return(3);
156 /* Read Analyze header image dimension */
157 if(fread(buf2, ANALYZE_HEADER_IMGDIM_SIZE, 1, fp)<1) return(3);
158 /* Read Analyze header image data history */
159 memset(buf3, 0, sizeof(ANALYZE_HEADER_HISTORY));
160 ret=fread(buf3, ANALYZE_HEADER_HISTORY_SIZE, 1, fp);
161 if(ANALYZE_TEST>1 && ret<1) printf(" complete data_history not found.\n");
162 /* Close file */
163 fclose(fp);
164 /* Compare file size from header contents to the calculated value */
165 /* to determine whether Analyze file is in little or big endian */
166 memcpy(&s1, buf1+0, 4); s2=s1; swawbip(&s2, 4);
167 if(abs(s1-nr)<abs(s2-nr)) same_order=1; else same_order=0;
168 if(ANALYZE_TEST>1) printf("same byte order: %d (s1=%d s2=%d nr=%d)\n",
169 same_order, s1, s2, nr);
170 if(same_order) h->little=little;
171 else {if(little) h->little=0; else h->little=1;}
172
173 /* Set key header structure contents */
174 if(!same_order) swawbip(buf1+0, 4);
175 memcpy(&h->hk.sizeof_hdr, buf1+0, 4);
176 memcpy(h->hk.data_type, buf1+4, 10);
177 memcpy(h->hk.db_name, buf1+14, 18);
178 if(!same_order) swawbip(buf1+32, 4);
179 memcpy(&h->hk.extents, buf1+32, 4);
180 if(!same_order) swabip(buf1+36, 2);
181 memcpy(&h->hk.session_error, buf1+36, 2);
182 memcpy(&h->hk.regular, buf1+38, 1);
183 memcpy(&h->hk.hkey_un0, buf1+39, 1);
184
185 /* Set image dimension header structure contents */
186 if(!same_order) swabip(buf2+0, 16);
187 memcpy(h->dime.dim, buf2+0, 16);
188 if(!same_order) swabip(buf2+16, 2);
189 memcpy(&h->dime.unused8, buf2+16, 2);
190 if(!same_order) swabip(buf2+18, 2);
191 memcpy(&h->dime.unused9, buf2+18, 2);
192 if(!same_order) swabip(buf2+20, 2);
193 memcpy(&h->dime.unused10, buf2+20, 2);
194 if(!same_order) swabip(buf2+22, 2);
195 memcpy(&h->dime.unused11, buf2+22, 2);
196 if(!same_order) swabip(buf2+24, 2);
197 memcpy(&h->dime.unused12, buf2+24, 2);
198 if(!same_order) swabip(buf2+26, 2);
199 memcpy(&h->dime.unused13, buf2+26, 2);
200 if(!same_order) swabip(buf2+28, 2);
201 memcpy(&h->dime.unused14, buf2+28, 2);
202 if(!same_order) swabip(buf2+30, 2);
203 memcpy(&h->dime.datatype, buf2+30, 2);
204 if(!same_order) swabip(buf2+32, 2);
205 memcpy(&h->dime.bitpix, buf2+32, 2);
206 if(!same_order) swabip(buf2+34, 2);
207 memcpy(&h->dime.dim_un0, buf2+34, 2);
208 if(!same_order) swawbip(buf2+36, 32);
209 memcpy(h->dime.pixdim, buf2+36, 32);
210 if(!same_order) swawbip(buf2+68, 4);
211 memcpy(&h->dime.vox_offset, buf2+68, 4);
212 if(!same_order) swawbip(buf2+72, 4);
213 memcpy(&h->dime.funused1, buf2+72, 4);
214 if(!same_order) swawbip(buf2+76, 4);
215 memcpy(&h->dime.funused2, buf2+76, 4);
216 if(!same_order) swawbip(buf2+80, 4);
217 memcpy(&h->dime.funused3, buf2+80, 4);
218 if(!same_order) swawbip(buf2+84, 4);
219 memcpy(&h->dime.cal_max, buf2+84, 4);
220 if(!same_order) swawbip(buf2+88, 4);
221 memcpy(&h->dime.cal_min, buf2+88, 4);
222 if(!same_order) swawbip(buf2+92, 4);
223 memcpy(&h->dime.compressed, buf2+92, 4);
224 if(!same_order) swawbip(buf2+96, 4);
225 memcpy(&h->dime.verified, buf2+96, 4);
226 if(!same_order) swawbip(buf2+100, 4);
227 memcpy(&h->dime.glmax, buf2+100, 4);
228 if(!same_order) swawbip(buf2+104, 4);
229 memcpy(&h->dime.glmin, buf2+104, 4);
230
231 /* Set data history header structure contents */
232 memcpy(h->hist.descrip, buf3+0, 80);
233 memcpy(h->hist.aux_file, buf3+80, 24);
234 memcpy(&h->hist.orient, buf3+104, 1);
235 memcpy(h->hist.originator, buf3+105, 10);
236 memcpy(h->hist.generated, buf3+115, 10);
237 memcpy(h->hist.scannum, buf3+125, 10);
238 memcpy(h->hist.patient_id, buf3+135, 10);
239 memcpy(h->hist.exp_date, buf3+145, 10);
240 memcpy(h->hist.exp_time, buf3+155, 10);
241 memcpy(h->hist.hist_un0, buf3+165, 3);
242 if(!same_order) swawbip(buf3+168, 4);
243 memcpy(&h->hist.views, buf3+168, 4);
244 if(!same_order) swawbip(buf3+172, 4);
245 memcpy(&h->hist.vols_added, buf3+172, 4);
246 if(!same_order) swawbip(buf3+176, 4);
247 memcpy(&h->hist.start_field, buf3+176,4);
248 if(!same_order) swawbip(buf3+180, 4);
249 memcpy(&h->hist.field_skip, buf3+180, 4);
250 if(!same_order) swawbip(buf3+184, 4);
251 memcpy(&h->hist.omax, buf3+184, 4);
252 if(!same_order) swawbip(buf3+188, 4);
253 memcpy(&h->hist.omin, buf3+188, 4);
254 if(!same_order) swawbip(buf3+192, 4);
255 memcpy(&h->hist.smax, buf3+192, 4);
256 if(!same_order) swawbip(buf3+196, 4);
257 memcpy(&h->hist.smin, buf3+196, 4);
258
259 /* Check header contents */
260 if(h->hk.extents!=16384 && h->hk.extents!=0) {
261 if(ANALYZE_TEST>1) printf("hk.extents := %d\n", h->hk.extents);
262 return(11);
263 }
264 if(h->hk.regular!='r') {
265 if(ANALYZE_TEST>1) printf("hk.regular := %c\n", h->hk.regular);
266 return(12);
267 }
268
269 return(0);
270}
void swabip(void *buf, long long int size)
Definition swap.c:72
void swawbip(void *buf, long long int size)
Definition swap.c:93
int little_endian()
Definition swap.c:14

Referenced by anaExistsNew(), imgReadAnalyze(), imgReadAnalyzeFrame(), imgReadAnalyzeHeader(), and imgWriteAnalyzeFrame().

◆ anaReadImagedata()

int anaReadImagedata ( FILE * fp,
ANALYZE_DSR * h,
int frame,
float * data )
extern

Read Analyze 7.5 image data, convert byte order if necessary, and scale values to floats. Reads only one frame at a time!

Returns
Returns 0 if ok, <>0 in case of an error.
See also
anaReadHeader
Parameters
fpFile, opened previously in binary mode.
hAnalyze header, read previously.
frameFrame number to read [1..number of frames].
dataPointer to image float data allocated previously.

Definition at line 454 of file analyze.c.

463 {
464 int little;
465 long int dimNr, dimx, dimy, dimz=1, dimt=1;
466 char *mdata, *mptr;
467 float f, *fptr;
468 short int *sptr;
469 int *iptr;
470 double d;
471
472
473 if(ANALYZE_TEST) printf("anaReadImagedata(fp, h, %d, data)\n", frame);
474
475 /* Check the arguments */
476 if(frame<=0 || fp==NULL || h==NULL || data==NULL) return(1);
477
478 /* Get the image dimensions from header */
479 dimNr=h->dime.dim[0]; if(dimNr<2) return(2);
480 dimx=h->dime.dim[1];
481 dimy=h->dime.dim[2];
482 if(dimNr>2) dimz=h->dime.dim[3];
483 if(dimNr>3) dimt=h->dime.dim[4];
484 if(frame>dimt) return(3);
485 long long pxlNr=dimx*dimy*dimz; if(pxlNr<1) return(4);
486
487 /* Allocate memory for the binary data */
488 if(h->dime.bitpix==0 && h->dime.datatype>0) { /* Fix bitpix if necessary */
492 else if(h->dime.datatype==ANALYZE_DT_SIGNED_INT) h->dime.bitpix=32;
493 else if(h->dime.datatype==ANALYZE_DT_FLOAT) h->dime.bitpix=32;
494 else if(h->dime.datatype==ANALYZE_DT_DOUBLE) h->dime.bitpix=64;
495 else if(h->dime.datatype==ANALYZE_DT_RGB) h->dime.bitpix=24;
496 }
497 if(h->dime.bitpix<8) return(5); /* We don't support bit data */
498 long long rawSize=pxlNr*(h->dime.bitpix/8); if(rawSize<1) return(5);
499 if(ANALYZE_TEST>0) printf(" pxlNr=%lld rawSize=%lld\n", pxlNr, rawSize);
500 mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11);
501
502 /* Seek the start of current frame data */
503 long long start_pos=(frame-1)*rawSize;
504 {
505 long int n=(long int)h->dime.vox_offset;
506 if((n>0 && frame==1) || (n<0)) start_pos+=labs(n);
507 }
508 if(ANALYZE_TEST>2) printf("start_pos=%lld\n", start_pos);
509 fseeko(fp, start_pos, SEEK_SET);
510 if(ftello(fp)!=start_pos) {
511 if(ANALYZE_TEST>5) printf("could not move to start_pos\n");
512 free(mdata); return(7);
513 }
514
515 /* Read the data */
516 mptr=mdata;
517 {
518 size_t n=fread(mptr, rawSize, 1, fp);
519 if(n<1) {
520 if(ANALYZE_TEST>5) printf("could read only %zu bytes when request was %lld\n", n, rawSize);
521 free(mdata); return(8);
522 }
523 }
524
525 /* Convert byte order if necessary */
526 little=little_endian(); mptr=mdata;
527 if(little!=h->little) {
528 if(ANALYZE_TEST>0) printf("byte conversion\n");
529 switch(h->dime.bitpix) {
530 case 8: /* no conversion needed */ break;
531 case 16: swabip(mptr, rawSize); break;
532 case 32: swawbip(mptr, rawSize); break;
533 case 64: swawbip(mptr, rawSize); break;
534 default:
535 if(ANALYZE_TEST>5) printf("unsupported anahdr.dime.bitpix := %d\n", h->dime.bitpix);
536 free(mdata); return(5);
537 }
538 }
539
540 /* Get scale factor */
541 f=1.0;
542 if(h->dime.funused1>0.0) f*=h->dime.funused1;
543
544 /* Copy data to float pixel values */
545 mptr=mdata; fptr=data;
546 switch(h->dime.datatype) {
548 if(h->dime.bitpix!=8) {
549 if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n",
550 h->dime.datatype, h->dime.bitpix);
551 free(mdata); return(5);
552 }
553 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
554 *fptr=f*(float)(unsigned char)(*mptr);
555 break;
557 if(h->dime.bitpix!=16) {
558 if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n",
559 h->dime.datatype, h->dime.bitpix);
560 free(mdata); return(5);
561 }
562 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
563 sptr=(short int*)mptr; *fptr=f*(float)(*sptr);
564 }
565 break;
567 if(h->dime.bitpix!=16 && h->dime.bitpix!=32) {
568 if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n",
569 h->dime.datatype, h->dime.bitpix);
570 free(mdata); return(5);
571 }
572 if(h->dime.bitpix==16) {
573 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
574 iptr=(int*)mptr; *fptr=f*(float)(*iptr);
575 }
576 } else if(h->dime.bitpix==32) {
577 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
578 iptr=(int*)mptr; *fptr=f*(float)(*iptr);
579 }
580 }
581 break;
582 case ANALYZE_DT_FLOAT:
583 if(h->dime.bitpix!=16 && h->dime.bitpix!=32) {
584 if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n",
585 h->dime.datatype, h->dime.bitpix);
586 free(mdata); return(5);
587 }
588 if(h->dime.bitpix==16) {
589 memcpy(fptr, mptr, pxlNr*2);
590 for(long long i=0; i<pxlNr; i++, fptr++) *fptr*=f;
591 } else if(h->dime.bitpix==32) {
592 memcpy(fptr, mptr, pxlNr*4);
593 for(long long i=0; i<pxlNr; i++, fptr++) *fptr*=f;
594 }
595 break;
597 if(h->dime.bitpix!=32) {
598 if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n",
599 h->dime.datatype, h->dime.bitpix);
600 free(mdata); return(5);
601 }
602 if(h->dime.bitpix==32) {
603 memcpy(fptr, mptr, pxlNr*4);
604 for(long long i=0; i<pxlNr; i++, fptr++) *fptr*=f;
605 }
606 break;
608 /* Add support for 64-bit double, if needed */
609 if(h->dime.bitpix!=32) {
610 if(ANALYZE_TEST>5) printf("invalid combination of datatype and bitpix (%d, %d)\n",
611 h->dime.datatype, h->dime.bitpix);
612 free(mdata); return(5);
613 }
614 for(long long i=0; i<pxlNr; i++, mptr+=8, fptr++) {
615 memcpy(&d, mptr, 8); *fptr=f*d;
616 }
617 break;
618 default:
619 if(ANALYZE_TEST>5) printf("unsupported anahdr.dime.datatype := %d\n", h->dime.datatype);
620 free(mdata); return(5);
621 }
622
623 free(mdata);
624 if(ANALYZE_TEST>1) printf("anaReadImagedata() succeeded\n");
625 return(0);
626}
#define ANALYZE_DT_SIGNED_INT
Definition libtpcimgio.h:57
#define ANALYZE_DT_COMPLEX
Definition libtpcimgio.h:61
#define ANALYZE_DT_SIGNED_SHORT
Definition libtpcimgio.h:55
#define ANALYZE_DT_BINARY
Definition libtpcimgio.h:51
#define ANALYZE_DT_RGB
Definition libtpcimgio.h:65
#define ANALYZE_DT_UNSIGNED_CHAR
Definition libtpcimgio.h:53
#define ANALYZE_DT_DOUBLE
Definition libtpcimgio.h:63
#define ANALYZE_DT_FLOAT
Definition libtpcimgio.h:59

Referenced by imgReadAnalyze(), and imgReadAnalyzeFrame().

◆ anaRemove()

int anaRemove ( const char * dbname)
extern

Remove header and data files belonging to specified Analyze 7.5 database. SIF is not deleted in any case.

Returns
Returns 0 when call was successful, 1 if header file deletion failed, 2 if data file deletion failed. Call is considered successful, if database does not exist initially.
See also
anaExists
Parameters
dbnameAnalyze database name.

Definition at line 666 of file analyze.c.

669 {
670 char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
671
672 if(ANALYZE_TEST) printf("anaRemove(%s)\n", dbname);
673 if(anaDatabaseExists(dbname, hdrfile, datfile, siffile)==0) return 0;
674 if(ANALYZE_TEST>2) printf(" removing %s and %s\n", hdrfile, datfile);
675 if(remove(hdrfile)!=0) return 1;
676 if(remove(datfile)!=0) return 2;
677 return 0;
678}
int anaDatabaseExists(const char *dbname, char *hdrfile, char *imgfile, char *siffile)
Definition analyze.c:704

◆ anaRemoveFNameExtension()

void anaRemoveFNameExtension ( char * fname)
extern

Check if Analyze 7.5 filename was given accidentally with extension. Remove the extension if necessary.

See also
anaExists, anaRemove
Parameters
fnameFull name of file.

Definition at line 687 of file analyze.c.

690 {
691 char *cptr;
692 cptr=strrchr(fname, '.'); if(cptr==NULL) return;
693 if(strcasecmp(cptr, ".")==0 || strcasecmp(cptr, ".img")==0 ||
694 strcasecmp(cptr, ".hdr")==0 || strcasecmp(cptr, ".sif")==0)
695 *cptr=(char)0;
696}

Referenced by anaDatabaseExists(), and imgRead().

◆ anaWriteHeader()

int anaWriteHeader ( char * filename,
ANALYZE_DSR * h )
extern

Write Analyze header contents. Header field 'little' is used to determine the required byte order.

Returns
Returns 0, if ok, 1 if invalid input, 2 if file could not be opened for writing, 3 if data header write failed, 4 if image dimension write failed, and 5 if header history write failed.
See also
anaReadHeader
Parameters
filenameName of file to read (including path and extension)
hPointer to Analyze header structure

Definition at line 282 of file analyze.c.

287 {
288 unsigned char buf1[ANALYZE_HEADER_KEY_SIZE];
289 unsigned char buf2[ANALYZE_HEADER_IMGDIM_SIZE];
290 unsigned char buf3[ANALYZE_HEADER_HISTORY_SIZE];
291 FILE *fp;
292 int same_order, little;
293
294
295 if(ANALYZE_TEST) printf("anaWriteHeader(%s, *dsr)\n", filename);
296
297 /* Check arguments */
298 if(strlen(filename)<1 || h==NULL) return(1);
299 little=little_endian();
300 if(little==h->little) same_order=1; else same_order=0;
301
302 /* Copy header contents into buffers */
303 /* Header key */
304 memset(buf1, 0, ANALYZE_HEADER_KEY_SIZE);
305 memcpy(buf1+0, &h->hk.sizeof_hdr, 4); if(!same_order) swawbip(buf1+0, 4);
306 memcpy(buf1+4, &h->hk.data_type, 10);
307 memcpy(buf1+14, &h->hk.db_name, 18);
308 memcpy(buf1+32, &h->hk.extents, 4); if(!same_order) swawbip(buf1+32, 4);
309 memcpy(buf1+36, &h->hk.session_error, 2); if(!same_order) swabip(buf1+36, 2);
310 memcpy(buf1+38, &h->hk.regular, 1);
311 memcpy(buf1+39, &h->hk.hkey_un0, 1);
312 /* Image dimension */
313 memset(buf2, 0, ANALYZE_HEADER_IMGDIM_SIZE);
314 memcpy(buf2+0, h->dime.dim, 16); if(!same_order) swabip(buf2+0, 16);
315 memcpy(buf2+16, &h->dime.unused8, 2); if(!same_order) swabip(buf2+16, 2);
316 memcpy(buf2+18, &h->dime.unused9, 2); if(!same_order) swabip(buf2+18, 2);
317 memcpy(buf2+20, &h->dime.unused10, 2); if(!same_order) swabip(buf2+20, 2);
318 memcpy(buf2+22, &h->dime.unused11, 2); if(!same_order) swabip(buf2+22, 2);
319 memcpy(buf2+24, &h->dime.unused12, 2); if(!same_order) swabip(buf2+24, 2);
320 memcpy(buf2+26, &h->dime.unused13, 2); if(!same_order) swabip(buf2+26, 2);
321 memcpy(buf2+28, &h->dime.unused14, 2); if(!same_order) swabip(buf2+28, 2);
322 memcpy(buf2+30, &h->dime.datatype, 2); if(!same_order) swabip(buf2+30, 2);
323 memcpy(buf2+32, &h->dime.bitpix, 2); if(!same_order) swabip(buf2+32, 2);
324 memcpy(buf2+34, &h->dime.dim_un0, 2); if(!same_order) swabip(buf2+34, 2);
325 memcpy(buf2+36, h->dime.pixdim, 32); if(!same_order) swawbip(buf2+36, 32);
326 memcpy(buf2+68, &h->dime.vox_offset, 4); if(!same_order) swawbip(buf2+68, 4);
327 memcpy(buf2+72, &h->dime.funused1, 4); if(!same_order) swawbip(buf2+72, 4);
328 memcpy(buf2+76, &h->dime.funused2, 4); if(!same_order) swawbip(buf2+76, 4);
329 memcpy(buf2+80, &h->dime.funused3, 4); if(!same_order) swawbip(buf2+80, 4);
330 memcpy(buf2+84, &h->dime.cal_max, 4); if(!same_order) swawbip(buf2+84, 4);
331 memcpy(buf2+88, &h->dime.cal_min, 4); if(!same_order) swawbip(buf2+88, 4);
332 memcpy(buf2+92, &h->dime.compressed, 4); if(!same_order) swawbip(buf2+92, 4);
333 memcpy(buf2+96, &h->dime.verified, 4); if(!same_order) swawbip(buf2+96, 4);
334 memcpy(buf2+100, &h->dime.glmax, 4); if(!same_order) swawbip(buf2+100, 4);
335 memcpy(buf2+104, &h->dime.glmin, 4); if(!same_order) swawbip(buf2+104, 4);
336 /* Data history */
337 memset(buf3, 0, ANALYZE_HEADER_HISTORY_SIZE);
338 memcpy(buf3+0, &h->hist.descrip, 80);
339 memcpy(buf3+80, &h->hist.aux_file, 24);
340 memcpy(buf3+104, &h->hist.orient, 1);
341 memcpy(buf3+105, &h->hist.originator, 10);
342 memcpy(buf3+115, &h->hist.generated, 10);
343 memcpy(buf3+125, &h->hist.scannum, 10);
344 memcpy(buf3+135, &h->hist.patient_id, 10);
345 memcpy(buf3+145, &h->hist.exp_date, 10);
346 memcpy(buf3+155, &h->hist.exp_time, 10);
347 memcpy(buf3+165, &h->hist.hist_un0, 3);
348 memcpy(buf3+168, &h->hist.views, 4); if(!same_order) swawbip(buf3+168, 4);
349 memcpy(buf3+172, &h->hist.vols_added,4); if(!same_order) swawbip(buf3+172, 4);
350 memcpy(buf3+176, &h->hist.start_field,4); if(!same_order) swawbip(buf3+176,4);
351 memcpy(buf3+180, &h->hist.field_skip,4); if(!same_order) swawbip(buf3+180, 4);
352 memcpy(buf3+184, &h->hist.omax, 4); if(!same_order) swawbip(buf3+184, 4);
353 memcpy(buf3+188, &h->hist.omin, 4); if(!same_order) swawbip(buf3+188, 4);
354 memcpy(buf3+192, &h->hist.smax, 4); if(!same_order) swawbip(buf3+192, 4);
355 memcpy(buf3+196, &h->hist.smin, 4); if(!same_order) swawbip(buf3+196, 4);
356
357 /* Open header file for write */
358 fp=fopen(filename, "wb"); if(fp==NULL) return(2);
359 /* Write header key */
360 if(fwrite(buf1, 1, ANALYZE_HEADER_KEY_SIZE, fp) != ANALYZE_HEADER_KEY_SIZE) {
361 fclose(fp); return(3);}
362 /* Write image dimension */
363 if(fwrite(buf2, 1, ANALYZE_HEADER_IMGDIM_SIZE, fp) != ANALYZE_HEADER_IMGDIM_SIZE) {
364 fclose(fp); return(4);}
365 /* Write data history */
366 if(fwrite(buf3, 1, ANALYZE_HEADER_HISTORY_SIZE, fp) != ANALYZE_HEADER_HISTORY_SIZE) {
367 fclose(fp); return(5);}
368 fclose(fp);
369
370 return(0);
371}

Referenced by imgWriteAnalyze(), and imgWriteAnalyzeFrame().

◆ dcmAddItem()

int dcmAddItem ( DCMFILE * dcm,
DCMITEM * d,
short int aschild,
DCMTAG tag,
dcmvr vr,
unsigned int vl,
char * rd,
const int verbose )
extern

Add an item to DCMFILE data struct.

See also
dcmfileInit, dcmfileFree
Returns
0 if successful, otherwise >0.
Parameters
dcmPointer to DCMFILE.
dPointer to a previous item in DCMFILE, into which to link this item; enter NULL to add as next item to the highest level.
aschildAdd as child; 1=yes, 0=no.
tagTag
vrVR
vlVL; enter 0xFFFFFFFF to use VR's default length.
rdPointer to the item value as byte array
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 1239 of file dcm.c.

1257 {
1258 if(verbose>0) {
1259 printf("%s(dcm, (%04X,%04X))", __func__, tag.group, tag.element);
1260 if(d==NULL) printf(", null"); else printf(", ptr");
1261 printf(", %d, %s, 0x%08X, rd", aschild, dcmVRName(vr), vl);
1262 printf(")\n");
1263 }
1264 if(dcm==NULL) return(1);
1265 if(vr==DCM_VR_INVALID) return(2);
1266
1267 /* Check that caller has not given previous item pointer when there are none in DCMFILE */
1268 if(d!=NULL && dcm->item==NULL) return(3);
1269 /* Check that caller has not given previous item pointer that already has child */
1270 if(d!=NULL && aschild && d->child_item!=NULL) return(4);
1271
1272 /* Check whether we currently support the Transfer UID */
1273 if(dcm->truid!=DCM_TRUID_LEE) return(5);
1274
1275 /* Allocate memory for the new element; do not free it here, since it will be part of
1276 DCMFILE struct. */
1277 if(verbose>1) printf(" allocating memory for the item\n");
1278 DCMITEM *item=(DCMITEM*)malloc(sizeof(DCMITEM));
1279 if(item==NULL) return(11);
1280 item->next_item=item->child_item=(DCMITEM*)NULL;
1281 item->fp=dcm->fp; item->truid=dcm->truid;
1282 item->rd=(char*)NULL;
1283
1284 /* Set item tag, VR, and VL */
1285 if(verbose>1) printf(" setting item contents\n");
1286 item->tag.group=tag.group;
1287 item->tag.element=tag.element;
1288 item->vr=vr;
1289 item->vl=vl;
1290 /* Allocate memory for item value */
1291 size_t s;
1292 if(vl==0xFFFFFFFF) s=dcmVRVLength(vr); else s=vl;
1293 if(s>0) {
1294 if(item->vl==0xFFFFFFFF) item->vl=(unsigned int)s;
1295 if(verbose>1) printf(" allocating %u bytes for the item value\n", (unsigned int)s);
1296 item->rd=(char*)calloc(s, sizeof(char));
1297 if(item->rd==NULL) {free(item); return(21);}
1298 } else {
1299 if(verbose>1) printf("zero size for item value\n");
1300 if(rd==NULL) {
1301 if(verbose>1) printf("... which is ok since value is empty, too.\n");
1302 } else {
1303 if(verbose>0) printf("... which is not ok because we have value to store.\n");
1304 if(item->rd==NULL) {free(item); return(22);}
1305 }
1306 }
1307 /* Copy the item value */
1308 if(rd!=NULL && s>0) {
1309 if(verbose>1) printf(" copying the item value\n");
1310 /* Special treatment for strings, because those tend to be shorter than told */
1311 if(vr==DCM_VR_LO || vr==DCM_VR_LT || vr==DCM_VR_PN || vr==DCM_VR_SH || vr==DCM_VR_UI || vr==DCM_VR_UR)
1312 {
1313 unsigned int len=strnlen(rd, s);
1314 if(len<s) strlcpy(item->rd, rd, s);
1315 else memcpy(item->rd, rd, s);
1316 } else if(vr==DCM_VR_DS || vr==DCM_VR_IS)
1317 {
1318 unsigned int len=strnlen(rd, s);
1319 if(len<s) strlcpy(item->rd, rd, s);
1320 else memcpy(item->rd, rd, s);
1321 } else {
1322 memcpy(item->rd, rd, s);
1323 }
1324 }
1325
1326
1327 /* If we have the item to link to, then do the linking */
1328 if(verbose>1) printf(" link the item.\n");
1329 if(d!=NULL) {
1330 if(aschild) {
1331 d->child_item=item;
1332 item->parent_item=d;
1333 item->prev_item=(DCMITEM*)NULL;
1334 } else if(d->next_item==NULL) {
1335 d->next_item=item;
1336 item->prev_item=d;
1337 item->parent_item=d->parent_item;
1338 } else {
1339 /* find the last item in the list */
1340 DCMITEM *ip=d; while(ip->next_item!=NULL) ip=ip->next_item;
1341 ip->next_item=item;
1342 item->prev_item=ip;
1343 item->parent_item=ip->parent_item;
1344 }
1345 } else if(dcm->item==NULL) {
1346 /* This is truly the first item ever */
1347 dcm->item=item;
1348 item->prev_item=item->parent_item=(DCMITEM*)NULL;
1349 } else {
1350 /* Caller lets us find the item to link to */
1351 DCMITEM *ip=dcm->item; while(ip->next_item!=NULL) ip=ip->next_item;
1352 ip->next_item=item;
1353 item->prev_item=ip;
1354 item->parent_item=ip->parent_item;
1355 }
1356
1357 if(verbose>2) dcmitemPrint(item);
1358
1359 if(verbose>1) printf(" all done.\n");
1360 return(0);
1361}
size_t dcmVRVLength(dcmvr id)
Definition dcm.c:264
char * dcmVRName(dcmvr id)
Definition dcm.c:246
void dcmitemPrint(DCMITEM *d)
Definition dcm.c:1205
size_t strnlen(const char *s, size_t n)
Definition strext.c:181
dcmtruid truid
DCMITEM * item
FILE * fp
dcmtruid truid
struct DCMITEM * child_item
struct DCMITEM * next_item
unsigned int vl
FILE * fp
char * rd
struct DCMITEM * prev_item
struct DCMITEM * parent_item
DCMTAG tag
unsigned short int element
unsigned short int group

◆ dcmDA2intl()

char * dcmDA2intl ( const char * orig,
char * intl )
extern

Convert DICOM date 'DA' to international format YYYY-MM-DD.

Returns
Returns pointer to the date string, or NULL in case of an error.
Parameters
origPointer to original DICOM string.
intlPointer to string where date in international format will be written; must be allocated for at least 11 characters.

Definition at line 299 of file dcm.c.

305 {
306 if(orig==NULL || intl==NULL) return(NULL);
307 if(strnlen(orig, 10)<8) return(NULL);
308 if(isdigit(orig[4])) { // modern format YYYYMMDD
309 sprintf(intl, "%4.4s-%2.2s-%2.2s", orig, orig+4, orig+6);
310 } else { // old format YYYY.MM.DD
311 sprintf(intl, "%4.4s-%2.2s-%2.2s", orig, orig+5, orig+8);
312 }
313 if(isdate(intl)) {intl[0]=(char)0; return(NULL);}
314 return(intl);
315}
int isdate(char *str)
Definition datetime.c:146

◆ dcmDT2intl()

char * dcmDT2intl ( const char * orig,
char * intl )
extern

Convert DICOM datetime 'DT' to international format YYYY-MM-DD hh:mm:ss.

Returns
Returns pointer to the time string, or NULL in case of an error.
Parameters
origPointer to original DICOM string. Should be in format YYYYMMDDhhmmss.FFFFFF+hhmm
intlPointer to string where date and time in international format will be written; must be allocated for at least 20 characters.

Definition at line 345 of file dcm.c.

352 {
353 if(orig==NULL || intl==NULL) return(NULL);
354 if(strnlen(orig, 26)<14) return(NULL);
355 sprintf(intl, "%4.4s-%2.2s-%2.2s %2.2s:%2.2s:%2.2s",
356 orig, orig+4, orig+6, orig+8, orig+10, orig+12);
357 if(isdatetime(intl, NULL)) {intl[0]=(char)0; return(NULL);}
358 return(intl);
359}
int isdatetime(char *str, char *intdate)
Definition datetime.c:280

◆ dcmfileFree()

void dcmfileFree ( DCMFILE * d)
extern

Free memory allocated for DCMFILE data. All contents are destroyed.

Precondition
Before first use initialize the struct with dcmfileInit().
See also
dcmfileInit
Author
Vesa Oikonen
Parameters
dPointer to DCMFILE.

Definition at line 868 of file dcm.c.

871 {
872 if(d==NULL) return;
873 dcmitemFree(d->item);
874 dcmfileInit(d);
875}
void dcmfileInit(DCMFILE *d)
Definition dcm.c:823
void dcmitemFree(DCMITEM *d)
Definition dcm.c:840

Referenced by dcmFileRead().

◆ dcmfileInit()

void dcmfileInit ( DCMFILE * d)
extern

Initiate the DCMFILE struct before any use.

See also
dcmfileFree
Parameters
dPointer to DCMFILE.

Definition at line 823 of file dcm.c.

826 {
827 if(d==NULL) return;
828 d->filename[0]=(char)0;
829 d->fp=(FILE*)NULL;
831 d->item=(DCMITEM*)NULL;
832}
char filename[FILENAME_MAX]

Referenced by dcmfileFree().

◆ dcmfileMaxDepth()

unsigned short int dcmfileMaxDepth ( DCMFILE * df)
extern

Get the maximum depth of DCMFILE items tree.

Returns
Returns the number of item levels under specified DCMFILE, or zero in case of an error or if there are no items.
See also
dcmitemParentNr, dcmitemMaxDepth
Parameters
dfPointer to DCMFILE item.

Definition at line 903 of file dcm.c.

906 {
907 if(df==NULL || df->item==NULL) return(0);
908 unsigned short int m=0, n=0;
909 DCMITEM *sd=df->item;
910 while(sd!=NULL) { // go through all sisters
911 n=dcmitemMaxDepth(sd); if(n>m) m=n;
912 sd=sd->next_item;
913 }
914 return(m+1);
915}
unsigned short int dcmitemMaxDepth(DCMITEM *d)
Definition dcm.c:884

◆ dcmFileRead()

int dcmFileRead ( const char * filename,
DCMFILE * dcm,
const short int headerOnly,
int verbose )
extern

Read a single DICOM file.

See also
dcmVerifyMagic, dcmfileInit, dcmfileFree, dcmReadTransferSyntaxUID, dcmFileWrite
Returns
0 when successful.
Parameters
filenamePointer to filename.
dcmPointer to initiated data structure.
headerOnlyRead only header (1), or read both header and pixel data (0).
verboseVerbose level; if zero, then nothing is printed into stdout or stderr

Definition at line 1687 of file dcm.c.

1696 {
1697 if(filename==NULL || strnlen(filename, 10)<1 || dcm==NULL) return(1);
1698 if(verbose>1) printf("%s('%s', %d)\n", __func__, filename, headerOnly);
1699
1700 /* Delete any previous data */
1701 dcmfileFree(dcm);
1702
1703 /* Open the file */
1704 strlcpy(dcm->filename, filename, FILENAME_MAX);
1705 dcm->fp=fopen(dcm->filename, "rb");
1706 if(dcm->fp==NULL) {
1707 return(2);
1708 }
1709
1710 /* Check the magic number and move file pointer to the end of it */
1711 if(verbose>2) printf("checking DICOM magic number\n");
1712 if(dcmVerifyMagic(NULL, dcm->fp)!=1) {
1713 fclose(dcm->fp);
1714 return(2);
1715 }
1716
1717 /* Get the Transfer Syntax UID */
1718 if(verbose>2) printf("checking Transfer Syntax UID\n");
1720 if(dcm->truid==DCM_TRUID_INVALID) { // not found
1721 fclose(dcm->fp);
1722 return(2);
1723 }
1724 if(verbose>0) { // print the UID
1725 printf("Transfer Syntax UID := %s\n", dcmTrUIDDescr(dcm->truid));
1726 fflush(stdout);
1727 }
1728
1729 /* Check whether we currently support the Transfer UID */
1730 if(dcm->truid!=DCM_TRUID_LEE) {
1731 fclose(dcm->fp);
1732 return(2);
1733 }
1734
1735 /* Read DICOM file elements */
1736 int ret=0;
1737 do {
1738 // note that the next function may need to call itself,
1739 // therefore counting loops here would not be useful.
1740 ret=dcmFileReadNextElement(dcm, NULL, NULL, 0, headerOnly, verbose-10);
1741 } while(ret==0 && !feof(dcm->fp));
1742 fclose(dcm->fp);
1743 /* TPCERROR_NO_KEY means that no (more) tag was found;
1744 other codes still mean that something bad happened. */
1745 if(ret==-1) {
1746 if(verbose>1) printf(" eof\n");
1747 ret=0;
1748 }
1749 return(ret);
1750}
dcmtruid dcmReadTransferSyntaxUID(FILE *fp)
Definition dcm.c:502
char * dcmTrUIDDescr(dcmtruid id)
Definition dcm.c:466
void dcmfileFree(DCMFILE *d)
Definition dcm.c:868
int dcmFileReadNextElement(DCMFILE *dcm, DCMITEM *prev_item, DCMITEM *parent_item, const short int sub, const short int headerOnly, int verbose)
Definition dcm.c:1370
int dcmVerifyMagic(const char *filename, FILE *fp)
Definition dcm.c:157

◆ dcmFileReadNextElement()

int dcmFileReadNextElement ( DCMFILE * dcm,
DCMITEM * prev_item,
DCMITEM * parent_item,
const short int sub,
const short int headerOnly,
int verbose )
extern

Read an element from DICOM file, and add it to the given linked list. This function will be called recursively in case of sequential items.

Returns
0 when successful, >0 in case of an error, -1 when no more elements could be read.
See also
dcmFileRead
Parameters
dcmPointer to DCMFILE struct; must be initiated before first call.
prev_itemPointer to previous element; NULL if none exists (yet).
parent_itemPointer to parent element; NULL if none exists (yet).
subAdd as next element (0) or as child element.
headerOnlyRead only header (1), or read both header and pixel data (0).
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 1370 of file dcm.c.

1383 {
1384 if(verbose>0) printf("%s(DCMFILE*, DCMITEM*, DCMITEM*, %d, %d)\n", __func__, sub, headerOnly);
1385 if(dcm==NULL || dcm->fp==NULL) return(1);
1386 if(sub!=0 && parent_item==NULL) return(1);
1387 if(feof(dcm->fp)) return(-1);
1388
1389 /* Check whether we currently support the Transfer UID */
1390 if(dcm->truid!=DCM_TRUID_LEE) return(2);
1391
1392 if(verbose>10) {
1393 if(dcm->item==NULL) printf(" will add first element\n");
1394 else if(sub==0) printf(" will add next element\n");
1395 else printf(" will add subelement\n");
1396 }
1397
1398 /* Is this a child to a sequence element? */
1399 int sq_child=0;
1400 if(parent_item!=NULL && parent_item->vr==DCM_VR_SQ) {sq_child=1;}
1401 if(verbose>10 && sq_child!=0) printf(" we're a child to a sequence element\n");
1402
1403 /* Allocate memory for the new element */
1404 DCMITEM *item=(DCMITEM*)malloc(sizeof(DCMITEM));
1405 if(item==NULL) return(4);
1406 item->prev_item=prev_item;
1407 item->parent_item=parent_item;
1408 item->next_item=item->child_item=(DCMITEM*)NULL;
1409 item->fp=dcm->fp; item->truid=dcm->truid;
1410 item->rd=(char*)NULL;
1411
1412 /* Save current file position (should be the start of element) */
1413 if(fgetpos(dcm->fp, &item->pos)) {
1414 free(item); return(2);
1415 }
1416
1417 /* Read the tag (2x2 bytes) */
1418 if(verbose>10) {
1419 long int tagpos=ftell(dcm->fp);
1420 printf(" reading tag at %ld\n", tagpos);
1421 }
1422 if(dcmReadFileTag(dcm->fp, &item->tag)) {
1423 if(verbose>1 && !feof(dcm->fp)) printf(" error in reading the tag.\n");
1424 free(item);
1425 if(feof(dcm->fp)) return(-1);
1426 return(2);
1427 }
1428
1429 if(verbose>2) {
1430 printf(" tag(%04x,%04x) with %u parents\n",
1431 item->tag.group, item->tag.element, dcmitemParentNr(item));
1432 }
1433
1434 /* If child, then check for item delimitation tag (although it should not be here) */
1435 if(dcmitemParentNr(item)>0 && item->tag.group==0xFFFE && item->tag.element==0xE00D) {
1436 if(verbose>10)
1437 printf(" item delimitation tag(%04x,%04x) found, reading VL\n",
1438 item->tag.group, item->tag.element);
1439 unsigned long int vl=dcmReadFileVL(dcm->fp, 4);
1440 if(verbose>1) printf(" item delimitation tag VL := %lu (0x%08lx)\n", vl, vl);
1441 if(vl!=0) {
1442 if(verbose>1) printf(" error: VL should have been 0\n");
1443 return(3);
1444 }
1445 return(0);
1446 }
1447
1448
1449 /* Read value representation and length (VR and VL, 2x2 or 2x4 bytes) */
1450 {
1451 if(verbose>10) printf(" reading VR and VL\n");
1452 int ret;
1453 unsigned int n;
1454 ret=dcmReadFileVRVL(dcm->fp, &item->vr, &item->vl, &n);
1455 if(ret!=0) {
1456 if(verbose>1) printf(" invalid VR or VL\n");
1457 free(item); return(ret);
1458 }
1459 if(verbose>1) {
1460 printf(" VR := %s (%s)\n", dcmVRName(item->vr), dcmVRDescr(item->vr));
1461 printf(" VL := %u (0x%08x) (%d bytes field)\n", item->vl, item->vl, n/2);
1462 fflush(stdout);
1463 }
1464 }
1465
1466 /* Read value field, and add the current element to the list */
1467 if(item->vr==DCM_VR_SQ) {
1468 if(ftell(dcm->fp)<0) return(2);
1469 unsigned long int sqPos=(unsigned long int)ftell(dcm->fp);
1470 if(verbose>10) {printf(" sequence... at %ld\n", sqPos); fflush(stdout);}
1471 unsigned long int sqContentLength=item->vl;
1472 if(verbose>12) printf(" sequence contents length is %lu\n", sqContentLength);
1473 /* File position is now at the start of first item in the sequence */
1474 int ret;
1475 /* If parent has no previous child, then define this as its child */
1476 if(sq_child!=0 && parent_item->child_item==NULL) {
1477 parent_item->child_item=item;
1478 } else {
1479 /* else, add SQ sequence itself as next element to the list, and later
1480 add each sequence item as child to it */
1481 if(prev_item==NULL) {
1482 if(dcm->item==NULL) { // truly the first item
1483 dcm->item=item;
1484 } else { // search for the previous one
1485 DCMITEM *ip; ip=dcm->item;
1486 while(ip->next_item!=NULL) ip=ip->next_item;
1487 ip->next_item=item; item->prev_item=ip;
1488 }
1489 } else {
1490 prev_item->next_item=item; item->prev_item=prev_item;
1491 }
1492 }
1493 /* Read the first item tag and length, but there is no VR to read this time */
1494 if(verbose>10) {
1495 long int tagpos=ftell(dcm->fp);
1496 printf(" reading first item tag at %ld\n", tagpos);
1497 }
1498 DCMTAG itemtag;
1499 ret=dcmReadFileTag(dcm->fp, &itemtag);
1500 if(ret!=0) {
1501 if(verbose>1) printf(" error %d in reading the tag.\n", ret);
1502 return(2);
1503 }
1504 if(verbose>1) printf(" item tag(%04x,%04x)\n", itemtag.group, itemtag.element);
1505 /* It is common that sequence is empty; check it first */
1506 if(itemtag.group==0xFFFE && (itemtag.element==0xE0DD || itemtag.element==0xE00D)) {
1507 /* yes; then read also the 4 byte LV, which should be zero */
1508 if(verbose>10)
1509 printf(" sequence delimitation item tag(%04x,%04x) found, reading VL\n",
1510 itemtag.group, itemtag.element);
1511 unsigned long int vl=dcmReadFileVL(dcm->fp, 4);
1512 if(verbose>1) printf(" item tag VL := %lu (0x%08lx)\n", vl, vl);
1513 if(vl!=0) {
1514 if(verbose>1) printf(" error: VL should have been 0\n");
1515 return(2);
1516 }
1517 if(verbose>3) printf(" ending sequence before it really started.\n");
1518 return(0);
1519 }
1520 /* If sequence actually contains something, the Item tag must be 0xFFFE,0xE000 */
1521 if(itemtag.group!=0xFFFE || itemtag.element!=0xE000) {
1522 if(verbose>1) printf(" invalid sequence item tag(%04x,%04x)\n", itemtag.group, itemtag.element);
1523 return(2);
1524 }
1525 /* Read past the VL of this item (always 4 bytes) */
1526 unsigned long int itemvl=dcmReadFileVL(dcm->fp, 4);
1527 if(verbose>3) {printf(" item_VL := %lu (0x%08lx)\n", itemvl, itemvl);}
1528 if(ftell(dcm->fp)<0) return(2);
1529 unsigned long int sqItemPos=(unsigned long int)ftell(dcm->fp);
1530 /* Check if that is all of this sequence (probably Siemens) */
1531 if((sqItemPos-sqPos)>=sqContentLength) {
1532 if(verbose>3) printf(" ending sequence since it was found to be empty.\n");
1533 return(0);
1534 }
1535 if(verbose>12) printf(" sequence content start position at %ld\n", sqItemPos);
1536 /* Read the first item value as its own element, adding it as child to SQ */
1537 ret=dcmFileReadNextElement(dcm, NULL, item, 1, headerOnly, verbose-1);
1538 if(ret!=0) {
1539 if(verbose>1) printf(" error in reading the first item value dataset\n");
1540 return(ret);
1541 }
1542 /* Now we continue reading more items, until we reach Sequence Delimitation Item */
1543 while(!feof(dcm->fp)) {
1544 /* Do not read pass the length of the sequence data */
1545 if(ftell(dcm->fp)<0) return(2);
1546 unsigned long int cPos=(unsigned long int)ftell(dcm->fp);
1547 if(sqContentLength>0 && (cPos-sqPos)>=sqContentLength) {
1548 if(verbose>3) printf(" we reached the end of sequence VL %lu\n", sqContentLength);
1549 /* set fake sequence delimitation tag */
1550 itemtag.group=0xFFFE; itemtag.element=0xE0DD;
1551 break;
1552 }
1553 if(verbose>10) {
1554 long int tagpos=ftell(dcm->fp);
1555 printf(" reading next sequence item tag at %ld, %ld after start\n", tagpos, tagpos-sqItemPos);
1556 }
1557 if(dcmReadFileTag(dcm->fp, &itemtag)) return(2);
1558 if(verbose>1) printf(" next item tag(%04x,%04x)\n", itemtag.group, itemtag.element);
1559 itemvl=dcmReadFileVL(dcm->fp, 4); // delimitation tag has this too
1560 if(verbose>3) {printf(" item_VL := %lu (0x%08lx)\n", itemvl, itemvl);}
1561 /* Check if we got sequence delimitation tag */
1562 if(itemtag.group==0xFFFE && itemtag.element==0xE0DD)
1563 {
1564 if(verbose>3) printf(" we got sequence delimitation tag\n");
1565 break;
1566 }
1567 /* Check if we got item delimitation tag from the previous item */
1568 if(itemtag.group==0xFFFE && itemtag.element==0xE00D)
1569 {
1570 if(verbose>3) printf(" we got item delimitation tag\n");
1571 if(itemvl!=0) {
1572 if(verbose>1) printf(" error: VL should have been 0\n");
1573 return(3);
1574 }
1575 continue;
1576 }
1577 /* Otherwise this should be sequence item tag */
1578 if(itemtag.group!=0xFFFE || itemtag.element!=0xE000) {
1579 if(verbose>3) printf(" not sequence item tag, move file position back 2x4 bytes\n");
1580 fseek(dcm->fp, -8, SEEK_CUR); //return(TPCERROR_INVALID_VALUE);
1581 }
1582 /* Read the item value as its own element, adding it to the SQ child list */
1583 DCMITEM *child=item->child_item;
1584 if(child==NULL) {
1585 if(verbose>1) printf(" error had happened in adding the child element\n");
1586 return(2);
1587 }
1588 while(child->next_item!=NULL) child=child->next_item;
1589 ret=dcmFileReadNextElement(dcm, child, item, 0, headerOnly, verbose-1);
1590 if(ret!=0) {
1591 if(verbose>1) printf(" error in reading item value dataset\n");
1592 return(ret);
1593 }
1594 }
1595 /* Check that loop really stopped at sequence delimitation item */
1596 /* 0xE00D means the end of item, 0xE0DD the end of sequence. */
1597 if(itemtag.group!=0xFFFE || itemtag.element!=0xE0DD) {
1598 if(verbose>1)
1599 printf(" invalid sequence delimitation item tag(%04x,%04x)\n", itemtag.group, itemtag.element);
1600 return(2);
1601 }
1602 /* Done. Do not free item! */
1603 if(verbose>10) {printf(" end of sequence.\n"); fflush(stdout);}
1604 } else if(item->vl!=0xFFFFFFFF) {
1605 if(verbose>10) {printf(" reading value of %u bytes...\n", item->vl); fflush(stdout);}
1606 char *buf=NULL;
1607 if(item->vl>0) {
1608 buf=(char*)calloc(item->vl+1, sizeof(char));
1609 if(buf==NULL) {free(item); return(4);}
1610 if(fread(buf, 1, item->vl, item->fp)!=item->vl) {
1611 free(item); free(buf); return(3);
1612 }
1613 /* Do not store pixel data, if that was the request */
1614 if(headerOnly!=0 &&
1615 ((item->tag.group==0x7FE0 && item->tag.element>0) || item->tag.group==0x7FE1))
1616 {
1617 if(verbose>5) {printf(" ...not storing pixel data\n"); fflush(stdout);}
1618 free(buf); buf=(char*)NULL;
1619 } else {
1620 item->rd=buf;
1621 }
1622 } else if(verbose>4) {
1623 printf(" VL=0\n");
1624 }
1625 /* Add to list */
1626 if(sub==0) {
1627 if(prev_item==NULL) {
1628 if(dcm->item==NULL) { // truly the first item
1629 dcm->item=item;
1630 } else { // search for the previous one
1631 DCMITEM *ip; ip=dcm->item;
1632 while(ip->next_item!=NULL) ip=ip->next_item;
1633 ip->next_item=item; item->prev_item=ip;
1634 }
1635 } else {
1636 prev_item->next_item=item; item->prev_item=prev_item;
1637 }
1638 } else { // add as child
1639 parent_item->child_item=item; item->parent_item=parent_item;
1640 }
1641 /* Done. Do no free item or buf! */
1642 return(0);
1643
1644 } else { // VL=0xFFFFFFFF
1645 size_t s=dcmVRVLength(item->vr);
1646 if(s==0) {
1647 if(verbose>0) printf(" Unknown VL!!\n");
1648 free(item);
1649 return(3); //return(TPCERROR_OK);
1650 }
1651 if(verbose>4) printf(" VR_based_VL=%u\n", (unsigned int)s);
1652 char *buf=(char*)calloc(s+1, sizeof(char));
1653 if(buf==NULL) {free(item); return(4);}
1654 if(fread(buf, 1, s, item->fp)!=s) {
1655 free(item); free(buf); return(3);
1656 }
1657 item->rd=buf;
1658 /* Add to list */
1659 if(sub==0) {
1660 if(prev_item==NULL) {
1661 if(dcm->item==NULL) { // truly the first item
1662 dcm->item=item;
1663 } else { // search for the previous one
1664 DCMITEM *ip; ip=dcm->item;
1665 while(ip->next_item!=NULL) ip=ip->next_item;
1666 ip->next_item=item; item->prev_item=ip;
1667 }
1668 } else {
1669 prev_item->next_item=item; item->prev_item=prev_item;
1670 }
1671 } else { // add as child
1672 parent_item->child_item=item; item->parent_item=parent_item;
1673 }
1674 /* Done. Do no free item or buf! */
1675 return(0);
1676 }
1677
1678 return(0);
1679}
int dcmReadFileTag(FILE *fp, DCMTAG *tag)
Definition dcm.c:553
int dcmReadFileVRVL(FILE *fp, dcmvr *vr, unsigned int *vl, unsigned int *n)
Definition dcm.c:724
unsigned int dcmReadFileVL(FILE *fp, unsigned int n)
Definition dcm.c:692
unsigned short int dcmitemParentNr(DCMITEM *d)
Definition dcm.c:923
char * dcmVRDescr(dcmvr id)
Definition dcm.c:282
fpos_t pos

Referenced by dcmFileRead(), and dcmFileReadNextElement().

◆ dcmFileWrite()

int dcmFileWrite ( const char * filename,
DCMFILE * dcm,
int verbose )
extern

Write a single DICOM file.

See also
dcmFileRead, dcmfileInit, dcmfileFree
Returns
0 when successful.
Parameters
filenamePointer to file name.
dcmPointer to DICOM data to be written.
verboseVerbose level; if zero, then nothing is printed into stdout or stderr

Definition at line 1758 of file dcm.c.

1765 {
1766 if(filename==NULL || strnlen(filename, 10)<1 || dcm==NULL) return(1);
1767 if(verbose>1) {printf("%s('%s')\n", __func__, filename); fflush(stdout);}
1768
1769 /* Check for the data */
1770 if(dcm->item==NULL) {
1771 return(2);
1772 }
1773
1774 /* Check whether we currently support the Transfer UID */
1775 if(dcm->truid!=DCM_TRUID_LEE) { // Little endian explicit
1776 return(2);
1777 }
1778
1779
1780 /* Open the file */
1781 if(verbose>1) printf("opening the file for writing\n");
1782 FILE *fp;
1783 fp=fopen(filename, "wb");
1784 if(fp==NULL) return(3);
1785
1786 /* Write preamble (just 128 zeroes) and magic number */
1787 {
1788 if(verbose>1) printf("writing preamble\n");
1789 char buf1[128], buf2[5];
1790 for(int i=0; i<128; i++) buf1[i]=(char)0;
1791 strcpy(buf2, "DICM");
1792 if(fwrite(buf1, 128, 1, fp)<1 || fwrite(buf2, 4, 1, fp)<1) {
1793 fclose(fp);
1794 return(3);
1795 }
1796 }
1797
1798
1799 /* Write the contents */
1800 if(verbose>1) printf("writing DICOM contents\n");
1801 int ret=0;
1802 DCMITEM *iptr;
1803 DCMITEM *d1=dcm->item;
1804 while(d1!=NULL) {
1805 if(verbose>2) {dcmitemPrint(d1);}
1806 /* Write */
1807 iptr=d1;
1808 {
1809 size_t n;
1810 /* Write tag */
1811 if(dcmWriteFileTag(fp, &iptr->tag)!=0) {ret=1; break;}
1812 /* Write VR and VL */
1813 if(dcmWriteFileVRVL(fp, iptr->vr, iptr->vl, NULL)!=0) {ret=2; break;}
1814 /* Write value, unless zero length, or SQ, in which case written later */
1815 if(iptr->vl>0 && iptr->vr!=DCM_VR_SQ) {
1816 size_t len;
1817 if(iptr->vl==0xFFFFFFFF) {
1818 len=dcmVRVLength(iptr->vr);
1819 if(verbose>30) printf(" value_len1 := %u\n", (unsigned int)len);
1820 n=fwrite(iptr->rd, dcmVRVLength(iptr->vr), 1, fp);
1821 } else {
1822 len=iptr->vl;
1823 if(verbose>30) printf(" value_len3 := %u\n", (unsigned int)len);
1824 n=fwrite(iptr->rd, iptr->vl, 1, fp);
1825 }
1826 if(verbose>30) printf(" value_len := %u\n", (unsigned int)len);
1827 if(n!=1) {ret=4; break;}
1828 } else if(iptr->vr==DCM_VR_SQ && d1->child_item==NULL) {
1829 if(verbose>1) printf("SQ, but no contents to write!\n");
1830 /* Write Sequence Delimitation Item */
1831 if(dcmWriteFileSQDelimItem(fp)!=0) {ret=6; break;}
1832 }
1833 }
1834
1835 /* If this element (SQ) has children, then write those */
1836 /* Data Elements with a group of 0000, 0002 and 0006 shall not be present within Sequence Items,
1837 but that is not verified here */
1838 if(d1->child_item!=NULL) {
1839 DCMITEM *d2=d1->child_item;
1840 unsigned int d2counter=0;
1841 while(d2!=NULL) {
1842 if(verbose>2) {printf(" "); dcmitemPrint(d2);}
1843
1844 /* Write */
1845 iptr=d2;
1846
1847 /* First, write Item tag (FFFE,E000) */
1848 if(d2counter==0) {
1849 DCMTAG tag; tag.group=0xFFFE; tag.element=0xE000;
1850 if(dcmWriteFileTag(fp, &tag)!=0) {ret=11; break;}
1851 }
1852 /* Write item length; write 0xFFFFFFFF for now, correct later when known */
1853 fpos_t d2ilpos; // position for item length
1854 unsigned int d2il=0; // item length
1855 if(d2counter==0) {
1856 if(fgetpos(fp, &d2ilpos)) {ret=12; break;} // save position for writing later
1857 unsigned int ibuf;
1858 ibuf=0xFFFFFFFF;
1859 if(fwrite(&ibuf, 4, 1, fp)!=1) {ret=13; break;}
1860 }
1861 d2counter++;
1862
1863 /* Write item value data set */
1864 {
1865 /* Write tag */
1866 if(dcmWriteFileTag(fp, &iptr->tag)!=0) {ret=14; break;}
1867 d2il+=4;
1868 /* Write VR and VL */
1869 unsigned int s;
1870 if(dcmWriteFileVRVL(fp, iptr->vr, iptr->vl, &s)!=0) {ret=15; break;}
1871 d2il+=s;
1872 /* Write value, unless zero length, or SQ, in which case written later */
1873 if(iptr->vl>0 && iptr->vr!=DCM_VR_SQ) {
1874 size_t len, n;
1875 if(iptr->vl==0xFFFFFFFF) {
1876 len=dcmVRVLength(iptr->vr);
1877 if(verbose>30) printf(" value_len1 := %u\n", (unsigned int)len);
1878 n=fwrite(iptr->rd, dcmVRVLength(iptr->vr), 1, fp);
1879 d2il+=len;
1880 } else {
1881 len=iptr->vl;
1882 if(verbose>30) printf(" value_len3 := %u\n", (unsigned int)len);
1883 n=fwrite(iptr->rd, iptr->vl, 1, fp);
1884 d2il+=iptr->vl;
1885 }
1886 if(verbose>30) printf(" value_len := %u\n", (unsigned int)len);
1887 if(n!=1) {ret=17; break;}
1888 } else if(iptr->vr==DCM_VR_SQ && iptr->child_item==NULL) {
1889 if(verbose>1) printf("SQ, but no contents to write!\n");
1890 /* Write Sequence Delimitation Item */
1891 if(dcmWriteFileSQDelimItem(fp)!=0) {ret=19; break;}
1892 }
1893 }
1894
1895 /* If this element has children, then write those */
1896 if(d2->child_item!=NULL) {
1897 DCMITEM *d3=d2->child_item;
1898 unsigned int d3counter=0;
1899 while(d3!=NULL) {
1900 if(verbose>2) {printf(" "); dcmitemPrint(d3);}
1901
1902 /* Write */
1903 iptr=d3;
1904 if(iptr->vr==DCM_VR_SQ) {d3=d3->next_item; continue;} // for now do not write SQs
1905
1906 /* First, write Item tag (FFFE,E000) */
1907 if(d3counter==0) {
1908 DCMTAG tag; tag.group=0xFFFE; tag.element=0xE000;
1909 if(dcmWriteFileTag(fp, &tag)!=0) {ret=31; break;}
1910 d2il+=4;
1911 }
1912 /* Write item length; write 0xFFFFFFFF for now, correct later when known */
1913 fpos_t d3ilpos; // position for item length
1914 unsigned int d3il=0; // item length
1915 if(d3counter==0) {
1916 unsigned int ibuf;
1917 if(fgetpos(fp, &d3ilpos)) {ret=32; break;} // save position for writing later
1918 ibuf=0xFFFFFFFF;
1919 if(fwrite(&ibuf, 4, 1, fp)!=1) {ret=33; break;}
1920 d2il+=4;
1921 }
1922 d3counter++;
1923
1924 /* Write item value data set */
1925 {
1926 /* Write tag */
1927 if(dcmWriteFileTag(fp, &iptr->tag)!=0) {ret=34; break;}
1928 d3il+=4; d2il+=4;
1929 /* Write VR and VL */
1930 unsigned int s;
1931 if(dcmWriteFileVRVL(fp, iptr->vr, iptr->vl, &s)!=0) {ret=35; break;}
1932 d3il+=s; d2il+=s;
1933 /* Write value, unless zero length, or SQ, in which case written later */
1934 if(iptr->vl>0 && iptr->vr!=DCM_VR_SQ) {
1935 size_t len, n;
1936 if(iptr->vl==0xFFFFFFFF) {
1937 len=dcmVRVLength(iptr->vr);
1938 if(verbose>30) printf(" value_len1 := %u\n", (unsigned int)len);
1939 n=fwrite(iptr->rd, dcmVRVLength(iptr->vr), 1, fp);
1940 d3il+=len; d2il+=len;
1941 } else {
1942 len=iptr->vl;
1943 if(verbose>30) printf(" value_len3 := %u\n", (unsigned int)len);
1944 n=fwrite(iptr->rd, iptr->vl, 1, fp);
1945 d3il+=iptr->vl; d2il+=iptr->vl;
1946 }
1947 if(verbose>30) printf(" value_len := %u\n", (unsigned int)len);
1948 if(n!=1) {ret=37; break;}
1949 } else if(iptr->vr==DCM_VR_SQ && iptr->child_item==NULL) {
1950 if(verbose>1) printf("SQ, but no contents to write!\n");
1951 /* Write Sequence Delimitation Item */
1952 if(dcmWriteFileSQDelimItem(fp)!=0) {ret=39; break;}
1953 d2il+=8;
1954 }
1955 }
1956
1957 /* If this element has children, then write those */
1958 if(d3->child_item!=NULL) {
1959 //DCMITEM *d4=d3->child_item;
1960 if(verbose>0) fprintf(stderr, "Warning: 4th level items not written.\n");
1961 }
1962
1963 /* now that we known the length, write it to the saved position */
1964 if(0) {
1965 fpos_t opos; // current position to return to
1966 if(fgetpos(fp, &opos)) {ret=40; break;}
1967 fsetpos(fp, &d3ilpos); // go to the position for item length
1968 char buf[4];
1969 memcpy(buf, &d3il, 4);
1970 if(!little_endian()) swabip(buf, 4);
1971 if(fwrite(&buf, 4, 1, fp)!=1) {ret=41; break;}
1972 fsetpos(fp, &opos); // back to the position where we were
1973 }
1974
1975 d3=d3->next_item;
1976 }
1977 if(ret!=0) break;
1978
1979 /* Write Item Delimitation Tag */
1980 if(dcmWriteFileSQItemDelimTag(fp)!=0) {ret=21; break;}
1981 /* End of the sequence - write Sequence Delimitation Item */
1982 if(dcmWriteFileSQDelimItem(fp)!=0) {ret=21; break;}
1983
1984 }
1985
1986
1987 /* now that we known the length, write it to the saved position */
1988 if(0) {
1989 fpos_t opos; // current position to return to
1990 if(fgetpos(fp, &opos)) {ret=18; break;}
1991 fsetpos(fp, &d2ilpos); // go to the position for item length
1992 char buf[4];
1993 memcpy(buf, &d2il, 4);
1994 if(!little_endian()) swabip(buf, 4);
1995 if(fwrite(&buf, 4, 1, fp)!=1) {ret=19; break;}
1996 fsetpos(fp, &opos); // back to the position where we were
1997 }
1998
1999 d2=d2->next_item;
2000 }
2001 if(ret!=0) break;
2002
2003 /* Write Item Delimitation Tag */
2004 if(dcmWriteFileSQItemDelimTag(fp)!=0) {ret=21; break;}
2005 /* End of the sequence - write Sequence Delimitation Item */
2006 if(dcmWriteFileSQDelimItem(fp)!=0) {ret=21; break;}
2007
2008 }
2009
2010 d1=d1->next_item;
2011 } // next
2012 if(ret!=0) {
2013 if(verbose>0) fprintf(stderr, " ret := %d\n", ret);
2014 fclose(fp);
2015 return(3);
2016 }
2017
2018
2019 fclose(fp);
2020
2021 return(0);
2022}
int dcmWriteFileVRVL(FILE *fp, dcmvr vr, unsigned int vl, unsigned int *n)
Definition dcm.c:784
int dcmWriteFileSQItemDelimTag(FILE *fp)
Definition dcm.c:634
int dcmWriteFileTag(FILE *fp, DCMTAG *tag)
Definition dcm.c:583
int dcmWriteFileSQDelimItem(FILE *fp)
Definition dcm.c:609

◆ dcmFindTag()

DCMITEM * dcmFindTag ( DCMITEM * d,
const short int omit,
DCMTAG * tag,
const int verbose )
extern

Search for specified tag in DCMITEM data tree.

Returns
Returns pointer to next item with the tag, or NULL if not found.
Parameters
dPointer to current DICOM item.
omitOmit this item from the search.
tagPointer to the DICOM tag that is searched for.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 1163 of file dcm.c.

1172 {
1173 if(d==NULL || tag==NULL) return(NULL);
1174 if(verbose>0) printf("%s(%04X,%04X)\n", __func__, tag->group, tag->element);
1175 DCMITEM *iptr;
1176 if(omit==0) iptr=d; else iptr=d->next_item;
1177 while(iptr!=NULL) {
1178 if(verbose>2)
1179 printf(" checking tag(%04X,%04X)...\n", iptr->tag.group, iptr->tag.element);
1180 if(iptr->tag.group==tag->group && iptr->tag.element==tag->element) {
1181 if(verbose>2) printf(" found!\n");
1182 break;
1183 }
1184 /* Check if this item has children */
1185 if(iptr->child_item!=NULL) {
1186 if(verbose>2) printf(" going to search inside children...\n");
1187 DCMITEM *rptr=dcmFindTag(iptr->child_item, 0, tag, verbose);
1188 if(rptr!=NULL) return(rptr);
1189 if(verbose>3) printf(" nothing found in any of the children\n");
1190 }
1191 iptr=iptr->next_item;
1192 }
1193 /* Stop if we found tag, or if we do not have parent */
1194 if(iptr!=NULL) return(iptr);
1195 if(d->parent_item==NULL) return(NULL);
1196
1197 /* Search from the parent */
1198 if(verbose>2) printf(" going to search inside parent...\n");
1199 return(dcmFindTag(d->parent_item, 1, tag, verbose));
1200}
DCMITEM * dcmFindTag(DCMITEM *d, const short int omit, DCMTAG *tag, const int verbose)
Definition dcm.c:1163

Referenced by dcmFindTag().

◆ dcmitemFree()

void dcmitemFree ( DCMITEM * d)
extern

Recursively free memory allocated for DCMITEM items and their children items.

See also
dcmfileFree
Author
Vesa Oikonen
Parameters
dPointer to DCMITEM.

Definition at line 840 of file dcm.c.

843 {
844 if(d==NULL) return;
845 /* find the last item in the list */
846 DCMITEM *ip=d; while(ip->next_item!=NULL) ip=ip->next_item;
847 while(ip!=NULL) {
848 /* Free items child and their children */
849 if(ip->child_item!=NULL) dcmitemFree(ip->child_item);
850 /* Free this item and move to previous item */
851 if(ip->prev_item!=NULL) {
852 ip=ip->prev_item;
853 free(ip->next_item->rd); free(ip->next_item);
854 ip->next_item=NULL;
855 } else {
856 free(ip->rd); free(ip); ip=NULL;
857 }
858 }
859}

Referenced by dcmfileFree(), and dcmitemFree().

◆ dcmitemGetInt()

long int dcmitemGetInt ( DCMITEM * d)
extern

Read integer value from given DICOM item.

VR must be either UL, US, SL, SS, or IS; otherwise 0 is returned.

Returns
Returns the value as long int, in order to cope with originally unsigned integers.
See also
dcmitemGetInt, dcmValueString, dcmFindTag
Parameters
dPointer to item.

Definition at line 1084 of file dcm.c.

1087 {
1088 if(d==NULL || d->rd==NULL) return(0);
1089 long int li=0;
1090 if(d->vr==DCM_VR_UL) { // unsigned 32-bit int
1091 unsigned int i;
1092 memcpy(&i, d->rd, 4); if(!little_endian()) swap(&i, &i, 4);
1093 li=(long int)i;
1094 } else if(d->vr==DCM_VR_US) { // unsigned 16-bit int
1095 unsigned short int i;
1096 memcpy(&i, d->rd, 2); if(!little_endian()) swap(&i, &i, 2);
1097 li=(long int)i;
1098 } else if(d->vr==DCM_VR_SL) { // signed 32-bit int
1099 int i;
1100 memcpy(&i, d->rd, 4); if(!little_endian()) swap(&i, &i, 4);
1101 li=(long int)i;
1102 } else if(d->vr==DCM_VR_SS) { // signed 16-bit int
1103 short int i;
1104 memcpy(&i, d->rd, 2); if(!little_endian()) swap(&i, &i, 2);
1105 li=(long int)i;
1106 } else if(d->vr==DCM_VR_IS) { // integer string
1107 li=atol(d->rd);
1108 }
1109 return(li);
1110}
void swap(void *orig, void *new, int size)
Definition swap.c:31

◆ dcmitemGetReal()

double dcmitemGetReal ( DCMITEM * d)
extern

Read floating point value from given DICOM item.

VR must be either FL, FD, DS, UL, US, SL, SS, or IS; otherwise 0 is returned.

Returns
Returns the value as double.
See also
dcmitemGetInt, dcmValueString, dcmFindTag
Parameters
dPointer to item.

Definition at line 1120 of file dcm.c.

1123 {
1124 if(d==NULL || d->rd==NULL) return(0);
1125 double r=0.0;
1126 if(d->vr==DCM_VR_FL) { // 32-bit float
1127 float f;
1128 memcpy(&f, d->rd, 4); if(!little_endian()) swap(&f, &f, 4);
1129 r=(double)f;
1130 } else if(d->vr==DCM_VR_FD) { // 64-bit double
1131 double f;
1132 memcpy(&f, d->rd, 8); if(!little_endian()) swap(&f, &f, 8);
1133 r=f;
1134 } else if(d->vr==DCM_VR_DS) { // decimal string
1135 r=atof(d->rd);
1136 } else if(d->vr==DCM_VR_UL) { // unsigned 32-bit int
1137 unsigned int i;
1138 memcpy(&i, d->rd, 4); if(!little_endian()) swap(&i, &i, 4);
1139 r=(double)i;
1140 } else if(d->vr==DCM_VR_US) { // unsigned 16-bit int
1141 unsigned short int i;
1142 memcpy(&i, d->rd, 2); if(!little_endian()) swap(&i, &i, 2);
1143 r=(double)i;
1144 } else if(d->vr==DCM_VR_SL) { // signed 32-bit int
1145 int i;
1146 memcpy(&i, d->rd, 4); if(!little_endian()) swap(&i, &i, 4);
1147 r=(double)i;
1148 } else if(d->vr==DCM_VR_SS) { // signed 16-bit int
1149 short int i;
1150 memcpy(&i, d->rd, 2); if(!little_endian()) swap(&i, &i, 2);
1151 r=(double)i;
1152 } else if(d->vr==DCM_VR_IS) { // integer string
1153 r=(double)atol(d->rd);
1154 }
1155 return(r);
1156}

◆ dcmitemMaxDepth()

unsigned short int dcmitemMaxDepth ( DCMITEM * d)
extern

Get the maximum depth of DCMITEM tree.

Returns
Returns the number of levels under specified item, not including given item itself.
See also
dcmitemParentNr, dcmfileMaxDepth
Parameters
dPointer to DCMITEM item.

Definition at line 884 of file dcm.c.

887 {
888 if(d==NULL || d->child_item==NULL) return(0);
889 unsigned short int m=0, n=0;
890 DCMITEM *cd=d->child_item;
891 /* go through all children */
892 while(cd!=NULL) {
893 n=dcmitemMaxDepth(cd); if(n>m) m=n;
894 cd=cd->next_item;
895 }
896 return(m+1);
897}

Referenced by dcmfileMaxDepth(), and dcmitemMaxDepth().

◆ dcmitemParentNr()

unsigned short int dcmitemParentNr ( DCMITEM * d)
extern

Check how deep in DCMITEM tree this item is.

Returns
Returns the number of parents this item has.
See also
dcmitemMaxDepth, dcmfileMaxDepth
Parameters
dPointer to DCMITEM.

Definition at line 923 of file dcm.c.

926 {
927 if(d==NULL) return(0);
928 unsigned short int n=0;
929 DCMITEM *pd=d->parent_item;
930 while(pd!=NULL) {n++; pd=pd->parent_item;}
931 return(n);
932}

Referenced by dcmFileReadNextElement().

◆ dcmitemPrint()

void dcmitemPrint ( DCMITEM * d)
extern

Print contents of given DICOM item into stdout.

Parameters
dPointer to item.

Definition at line 1205 of file dcm.c.

1208 {
1209 if(d==NULL) {printf("(null)\n"); fflush(stdout); return;}
1210 printf("tag(%04X,%04X)", d->tag.group, d->tag.element); fflush(stdout);
1211 printf(" VR=%s", dcmVRName(d->vr)); fflush(stdout);
1212 if(d->vl==0xFFFFFFFF) printf(" VL=%08X", d->vl); else printf(" VL=%u", d->vl);
1213 fflush(stdout);
1214 char *buf=dcmValueString(d); printf(" '%s'", buf); free(buf);
1215 printf("\n"); fflush(stdout);
1216}
char * dcmValueString(DCMITEM *d)
Definition dcm.c:942

Referenced by dcmAddItem(), and dcmFileWrite().

◆ dcmReadFileTag()

int dcmReadFileTag ( FILE * fp,
DCMTAG * tag )
extern

Read DICOM tag from current file position.

Note
Tag validity is not verified here; error may be caused by end-of-file. Alternatively, read may seem to be successful, but tag contents are file padding symbols (0xFFFC).
See also
dcmReadFile, dcmReadFileElement
Returns
Returns 0 when successful, otherwise >0.
Author
Vesa Oikonen
Parameters
fpFile pointer, positioned at the start of the element (and tag).
tagPointer to DICOM tag struct; enter NULL if you just need to move file position over the tag.

Definition at line 553 of file dcm.c.

559 {
560 if(tag!=NULL) {tag->group=tag->element=0xFFFC;} // padding
561 if(fp==NULL || feof(fp)) return(1);
562 unsigned short int buf[2];
563 size_t n=fread(&buf, 2, 2, fp);
564 if(n!=2) return(2+n);
565 if(tag!=NULL) {
566 tag->group=buf[0];
567 tag->element=buf[1];
568 if(!little_endian()) { // tag is by default little endian
569 swap(&tag->group, &tag->group, 2);
570 swap(&tag->element, &tag->element, 2);
571 }
572 }
573 return(0);
574}

Referenced by dcmFileReadNextElement(), and dcmReadTransferSyntaxUID().

◆ dcmReadFileVL()

unsigned int dcmReadFileVL ( FILE * fp,
unsigned int n )
extern

Read DICOM value length (2 or 4 bytes, depending on VR) from current file position.

See also
dcmReadFileTag, dcmReadFileVR, dcmReadFileElement
Returns
Returns the value length.
Author
Vesa Oikonen
Parameters
fpFile pointer, positioned at the VL start.
nNumber of bytes (2 or 4) in the VL representation.

Definition at line 692 of file dcm.c.

697 {
698 unsigned int vl=0;
699 if(fp==NULL || (n!=2 && n!=4)) return(vl);
700
701 /* Read 2 or 4 bytes */
702 if(n==2) {
703 unsigned short int si;
704 if(fread(&si, 2, 1, fp)!=1) return(vl);
705 if(!little_endian()) swap(&si, &si, 2);
706 vl=si;
707 } else if(n==4) {
708 unsigned int li;
709 if(fread(&li, 4, 1, fp)!=1) return(vl);
710 if(!little_endian()) swap(&li, &li, 4);
711 vl=li;
712 }
713 return(vl);
714}

Referenced by dcmFileReadNextElement(), and dcmReadTransferSyntaxUID().

◆ dcmReadFileVR()

dcmvr dcmReadFileVR ( FILE * fp,
char * vrstr )
extern

Read DICOM value representation (2 or 4 bytes) from current file position.

See also
dcmReadFileTag, dcmReadFileElement
Returns
Returns the enumerated VR number, DCM_VR_INVALID in case of an error.
Author
Vesa Oikonen
Parameters
fpFile pointer, positioned at the VR start.
vrstrPointer for VR string, allocated for at least 3 characters to have space for the trailing null; enter NULL if not needed.

Definition at line 655 of file dcm.c.

661 {
662 if(vrstr!=NULL) vrstr[0]=(char)0;
663 if(fp==NULL) return(DCM_VR_INVALID);
664
665 /* Read the first two bytes */
666 char buf[3];
667 if(fread(&buf, 1, 2, fp)!=2) return(DCM_VR_INVALID);
668 buf[2]=(char)0;
669
670 /* Identify the VR */
671 dcmvr lvr=dcmVRId(buf);
672 if(vrstr!=NULL) {
673 if(lvr!=DCM_VR_INVALID) strcpy(vrstr, dcmVRName(lvr));
674 else strcpy(vrstr, buf);
675 }
676
677 /* If this VR has extra 2 byte reserved space, then
678 we need to read but do not use the next 2 bytes. */
679 if(dcmVRReserved(lvr)!=0) {
680 if(fread(&buf, 1, 2, fp)!=2) return(DCM_VR_INVALID);
681 }
682 return(lvr);
683}
unsigned char dcmVRReserved(dcmvr id)
Definition dcm.c:205
dcmvr dcmVRId(const char *s)
Definition dcm.c:223

Referenced by dcmReadTransferSyntaxUID().

◆ dcmReadFileVRVL()

int dcmReadFileVRVL ( FILE * fp,
dcmvr * vr,
unsigned int * vl,
unsigned int * n )
extern

Read DICOM Value Representation (VR, 2 or 4 bytes) and Value Length (VL, 2 or 4 bytes) from current file position.

See also
dcmReadFileVR, dcmReadFileVL, dcmReadFileTag, dcmReadFileElement, dcmWriteFileVRVL
Returns
0 when successful.
Author
Vesa Oikonen
Parameters
fpFile pointer, positioned at the VR start.
vrPointer for enumerated VR value; enter NULL if not needed (file pointer moved anyway).
vlPointer for VL; enter NULL if not needed (file pointer moved anyway).
nPointer for number of bytes read from file; enter NULL if not needed.

Definition at line 724 of file dcm.c.

733 {
734 if(vr!=NULL) *vr=DCM_VR_INVALID;
735 if(vl!=NULL) *vl=0;
736 if(n!=NULL) *n=0;
737 if(fp==NULL) return(1);
738
739 /* Read the first two bytes */
740 char buf[3];
741 if(fread(&buf, 1, 2, fp)!=2) return(2); else if(n!=NULL) *n+=2;
742 buf[2]=(char)0;
743
744 /* Identify the VR */
745 dcmvr lvr=dcmVRId(buf);
746 if(vr!=NULL) *vr=lvr;
747 if(lvr==DCM_VR_INVALID) return(3);
748
749 /* If this VR has extra 2 byte reserved space, then
750 we need to read but do not use the next 2 bytes. */
751 unsigned int bsize=2+dcmVRReserved(lvr);
752 if(bsize==4) {
753 if(fread(&buf, 1, 2, fp)!=2) return(2);
754 if(n!=NULL) *n+=2;
755 }
756
757 /* Read VL from the next 2 or 4 bytes */
758 unsigned int lvl=0;
759 if(bsize==2) {
760 unsigned short int si;
761 if(fread(&si, 2, 1, fp)!=1) return(2);
762 if(!little_endian()) swap(&si, &si, 2);
763 lvl=si;
764 } else {
765 unsigned int li;
766 if(fread(&li, 4, 1, fp)!=1) return(2);
767 if(!little_endian()) swap(&li, &li, 4);
768 lvl=li;
769 }
770 if(n!=NULL) *n+=bsize;
771 if(vl!=NULL) *vl=lvl;
772
773 return(0);
774}

Referenced by dcmFileReadNextElement().

◆ dcmReadTransferSyntaxUID()

dcmtruid dcmReadTransferSyntaxUID ( FILE * fp)
extern

Read and identify the DICOM Transfer Syntax UID.

Returns
Returns the enumerated UID, or DCM_TRUID_INVALID.
See also
dcmVerifyMagic
Parameters
fpPointer to DICOM file opened in binary format, and positioned right after the Magic number. Position will be returned to this position.

Definition at line 502 of file dcm.c.

507 {
508 if(fp==NULL || feof(fp)) return(DCM_TRUID_INVALID);
509 /* Save original file position */
510 fpos_t opos;
511 if(fgetpos(fp, &opos)) return(DCM_TRUID_INVALID);
512 /* Read file until we find DICOM tag 0x0002,0x0010 */
513 DCMTAG tag;
514 int tag_found=0;
515 while(!tag_found && !feof(fp)) {
516 if(dcmReadFileTag(fp, &tag)) break;
517 if(tag.group==0x0002 && tag.element==0x0010) {tag_found=1; break;}
518 /* not the tag that we want, so just go through this item */
519 dcmvr vr=dcmReadFileVR(fp, NULL);
520 unsigned int vl=0;
521 if(dcmVRReserved(vr)==0) vl=dcmReadFileVL(fp, 2);
522 else vl=dcmReadFileVL(fp, 4);
523 if(vr==DCM_VR_SQ) break;
524 if(vl==0xFFFFFFFF) break;
525 char buf[vl+1];
526 if(fread(buf, 1, vl, fp)!=vl) break;
527 } // get next tag
528 if(!tag_found) {fsetpos(fp, &opos); return(DCM_TRUID_INVALID);}
529 /* Read the UID */
530 if(dcmReadFileVR(fp, NULL)!=DCM_VR_UI) {
531 fsetpos(fp, &opos); return(DCM_TRUID_INVALID);
532 }
533 unsigned int vl=dcmReadFileVL(fp, 2);
534 if(vl==0 || vl==0xFFFFFFFF) {fsetpos(fp, &opos); return(DCM_TRUID_INVALID);}
535 char uid[vl+1];
536 if(fread(uid, 1, vl, fp)!=vl) {fsetpos(fp, &opos); return(DCM_TRUID_INVALID);}
537 /* Return file position to the original */
538 fsetpos(fp, &opos);
539 /* Identify the UID */
540 return(dcmTrUID(uid));
541}
dcmvr dcmReadFileVR(FILE *fp, char *vrstr)
Definition dcm.c:655
dcmtruid dcmTrUID(const char *s)
Definition dcm.c:445

Referenced by dcmFileRead().

◆ dcmSOPIdentify()

unsigned int dcmSOPIdentify ( const char * s)
extern

Identify the DICOM SOP UID.

Returns
Returns the SOP UID list index.
See also
dcmSOPName, dcmSOPUID
Parameters
sSOP UID string.

Definition at line 367 of file dcm.c.

370 {
371 if(s==NULL || strnlen(s, 3)<3) return(0);
372
373 /* Identify the SOP UID */
374 unsigned int i=0;
375 while(strcmp(dcm_sop[i].uid, "unknown")!=0) {
376 if(strcmp(dcm_sop[i].uid, s)==0) return(i);
377 i++;
378 }
379 return(i);
380}

◆ dcmSOPName()

char * dcmSOPName ( unsigned int i)
extern

Get the DICOM SOP UID Name.

Returns
Returns pointer to the SOP Name string.
See also
dcmSOPIdentify, dcmSOPUID
Parameters
iSOP UID list index.

Definition at line 388 of file dcm.c.

391 {
392 unsigned int j=0;
393 while(strcmp(dcm_sop[j].uid, "unknown")!=0) {
394 if(i==j) return(dcm_sop[j].name);
395 j++;
396 }
397 return(dcm_sop[j].name);
398}

◆ dcmSOPUID()

char * dcmSOPUID ( unsigned int i)
extern

Get the DICOM SOP UID.

Returns
Returns pointer to the UID string.
See also
dcmSOPIdentify, dcmSOPName
Parameters
iSOP UID list index.

Definition at line 406 of file dcm.c.

409 {
410 unsigned int j=0;
411 while(strcmp(dcm_sop[j].uid, "unknown")!=0) {
412 if(i==j) return(dcm_sop[j].uid);
413 j++;
414 }
415 return(dcm_sop[j].uid);
416}

◆ dcmSOPUIDName()

char * dcmSOPUIDName ( const char * s)
extern

Get the name of DICOM SOP UID.

Returns
Returns pointer to the SOP UID name string.
See also
dcmSOPName, dcmSOPUID
Parameters
sSOP UID string.

Definition at line 424 of file dcm.c.

427 {
428 if(s==NULL || strnlen(s, 3)<3) return(dcm_sop[0].name);
429
430 /* Identify the SOP UID */
431 unsigned int i=0;
432 while(strcmp(dcm_sop[i].uid, "unknown")!=0) {
433 if(strcmp(dcm_sop[i].uid, s)==0) return(dcm_sop[i].name);
434 i++;
435 }
436 return(dcm_sop[i].name);
437}

◆ dcmTagSet()

void dcmTagSet ( DCMTAG * tag,
unsigned short int group,
unsigned short int element )
extern

Set DICOM Tag group and element.

Parameters
tagPointer to Tag to set.
groupTag Group
elementTag Element

Definition at line 1221 of file dcm.c.

1228 {
1229 tag->group=group;
1230 tag->element=element;
1231}

◆ dcmTM2intl()

char * dcmTM2intl ( const char * orig,
char * intl )
extern

Convert DICOM time 'TM' to international format hh:mm:ss.

Returns
Returns pointer to the time string, or NULL in case of an error.
Parameters
origPointer to original DICOM string.
intlPointer to string where time in international format will be written; must be allocated for at least 9 characters.

Definition at line 322 of file dcm.c.

328 {
329 if(orig==NULL || intl==NULL) return(NULL);
330 if(strnlen(orig, 14)<6) return(NULL);
331 if(isdigit(orig[2])) { // modern format hhmmss.fract
332 sprintf(intl, "%2.2s:%2.2s:%2.2s", orig, orig+2, orig+4);
333 } else { // old format hh.mm.ss
334 sprintf(intl, "%2.2s:%2.2s:%2.2s", orig, orig+3, orig+6);
335 }
336 if(istime(intl)) {intl[0]=(char)0; return(NULL);}
337 return(intl);
338}
int istime(char *str)
Definition datetime.c:259

◆ dcmTrUID()

dcmtruid dcmTrUID ( const char * s)
extern

Identify the DICOM Transfer Syntax UID.

Returns
Returns the enumerated id.
See also
dcmTrUIDDescr
Parameters
sUID string.

Definition at line 445 of file dcm.c.

448 {
449 if(s==NULL || strnlen(s, 5)<5) return(DCM_TRUID_INVALID);
450
451 /* Identify the UID */
452 unsigned short int i=1; // 1 because 0 is unknown
453 while(dcm_truid[i].id!=DCM_TRUID_INVALID) {
454 if(strcmp(dcm_truid[i].uid, s)==0) return(dcm_truid[i].id);
455 i++;
456 }
457 return(DCM_TRUID_UNKNOWN);
458}

Referenced by dcmReadTransferSyntaxUID().

◆ dcmTrUIDDescr()

char * dcmTrUIDDescr ( dcmtruid id)
extern

Get the DICOM Transfer Syntax UID description.

Returns
Returns pointer to the description string.
See also
dcmTrUID
Parameters
idTransfer Syntax UID id (DCM_TRUID_LEI, ...).

Definition at line 466 of file dcm.c.

469 {
470 unsigned short int i=0;
471 while(dcm_truid[i].id!=DCM_TRUID_INVALID) {
472 if(id==dcm_truid[i].id) return(dcm_truid[i].descr);
473 i++;
474 }
475 return(dcm_truid[DCM_TRUID_INVALID].descr);
476}

Referenced by dcmFileRead().

◆ dcmTrUIDString()

char * dcmTrUIDString ( dcmtruid id)
extern

Get the DICOM Transfer Syntax UID string.

Returns
Returns pointer to the description string.
See also
dcmTrUID
Parameters
idTransfer Syntax UID id (DCM_TRUID_LEI, ...).

Definition at line 484 of file dcm.c.

487 {
488 unsigned short int i=0;
489 while(dcm_truid[i].id!=DCM_TRUID_INVALID) {
490 if(id==dcm_truid[i].id) return(dcm_truid[i].uid);
491 i++;
492 }
493 return(dcm_truid[DCM_TRUID_INVALID].uid);
494}

◆ dcmValueString()

char * dcmValueString ( DCMITEM * d)
extern

Pre-process the DICOM element value into format suitable for printing.

Note
Use only for printing information for the user.
Returns
Returns pointer to locally allocated null-terminated string.
Postcondition
Free the pointer after use.
See also
dcmitemGetInt, dcmitemGetReal, dcmFindTag

Attribute tag

Float

Double

Unsigned 32-bit int

Unsigned 16-bit int

Signed 32-bit int

Signed 16-bit int

Parameters
dPointer to item containing the value to print.

Definition at line 942 of file dcm.c.

945 {
946 if(d==NULL) return((char*)NULL);
947
948 /* For sequence, return string 'na' */
949 if(d->vr==DCM_VR_SQ) {
950 char *s=malloc(3); strcpy(s, "na"); // do not write char *s="na";
951 return(s);
952 }
953
954 /* If there is no value, then return string 'empty', or
955 'na', if value just was not stored (pixel data) */
956 if(d->vl==0) {
957 char *s=malloc(6); strcpy(s, "empty");
958 return(s);
959 } else if(d->rd==NULL) {
960 char *s=malloc(3); strcpy(s, "na");
961 return(s);
962 }
963
964 unsigned int len;
965 if(d->vl==0xFFFFFFFF) len=(unsigned int)dcmVRVLength(d->vr); else len=d->vl;
966
967 /* String values */
968 if(d->vr==DCM_VR_CS || d->vr==DCM_VR_DS || d->vr==DCM_VR_IS ||
969 d->vr==DCM_VR_LO || d->vr==DCM_VR_LT || d->vr==DCM_VR_PN ||
970 d->vr==DCM_VR_SH || d->vr==DCM_VR_ST)
971 {
972 char *s=malloc(len+1);
973 memcpy(s, d->rd, len); s[len]=(char)0;
974 return(s);
975 }
976
977 /* More string values */
978 if(d->vr==DCM_VR_AS || d->vr==DCM_VR_PN ||
979 d->vr==DCM_VR_DA || d->vr==DCM_VR_DT || d->vr==DCM_VR_TM ||
980 d->vr==DCM_VR_UT || d->vr==DCM_VR_AE ||
981 d->vr==DCM_VR_UI || d->vr==DCM_VR_UR)
982 {
983 char *s=malloc(len+1);
984 memcpy(s, d->rd, len); s[len]=(char)0;
985 return(s);
986 }
987
988
989 if(d->vr==DCM_VR_AT) {
990 DCMTAG tag;
991 memcpy(&tag.group, d->rd, 2);
992 memcpy(&tag.element, d->rd+2, 2);
993 if(!little_endian()) {
994 swap(&tag.group, &tag.group, 2);
995 swap(&tag.element, &tag.element, 2);
996 }
997 char *s=malloc(14);
998 sprintf(s, "0x%04x,0x%04x", tag.group, tag.element);
999 return(s);
1000 }
1001
1002
1003 if(d->vr==DCM_VR_FL) {
1004 float f;
1005 memcpy(&f, d->rd, 4);
1006 if(!little_endian()) swap(&f, &f, 4);
1007 char *s=malloc(16);
1008 sprintf(s, "%g", f);
1009 return(s);
1010 }
1011
1012
1013 if(d->vr==DCM_VR_FD) {
1014 char *s=malloc(32);
1015 double f;
1016 memcpy(&f, d->rd, 8);
1017 if(!little_endian()) swap(&f, &f, 8);
1018 sprintf(s, "%g", f);
1019 return(s);
1020 }
1021
1022
1023 if(d->vr==DCM_VR_UL) {
1024 unsigned int i;
1025 memcpy(&i, d->rd, 4);
1026 if(!little_endian()) swap(&i, &i, 4);
1027 char *s=malloc(16);
1028 sprintf(s, "%u", i);
1029 return(s);
1030 }
1031
1032
1033 if(d->vr==DCM_VR_US) {
1034 unsigned short int i;
1035 memcpy(&i, d->rd, 2);
1036 if(!little_endian()) swap(&i, &i, 2);
1037 char *s=malloc(8);
1038 sprintf(s, "%u", i);
1039 return(s);
1040 }
1041
1042
1043 if(d->vr==DCM_VR_SL) {
1044 int i;
1045 memcpy(&i, d->rd, 4);
1046 if(!little_endian()) swap(&i, &i, 4);
1047 char *s=malloc(16);
1048 sprintf(s, "%d", i);
1049 return(s);
1050 }
1051
1052
1053 if(d->vr==DCM_VR_SS) {
1054 short int i;
1055 memcpy(&i, d->rd, 2);
1056 if(!little_endian()) swap(&i, &i, 2);
1057 char *s=malloc(8);
1058 sprintf(s, "%d", i);
1059 return(s);
1060 }
1061
1062/* Not (yet) printed:
1063 DCM_VR_OB, ///< DICOM other byte string, even bytes, endian insensitive.
1064 DCM_VR_OD, ///< DICOM other double (64-bit) stream, endian sensitive.
1065 DCM_VR_OF, ///< DICOM other float (32-bit) stream, endian sensitive.
1066 DCM_VR_OL, ///< DICOM other long (32-bit) stream, endian sensitive.
1067 DCM_VR_OW, ///< DICOM other word (16-bit) stream, even bytes, endian sensitive.
1068 DCM_VR_UC, ///< DICOM unlimited characters.
1069 DCM_VR_UN, ///< DICOM unknown, any valid length of another VR.
1070 DCM_VR_INVALID ///< Invalid DICOM value representation.
1071*/
1072 char *s=malloc(3); strcpy(s, "na"); // do not write char *s="na";
1073 return(s);
1074}

Referenced by dcmitemPrint().

◆ dcmVerifyMagic()

int dcmVerifyMagic ( const char * filename,
FILE * fp )
extern

Verify that given file (either file name or file pointer) appears to be DICOM file, based on the magic number.

See also
dcmReadFile, dcmReadTransferSyntaxUID
Returns
Returns 1 if DICOM magic number can be found, or 0 if not.
Author
Vesa Oikonen
Parameters
filenameName of file to open and to verify for the magic number; enter NULL to use the file pointer (next argument) instead.
fpFile pointer of file to check, opened with fp=fopen(filename, "rb"); enter NULL to open file (previous argument) locally. Previously opened file pointer is first rewound to start; if DICOM magic number is found, then file pointer is left to the end of magic number, and if not, it is rewound to the file start.

Definition at line 157 of file dcm.c.

168 {
169 FILE *lfp;
170
171 if(filename==NULL && fp==NULL) return(0);
172 if(fp!=NULL) {
173 lfp=fp; rewind(lfp);
174 } else {
175 lfp=fopen(filename, "rb");
176 }
177 if(lfp==NULL) return(0);
178
179 /* Skip the first 128 bytes */
180 if(fseek(lfp, 128, SEEK_SET)) {if(fp==NULL) fclose(lfp); return(0);}
181
182 /* Read the next 4 bytes as characters */
183 char buf[5];
184 size_t n=fread(&buf, 1, 4, lfp);
185 buf[4]=(char)0;
186 if(n!=(size_t)4) {rewind(lfp); return(0);}
187
188 /* Check the magic number */
189 if(strncmp(buf, "DICM", 4)==0) {
190 if(fp==NULL) fclose(lfp);
191 return(1);
192 } else {
193 if(fp==NULL) fclose(lfp); else rewind(lfp);
194 return(0);
195 }
196}

Referenced by dcmFileRead(), and imgFormatDetermine().

◆ dcmVRDescr()

char * dcmVRDescr ( dcmvr id)
extern

Get the DICOM VR description.

Returns
Returns pointer to the description string.
See also
dcmIdentifyVR
Parameters
idVR id (DCM_VR_AE, ...).

Definition at line 282 of file dcm.c.

285 {
286 unsigned short int i=0;
287 while(dcm_vr[i].vr!=DCM_VR_INVALID) {
288 if(id==dcm_vr[i].vr) return(dcm_vr[i].descr);
289 i++;
290 }
291 return(dcm_vr[DCM_VR_INVALID].descr);
292}

Referenced by dcmFileReadNextElement().

◆ dcmVRId()

dcmvr dcmVRId ( const char * s)
extern

Identify the DICOM VR based on the two-character long string.

Returns
Returns the VR id.
See also
dcmVRName
Parameters
sVR string. Two first characters are used. String does not need to be null-terminated.

Definition at line 223 of file dcm.c.

227 {
228 if(s==NULL) return(DCM_VR_INVALID);
229 char buf[3]; buf[0]=s[0]; buf[1]=s[1]; buf[2]=(char)0;
230
231 /* Identify the VR */
232 unsigned short int i=0;
233 while(dcm_vr[i].vr!=DCM_VR_INVALID) {
234 if(strncmp(dcm_vr[i].name, buf, 2)==0) return(dcm_vr[i].vr);
235 i++;
236 }
237 return(DCM_VR_INVALID);
238}

Referenced by dcmReadFileVR(), and dcmReadFileVRVL().

◆ dcmVRName()

char * dcmVRName ( dcmvr id)
extern

Get the DICOM VR name.

Returns
Returns pointer to the name string.
See also
dcmIdentifyVR
Parameters
idVR id (DCM_VR_AE, ...).

Definition at line 246 of file dcm.c.

249 {
250 unsigned short int i=0;
251 while(dcm_vr[i].vr!=DCM_VR_INVALID) {
252 if(id==dcm_vr[i].vr) return(dcm_vr[i].name);
253 i++;
254 }
255 return(dcm_vr[DCM_VR_INVALID].name);
256}

Referenced by dcmAddItem(), dcmFileReadNextElement(), dcmitemPrint(), dcmReadFileVR(), and dcmWriteFileVRVL().

◆ dcmVRReserved()

unsigned char dcmVRReserved ( dcmvr id)
extern

Is the explicit VR (2 bytes) followed by reserved 2 bytes? If yes, then the following Value Length is also given as 32-byte integer, if no, then as 16-bit integer.

Returns
Returns 0, if not, and 2, if it is.
Parameters
idVR id (DCM_VR_AE, ...).

Definition at line 205 of file dcm.c.

208 {
209 unsigned short int i=0;
210 while(dcm_vr[i].vr!=DCM_VR_INVALID) {
211 if(id==dcm_vr[i].vr) return(dcm_vr[i].res);
212 i++;
213 }
214 return(2);
215}

Referenced by dcmReadFileVR(), dcmReadFileVRVL(), dcmReadTransferSyntaxUID(), and dcmWriteFileVRVL().

◆ dcmVRVLength()

size_t dcmVRVLength ( dcmvr id)
extern

Get the DICOM VR max value length in bytes; 0 if not defined.

Returns
Returns the length in bytes.
See also
dcmIdentifyVR
Parameters
idVR id (DCM_VR_AE, ...).

Definition at line 264 of file dcm.c.

267 {
268 unsigned short int i=0;
269 while(dcm_vr[i].vr!=DCM_VR_INVALID) {
270 if(id==dcm_vr[i].vr) return(dcm_vr[i].s);
271 i++;
272 }
273 return(dcm_vr[DCM_VR_INVALID].s);
274}

Referenced by dcmAddItem(), dcmFileReadNextElement(), dcmFileWrite(), and dcmValueString().

◆ dcmWriteFileSQDelimItem()

int dcmWriteFileSQDelimItem ( FILE * fp)
extern

Write DICOM Sequence delimitation item into current file position.

This item consists of four byte sequence delimitation tag (0xFFFE, 0xE0DD) and four byte item length (0x00000000), i.e. together 8 bytes.

See also
dcmWriteFileTag, dcmReadFileTag, dcmWriteFileSQItemDelimTag
Returns
0 when successful.
Author
Vesa Oikonen
Parameters
fpFile pointer, at the write position.

Definition at line 609 of file dcm.c.

612 {
613 if(fp==NULL) return(1);
614 int ret;
615 DCMTAG tag;
616 tag.group=0xFFFE; tag.element=0xE0DD;
617 ret=dcmWriteFileTag(fp, &tag); if(ret!=0) return(ret);
618 tag.group=0x0000; tag.element=0x0000;
619 ret=dcmWriteFileTag(fp, &tag); if(ret!=0) return(ret);
620 return(0);
621}

Referenced by dcmFileWrite().

◆ dcmWriteFileSQItemDelimTag()

int dcmWriteFileSQItemDelimTag ( FILE * fp)
extern

Write DICOM Sequence Item Delimitation Tag with VL into current file position.

This tag consists of four bytes, sequence item delimitation tag (0xFFFE, 0xE00D), followed by four byte item length (0x00000000), i.e. together 8 bytes.

See also
dcmWriteFileTag, dcmReadFileTag, dcmWriteFileSQDelimItem
Returns
0 when successful.
Author
Vesa Oikonen
Parameters
fpFile pointer, at the write position.

Definition at line 634 of file dcm.c.

637 {
638 if(fp==NULL) return(1);
639 int ret;
640 DCMTAG tag;
641 tag.group=0xFFFE; tag.element=0xE00D;
642 ret=dcmWriteFileTag(fp, &tag); if(ret!=0) return(ret);
643 tag.group=0x0000; tag.element=0x0000;
644 ret=dcmWriteFileTag(fp, &tag); if(ret!=0) return(ret);
645 return(0);
646}

Referenced by dcmFileWrite().

◆ dcmWriteFileTag()

int dcmWriteFileTag ( FILE * fp,
DCMTAG * tag )
extern

Write DICOM tag into current file position.

See also
dcmWriteFile, dcmReadFileTag
Returns
0 when successful.
Author
Vesa Oikonen
Parameters
fpFile pointer, at the write position.
tagPointer to DICOM tag struct to write.

Definition at line 583 of file dcm.c.

588 {
589 if(fp==NULL || tag==NULL) return(1);
590 unsigned short int buf[2];
591 buf[0]=tag->group;
592 buf[1]=tag->element;
593 if(!little_endian()) swabip(buf, 4); // tag is by default little endian
594 if(fwrite(&buf, 2, 2, fp)!=2) return(2);
595 return(0);
596}

Referenced by dcmFileWrite(), dcmWriteFileSQDelimItem(), and dcmWriteFileSQItemDelimTag().

◆ dcmWriteFileVRVL()

int dcmWriteFileVRVL ( FILE * fp,
dcmvr vr,
unsigned int vl,
unsigned int * n )
extern

Write DICOM Value Representation (VR, 2 or 4 bytes) and Value Length (VL, 2 or 4 bytes) into current file position.

See also
dcmWriteFileTag, dcmReadFileElement, dcmWriteFileVRVL
Returns
0 when successful.
Author
Vesa Oikonen
Parameters
fpFile pointer, opened fro writing in binary mode.
vrEnumerated VR value.
vlVL
nPointer for number of bytes written into file; enter NULL if not needed.

Definition at line 784 of file dcm.c.

793 {
794 if(n!=NULL) *n=0;
795 if(fp==NULL || vr==DCM_VR_INVALID) return(1);
796
797 /* If this VR has extra 2 byte reserved space, then
798 we need to write VR and VL with 4 bytes each, other wise with 2 bytes each. */
799 unsigned int bsize=2+dcmVRReserved(vr);
800
801 char buf[10];
802
803 /* Write VR */
804 memcpy(buf, dcmVRName(vr), 2); buf[2]=buf[3]=(char)0;
805 if(fwrite(buf, bsize, 1, fp)!=1) return(2);
806 if(n!=NULL) *n+=bsize;
807
808 /* Write VL */
809 memcpy(buf, &vl, bsize);
810 if(bsize==2) buf[2]=buf[3]=(char)0;
811 if(!little_endian()) swap(buf, buf, bsize);
812 if(fwrite(buf, bsize, 1, fp)!=1) return(2);
813 if(n!=NULL) *n+=bsize;
814
815 return(0);
816}

Referenced by dcmFileWrite().

◆ ecat63_is_scaling_needed()

int ecat63_is_scaling_needed ( float amax,
float * data,
long long nr )
extern

Check if pixel float values need to be scaled to be saved as short ints, or if they are already all very close to integers.

Returns
1 if scaling is necessary, and 0 if not.
Parameters
amaxAbsolute maximum value.
dataFloat array.
nrNumber of float values in float array.

Definition at line 662 of file ecat63w.c.

669 {
670 double d;
671
672 if(nr<1 || data==NULL) return(0);
673 /* scaling is necessary if all values are between -1 - 1 */
674 if(amax<0.9999) return(1);
675 /* Lets check first if at least the max value is close to integers or not */
676 if(modf(amax, &d)>0.0001) return(1);
677 /* if it is, then check all pixels */
678 for(long long i=0; i<nr; i++) if(modf(*data++, &d)>0.0001) return(1);
679 return(0);
680}

Referenced by ecat63WriteImageMatrix(), and ecat63WriteScanMatrix().

◆ ecat63AddImg()

int ecat63AddImg ( const char * fname,
IMG * img )
extern

Adds all matrices in memory to the ECAT file. If ECAT file does not exist, it is created.

Please note that existing ECAT file is NOT saved as bak file.

Returns
0 if ok, 1 invalid input, 2 image status is not 'occupied', 3 failed to open file for reading, 4 failed to allocate memory for data, 9 failed to write data, 21 invalid matrix list, 22 failed to write main header
Parameters
fnameName of the output ECAT 6.3 file.
imgPointer to data structure from which the data is written.

Definition at line 878 of file img_e63.c.

883 {
884 int n, m, ret=0, add=0;
885 int frameNr, planeNr;
886 int frame, plane, prev_plane;
887 float f, fmax, fmin, g, scale;
888 short int *sdata, *sptr, smin, smax;
889 FILE *fp;
890 ECAT63_mainheader main_header;
891 ECAT63_imageheader image_header;
892 ECAT63_scanheader scan_header;
893 MATRIXLIST mlist;
894 MatDir tmpMatdir;
895 Matval matval;
896 struct tm tm;
897
898 if(IMG_TEST) printf("ecat63AddImg(%s, *img)\n", fname);
899 if(IMG_TEST>4) imgInfo(img);
900 /* Check the arguments */
901 if(fname==NULL) {strcpy(ecat63errmsg, "invalid ECAT filename"); return(1);}
902 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
903 strcpy(ecat63errmsg, "image data is empty"); return(2);}
904 if(img->_dataType<1) img->_dataType=VAX_I2;
905
906 /* Check image size */
907 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024) {
908 strcpy(ecat63errmsg, "too large matrix size"); return(2);}
909
910 /* Initiate headers */
911 memset(&main_header, 0, sizeof(ECAT63_mainheader));
912 memset(&image_header,0, sizeof(ECAT63_imageheader));
913 memset(&scan_header, 0, sizeof(ECAT63_scanheader));
914
915 /* Make a main header */
916 main_header.sw_version=2;
917 main_header.num_planes=img->dimz;
918 main_header.num_frames=img->dimt;
919 main_header.num_gates=1;
920 main_header.num_bed_pos=1;
921 if(img->type==IMG_TYPE_IMAGE) main_header.file_type=IMAGE_DATA;
922 else if(img->type==IMG_TYPE_RAW) main_header.file_type=RAW_DATA;
923 else {strcpy(ecat63errmsg, "invalid filetype"); return(1);}
924 main_header.data_type=img->_dataType;
925 if(img->scanner>0) main_header.system_type=img->scanner;
927 main_header.calibration_factor=1.0;
928 main_header.axial_fov=img->axialFOV/10.0;
929 main_header.transaxial_fov=img->transaxialFOV/10.0;
930 main_header.plane_separation=img->sizez/10.0;
931 main_header.calibration_units=imgUnitToEcat6(img);
932 strncpy(main_header.radiopharmaceutical, img->radiopharmaceutical, 32);
933 if(gmtime_r((time_t*)&img->scanStart, &tm)!=NULL) {
934 main_header.scan_start_year=tm.tm_year+1900;
935 main_header.scan_start_month=tm.tm_mon+1;
936 main_header.scan_start_day=tm.tm_mday;
937 main_header.scan_start_hour=tm.tm_hour;
938 main_header.scan_start_minute=tm.tm_min;
939 main_header.scan_start_second=tm.tm_sec;
940 if(IMG_TEST>2) {
941 printf(" img->scanStart := %ld\n", (long int)img->scanStart);
942 printf(" -> tm_year := %d\n", tm.tm_year);
943 printf(" -> tm_hour := %d\n", tm.tm_hour);
944 }
945 } else {
946 main_header.scan_start_year=1900;
947 main_header.scan_start_month=1;
948 main_header.scan_start_day=1;
949 main_header.scan_start_hour=0;
950 main_header.scan_start_minute=0;
951 main_header.scan_start_second=0;
952 if(IMG_TEST>0) printf("invalid scan_start_time in IMG\n");
953 }
954 main_header.isotope_halflife=img->isotopeHalflife;
955 strcpy(main_header.isotope_code, imgIsotope(img));
956 strlcpy(main_header.study_name, img->studyNr, 12);
957 strcpy(main_header.patient_name, img->patientName);
958 strcpy(main_header.patient_id, img->patientID);
959 strlcpy(main_header.study_description, img->studyDescription, 32);
960 strlcpy(main_header.user_process_code, img->userProcessCode, 10);
961
962 /* Check if the ECAT file exists */
963 if(access(fname, 0) != -1) {
964 if(IMG_TEST) printf("Opening existing ECAT file.\n");
965 add=1;
966 /* Open the ECAT file */
967 if((fp=fopen(fname, "rb+")) == NULL) {
968 strcpy(ecat63errmsg, "cannot create ECAT file"); return(3);}
969 /* Read main header */
970 if((ret=ecat63ReadMainheader(fp, &main_header))) {
971 sprintf(ecat63errmsg, "cannot read main header (%d)", ret);
972 fclose(fp); return(3);
973 }
974 fflush(fp);
975 /* Check that filetypes are matching */
976 if((main_header.file_type==IMAGE_DATA && img->type==IMG_TYPE_IMAGE) ||
977 (main_header.file_type==RAW_DATA && img->type==IMG_TYPE_RAW)) {
978 /* ok */
979 } else {
980 sprintf(ecat63errmsg, "cannot add different filetype");
981 fclose(fp); return(3);
982 }
983 } else {
984 if(IMG_TEST) printf("ECAT file does not exist.\n");
985 add=0;
986 /* Create output ECAT file */
987 fp=ecat63Create(fname, &main_header);
988 if(fp==NULL) {strcpy(ecat63errmsg, "cannot create ECAT file"); return(3);}
989 }
990 if(IMG_TEST) ecat63PrintMainheader(&main_header, stdout);
991
992 /* Allocate memory for matrix data */
993 sdata=(short int*)malloc((size_t)img->dimx*img->dimy*sizeof(short int));
994 if(sdata==NULL) {strcpy(ecat63errmsg, "out of memory"); return(4);}
995
996 /* Set the subheader contents, as far as possible */
997 switch(main_header.file_type) {
998 case RAW_DATA:
999 scan_header.data_type=main_header.data_type;
1000 scan_header.dimension_1=img->dimx;
1001 scan_header.dimension_2=img->dimy;
1002 scan_header.frame_duration_sec=1;
1003 scan_header.scale_factor=1.0;
1004 scan_header.frame_start_time=0;
1005 scan_header.frame_duration=1000;
1006 scan_header.loss_correction_fctr=1.0;
1007 scan_header.sample_distance=(img->sampleDistance)/10.0;
1008 /*if(IMG_TEST) ecat63PrintScanheader(&scan_header);*/
1009 break;
1010 case IMAGE_DATA:
1011 image_header.data_type=main_header.data_type;
1012 image_header.num_dimensions=2;
1013 image_header.dimension_1=img->dimx;
1014 image_header.dimension_2=img->dimy;
1015 image_header.recon_scale=img->zoom;
1016 image_header.quant_scale=1.0;
1017 image_header.slice_width=img->sizez/10.;
1018 image_header.pixel_size=img->sizex/10.;
1019 image_header.frame_start_time=0;
1020 image_header.frame_duration=1000;
1021 image_header.plane_eff_corr_fctr=1.0;
1022 image_header.decay_corr_fctr=0.0;
1023 image_header.loss_corr_fctr=1.0;
1024 image_header.ecat_calibration_fctr=1.0;
1025 image_header.well_counter_cal_fctr=1.0;
1026 image_header.quant_units=main_header.calibration_units;
1027 /*if(IMG_TEST) ecat63PrintImageheader(&image_header);*/
1028 break;
1029 }
1030
1031 /* Write one matrix at a time */
1032 n=0;
1033 for(plane=1; plane<=img->dimz;plane++) for(frame=1;frame<=img->dimt;frame++) {
1034 /* Scale data to short ints */
1035 /* Search min and max */
1036 fmin=fmax=f=img->m[plane-1][0][0][frame-1];
1037 for(int i=0; i<img->dimy; i++) for(int j=0; j<img->dimx; j++) {
1038 f=img->m[plane-1][i][j][frame-1];
1039 if(f>fmax) fmax=f; else if(f<fmin) fmin=f;
1040 }
1041 /* Calculate scaling factor */
1042 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
1043 if(!isfinite(g)) {
1044 sprintf(ecat63errmsg, "invalid pixel values on pl%02d fr%02d (%d).", plane, frame, ret);
1045 fclose(fp); remove(fname); free(sdata);
1046 return(1);
1047 }
1048 if(g>0.0) scale=32766./g; else scale=1.0;
1049 if(!isfinite(scale)) scale=1.0;
1050 /*printf("fmin=%e fmax=%e g=%e scale=%e\n", fmin, fmax, g, scale);*/
1051 /* Scale matrix data to shorts */
1052 sptr=sdata;
1053 for(int i=0; i<img->dimy; i++) for(int j=0; j<img->dimx; j++) {
1054 *sptr=(short int)temp_roundf(scale*img->m[plane-1][i][j][frame-1]);
1055 sptr++;
1056 }
1057 /* Calculate and set subheader min&max and scale */
1058 smin=(short int)temp_roundf(scale*fmin);
1059 smax=(short int)temp_roundf(scale*fmax);
1060 if(main_header.file_type==RAW_DATA) {
1061 scan_header.scan_min=smin; scan_header.scan_max=smax;
1062 scan_header.scale_factor=1.0/scale;
1063 scan_header.frame_start_time=(int)temp_roundf(1000.*img->start[frame-1]);
1064 scan_header.frame_duration=
1065 (int)temp_roundf(1000.*(img->end[frame-1]-img->start[frame-1]));
1066 scan_header.prompts=temp_roundf(img->prompts[frame-1]);
1067 scan_header.delayed=temp_roundf(img->randoms[frame-1]);
1068 } else if(main_header.file_type==IMAGE_DATA) {
1069 image_header.image_min=smin; image_header.image_max=smax;
1070 image_header.quant_scale=1.0/scale;
1071 image_header.frame_start_time=(int)temp_roundf(1000.*img->start[frame-1]);
1072 image_header.frame_duration=
1073 (int)temp_roundf(1000.*(img->end[frame-1]-img->start[frame-1]));
1074 /* Set decay correction factor */
1076 image_header.decay_corr_fctr=img->decayCorrFactor[frame-1];
1077 else
1078 image_header.decay_corr_fctr=0.0;
1079 }
1080 /* Write matrix data */
1081 m=mat_numcod(frame, img->planeNumber[plane-1], 1, 0, 0);
1082 sptr=sdata;
1083 if(IMG_TEST) printf(" writing matnum=%d\n", m);
1084 if(main_header.file_type==RAW_DATA) {
1085 /*if(IMG_TEST) ecat63PrintScanheader(&scan_header);*/
1086 ret=ecat63WriteScan(fp, m, &scan_header, sptr);
1087 } else if(main_header.file_type==IMAGE_DATA) {
1088 /*if(IMG_TEST) ecat63PrintImageheader(&image_header);*/
1089 ret=ecat63WriteImage(fp, m, &image_header, sptr);
1090 }
1091 if(ret) {
1092 sprintf(ecat63errmsg, "cannot write data on pl%02d fr%02d (%d).",
1093 plane, frame, ret);
1094 fclose(fp); remove(fname); free(sdata);
1095 return(9);
1096 }
1097 n++;
1098 } /* next matrix */
1099 if(IMG_TEST) printf(" %d matrices written in %s\n", n, fname);
1100
1101 /* Free matrix memory */
1102 free(sdata);
1103
1104 /* If matrices were added, set main header */
1105 if(add==1) {
1106 fflush(fp);
1107 /* Read matrix list */
1108 ecat63InitMatlist(&mlist);
1109 ret=ecat63ReadMatlist(fp, &mlist, IMG_TEST);
1110 if(ret) {
1111 sprintf(ecat63errmsg, "cannot read matrix list (%d)", ret);
1112 fclose(fp); return(21);
1113 }
1114 if(mlist.matrixNr<=0) {
1115 strcpy(ecat63errmsg, "matrix list is empty"); fclose(fp); return(21);}
1116 /* Sort matrix list */
1117 for(int i=0; i<mlist.matrixNr-1; i++) for(int j=i+1; j<mlist.matrixNr; j++) {
1118 if(mlist.matdir[i].matnum>mlist.matdir[j].matnum) {
1119 tmpMatdir=mlist.matdir[i];
1120 mlist.matdir[i]=mlist.matdir[j]; mlist.matdir[j]=tmpMatdir;
1121 }
1122 }
1123 /* Calculate the number of planes and frames */
1124 prev_plane=plane=-1; /*prev_frame=frame=-1;*/ frameNr=planeNr=0;
1125 for(int m=0; m<mlist.matrixNr; m++) {
1126 mat_numdoc(mlist.matdir[m].matnum, &matval);
1127 plane=matval.plane; frame=matval.frame;
1128 if(plane!=prev_plane) {frameNr=1; planeNr++;} else {frameNr++;}
1129 prev_plane=plane; /*prev_frame=frame;*/
1130 } /* next matrix */
1131 ecat63EmptyMatlist(&mlist);
1132 main_header.num_planes=planeNr; main_header.num_frames=frameNr;
1133 /* Write main header */
1134 ret=ecat63WriteMainheader(fp, &main_header);
1135 if(ret) {
1136 sprintf(ecat63errmsg, "cannot write mainheader (%d)", ret);
1137 fclose(fp); return(22);
1138 }
1139 }
1140
1141 /* Close file and free memory */
1142 fclose(fp);
1143
1144 return(0);
1145}
struct tm * gmtime_r(const time_t *t, struct tm *tm)
Convert time_t to GMT struct tm.
Definition datetime.c:22
char ecat63errmsg[128]
Definition ecat63h.c:7
int ecat63ReadMatlist(FILE *fp, MATRIXLIST *ml, int verbose)
Definition ecat63ml.c:46
void ecat63InitMatlist(MATRIXLIST *mlist)
Definition ecat63ml.c:20
void ecat63EmptyMatlist(MATRIXLIST *mlist)
Definition ecat63ml.c:31
int mat_numcod(int frame, int plane, int gate, int data, int bed)
Definition ecat63ml.c:242
void mat_numdoc(int matnum, Matval *matval)
Definition ecat63ml.c:254
void ecat63PrintMainheader(ECAT63_mainheader *h, FILE *fp)
Definition ecat63p.c:16
int ecat63ReadMainheader(FILE *fp, ECAT63_mainheader *h)
Definition ecat63r.c:25
int ecat63WriteScan(FILE *fp, int matnum, ECAT63_scanheader *h, void *data)
Definition ecat63w.c:461
int ecat63WriteImage(FILE *fp, int matnum, ECAT63_imageheader *h, void *data)
Definition ecat63w.c:410
FILE * ecat63Create(const char *fname, ECAT63_mainheader *h)
Definition ecat63w.c:365
int ecat63WriteMainheader(FILE *fp, ECAT63_mainheader *h)
Definition ecat63w.c:24
int IMG_TEST
Definition img.c:6
void imgInfo(IMG *image)
Definition img.c:359
char * imgIsotope(IMG *img)
Definition imgdecayc.c:76
int imgUnitToEcat6(IMG *img)
Definition imgunits.c:175
#define IMG_TYPE_RAW
#define IMG_STATUS_OCCUPIED
#define ECAT63_SYSTEM_TYPE_DEFAULT
#define IMG_DC_CORRECTED
#define RAW_DATA
#define IMAGE_DATA
#define VAX_I2
#define IMG_TYPE_IMAGE
int temp_roundf(float e)
Definition petc99.c:20
short int num_dimensions
char radiopharmaceutical[32]
short int scan_start_month
short int scan_start_second
short int num_bed_pos
short int calibration_units
short int scan_start_year
char study_description[32]
short int scan_start_day
short int scan_start_minute
char user_process_code[10]
short int scan_start_hour
short int system_type
short int dimension_2
short int dimension_1
short int frame_duration_sec
float sizex
unsigned short int dimx
char type
char patientName[32]
char studyDescription[32]
float sampleDistance
float **** m
char decayCorrection
float transaxialFOV
char status
time_t scanStart
float * prompts
char userProcessCode[11]
unsigned short int dimt
int _dataType
int * planeNumber
char patientID[16]
int scanner
float * start
unsigned short int dimz
unsigned short int dimy
float * end
float zoom
char radiopharmaceutical[32]
float * decayCorrFactor
float isotopeHalflife
char studyNr[MAX_STUDYNR_LEN+1]
float * randoms
float axialFOV
float sizez
MatDir * matdir
int matnum
int frame
int plane

◆ ecat63CheckMatlist()

int ecat63CheckMatlist ( MATRIXLIST * ml)
extern

Checks that all matrixlist entries have read/write status.

Parameters
mlmatrix list
Returns
0 if ok, or 1 if an entry is marked as deleted or unfinished.

Definition at line 324 of file ecat63ml.c.

326 {
327 if(ml==NULL) return(1);
328 for(int i=0; i<ml->matrixNr; i++) if(ml->matdir[i].matstat!=1) return(1);
329 return(0);
330}
int matstat

Referenced by atnMake(), and ecatFixMatrixlist().

◆ ecat63CopyMainheader()

int ecat63CopyMainheader ( ECAT63_mainheader * h1,
ECAT63_mainheader * h2 )
extern

Copy ECAT 6.3 main header from one struct into another.

Returns
Returns 0 if ok.
Parameters
h1Pointer to source header
h2Pointer to target header

Definition at line 16 of file ecat63h.c.

21 {
22 int i;
23
24 if(h1==NULL || h2==NULL) return(1);
25 memset(h2, 0, sizeof(ECAT63_mainheader));
26
27 for(i=0; i<14; i++) h2->ecat_format[i]=h1->ecat_format[i];
28 for(i=0; i<14; i++) h2->fill1[i]=h1->fill1[i];
29 for(i=0; i<20; i++) h2->original_file_name[i]=h1->original_file_name[i];
30 h2->sw_version=h1->sw_version;
31 h2->data_type=h1->data_type;
33 h2->file_type=h1->file_type;
34 for(i=0; i<10; i++) h2->node_id[i]=h1->node_id[i];
41 for(i=0; i<8; i++) h2->isotope_code[i]=h1->isotope_code[i];
43 for(i=0; i<32; i++) h2->radiopharmaceutical[i]=h1->radiopharmaceutical[i];
50 h2->axial_fov=h1->axial_fov;
58 for(i=0; i<12; i++) h2->study_name[i]=h1->study_name[i];
59 for(i=0; i<16; i++) h2->patient_id[i]=h1->patient_id[i];
60 for(i=0; i<32; i++) h2->patient_name[i]=h1->patient_name[i];
62 for(i=0; i<10; i++) h2->patient_age[i]=h1->patient_age[i];
63 for(i=0; i<10; i++) h2->patient_height[i]=h1->patient_height[i];
64 for(i=0; i<10; i++) h2->patient_weight[i]=h1->patient_weight[i];
66 for(i=0; i<32; i++) h2->physician_name[i]=h1->physician_name[i];
67 for(i=0; i<32; i++) h2->operator_name[i]=h1->operator_name[i];
68 for(i=0; i<32; i++) h2->study_description[i]=h1->study_description[i];
70 h2->bed_type=h1->bed_type;
71 h2->septa_type=h1->septa_type;
72 for(i=0; i<20; i++) h2->facility_name[i]=h1->facility_name[i];
73 h2->num_planes=h1->num_planes;
74 h2->num_frames=h1->num_frames;
75 h2->num_gates=h1->num_gates;
78 for(i=0; i<15; i++) h2->bed_offset[i]=h1->bed_offset[i];
83 h2->collimator=h1->collimator;
84 for(i=0; i<10; i++) h2->user_process_code[i]=h1->user_process_code[i];
85 for(i=0; i<20; i++) h2->fill2[i]=h1->fill2[i];
86 return(0);
87}
short int coin_samp_mode
short int lwr_true_thres
short int compression_code
char patient_height[10]
short int fill2[20]
short int wobble_speed
short int transaxial_samp_mode
short int rot_source_speed
short int acquisition_type
char original_file_name[20]
short int transm_source_type
char patient_weight[10]
short int lwr_sctr_thres
short int axial_samp_mode
short int upr_true_thres
char physician_name[32]

Referenced by atnMake().

◆ ecat63CopyScanheader()

int ecat63CopyScanheader ( ECAT63_scanheader * h1,
ECAT63_scanheader * h2 )
extern

Copy ECAT 6.3 scan sub header from one struct into another.

Returns
Returns 0 if ok.
Parameters
h1Pointer to source header
h2Pointer to target header

Definition at line 94 of file ecat63h.c.

99 {
100 int i;
101
102 if(h1==NULL || h2==NULL) return(1);
103 memset(h2, 0, sizeof(ECAT63_scanheader));
104
105 for(i=0; i<126; i++) h2->fill1[i]=h1->fill1[i];
106 h2->data_type=h1->data_type;
107 h2->dimension_1=h1->dimension_1;
108 h2->dimension_2=h1->dimension_2;
109 h2->smoothing=h1->smoothing;
117 h2->scan_min=h1->scan_min;
118 h2->scan_max=h1->scan_max;
119 h2->prompts=h1->prompts;
120 h2->delayed=h1->delayed;
121 h2->multiples=h1->multiples;
122 h2->net_trues=h1->net_trues;
123 for(i=0; i<16; i++) h2->cor_singles[i]=h1->cor_singles[i];
124 for(i=0; i<16; i++) h2->uncor_singles[i]=h1->uncor_singles[i];
125 h2->tot_avg_cor=h1->tot_avg_cor;
131 for(i=0; i<22; i++) h2->fill2[i]=h1->fill2[i];
132 return(0);
133}
float uncor_singles[16]
short int processing_code
short int fill2[22]
float cor_singles[16]

◆ ecat63Create()

FILE * ecat63Create ( const char * fname,
ECAT63_mainheader * h )
extern

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.

Parameters
fnamefile name
hEcat 6.3 main header
Returns
opened file pointer, or NULL in case of failure

Definition at line 365 of file ecat63w.c.

367 {
368 FILE *fp;
369 char tmp[FILENAME_MAX];
370 int buf[MatBLKSIZE/4];
371
372 if(ECAT63_TEST) printf("ecat63Create()\n");
373 /* Check the arguments */
374 if(fname==NULL || h==NULL) return(NULL);
375 /* Check if file exists; backup, if necessary */
376 if(access(fname, 0) != -1) {
377 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
378 if(access(tmp, 0) != -1) remove(tmp);
379 if(ECAT63_TEST) printf("Renaming %s -> %s\n", fname, tmp);
380 rename(fname, tmp);
381 }
382 /* Open file */
383 fp=fopen(fname, "wb+"); if(fp==NULL) return(fp);
384 /* Write main header */
385 if(ecat63WriteMainheader(fp, h)) return(NULL);
386 /* Construct an empty matrix list ; convert to little endian if necessary */
387 memset(buf, 0, MatBLKSIZE);
388 buf[0]=31; buf[1]=2; if(!little_endian()) swawbip(buf, MatBLKSIZE);
389 /* Write data buffer */
390 fseek(fp, (MatFirstDirBlk-1)*MatBLKSIZE, SEEK_SET);
391 if(ftell(fp)!=(MatFirstDirBlk-1)*MatBLKSIZE) return(NULL);
392 if(fwrite(buf, 4, MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(NULL);
393 /* OK, then return file pointer */
394 return(fp);
395}
int ECAT63_TEST
Definition ecat63h.c:6
#define BACKUP_EXTENSION
#define MatFirstDirBlk
#define MatBLKSIZE

Referenced by atnMake(), ecat63AddImg(), ecat63CopyFile(), ecat63WriteAllImg(), and imgWriteEcat63Frame().

◆ ecat63Datatype()

char * ecat63Datatype ( short int dtype)
extern

Return pointer to string describing the ECAT 6.3 data_type

Parameters
dtypedata type code
Returns
pointer to static string

Definition at line 218 of file ecat63p.c.

220 {
221 static char *ecat63_datatype[]={
222 /* 0 */ "Unknown",
223 /* 1 */ "BYTE_TYPE",
224 /* 2 */ "VAX_I2",
225 /* 3 */ "VAX_I4",
226 /* 4 */ "VAX_R4",
227 /* 5 */ "IEEE_R4",
228 /* 6 */ "SUN_I2",
229 /* 7 */ "SUN_I4",
230 /* 8 */ "Unknown",
231 /* 9 */ "Unknown"
232 };
233 if(dtype>=0 && dtype<10) return(ecat63_datatype[dtype]);
234 else return(ecat63_datatype[0]);
235}

Referenced by ecat63PrintAttnheader(), ecat63PrintImageheader(), ecat63PrintMainheader(), ecat63PrintNormheader(), ecat63PrintScanheader(), and ecat63ReadMainheader().

◆ ecat63DeleteLateFrames()

int ecat63DeleteLateFrames ( MATRIXLIST * ml,
int frame_nr )
extern

Mark deleted the frames after the specified frame number.

This can be used to delete sum images from the end of dynamic ECAT images.

Parameters
mlmatrix list.
frame_nrlast index not to be marked as deleted.
Returns
number of deleted matrices.

Definition at line 342 of file ecat63ml.c.

344 {
345 int del_nr=0;
346 Matval matval;
347
348 for(int i=0; i<ml->matrixNr; i++) {
349 mat_numdoc(ml->matdir[i].matnum, &matval);
350 if(matval.frame>frame_nr) {del_nr++; ml->matdir[i].matstat=-1;}
351 }
352 return(del_nr);
353}

Referenced by ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), and imgReadEcat63Header().

◆ ecat63EditMHeader()

int ecat63EditMHeader ( ECAT63_mainheader * h,
char * field,
char * value,
int verbose )
extern

Edit ECAT 6.3 main header.

Returns
Returns 0, if ok, and 1 or 2, if field name or or value is invalid.
Parameters
hPointer to ECAT 6.3 mainheader structure
fieldField name to be changed
valueNew value for the field
verboseVerbose level; if <=0, then nothing is printed into stdout

Definition at line 140 of file ecat63h.c.

149 {
150// int yy, mm, dd;
151 short int si;
152 float f;
153
154 if(verbose>0) printf("ecat63EditMHeader('%s', '%s')\n", field, value);
155 si=atoi(value); f=atof(value);
156
157 if(strcmp(field, "ecat_format")==0 || strcmp(field, "magic_number")==0) {
158 strlcpy(h->ecat_format, value, 14);
159 } else if(strcmp(field, "fill1")==0) {
160 strlcpy(h->fill1, value, 14);
161 } else if(strcmp(field, "original_file_name")==0) {
162 strlcpy(h->original_file_name, value, 20);
163 } else if(strcmp(field, "sw_version")==0) {
164 if(si<=0) return(2); else h->sw_version=si;
165 } else if(strcmp(field, "data_type")==0) {
166 if(si<0) return(2); else h->data_type=si;
167 } else if(strcmp(field, "system_type")==0) {
168 if(si<0) return(2); else h->system_type=si;
169 } else if(strcmp(field, "file_type")==0) {
170 if(si<0) return(2); else h->file_type=si;
171 } else if(strcmp(field, "node_id")==0 || strcmp(field, "serial_number")==0) {
172 strlcpy(h->node_id, value, 10);
173 } else if(strcmp(field, "scan_start_day")==0) {
174 if(si<0) return(2); else h->scan_start_day=si;
175 } else if(strcmp(field, "scan_start_month")==0) {
176 if(si<0) return(2); else h->scan_start_month=si;
177 } else if(strcmp(field, "scan_start_year")==0) {
178 if(si<0) return(2); else h->scan_start_year=si;
179 } else if(strcmp(field, "scan_start_hour")==0) {
180 if(si<0) return(2); else h->scan_start_hour=si;
181 } else if(strcmp(field, "scan_start_minute")==0) {
182 if(si<0) return(2); else h->scan_start_minute=si;
183 } else if(strcmp(field, "scan_start_second")==0) {
184 if(si<0) return(2); else h->scan_start_second=si;
185 } else if(strcmp(field, "scan_start_time")==0) {
186 int YYYY, MM, DD, hh, mm, ss, n;
187 n=sscanf(value, "%d-%d-%d %d:%d:%d", &YYYY, &MM, &DD, &hh, &mm, &ss);
188 if(n!=6 && n!=3) return(2);
189 h->scan_start_year=YYYY;
190 h->scan_start_month=MM;
191 h->scan_start_day=DD;
192 if(n==6) {
193 h->scan_start_hour=hh;
194 h->scan_start_minute=mm;
195 h->scan_start_second=ss;
196 }
197 } else if(strcmp(field, "isotope_code")==0 || strcmp(field, "isotope_name")==0) {
198 strlcpy(h->isotope_code, value, 8);
199 } else if(strcmp(field, "isotope_halflife")==0) {
200 if(f<=1.0E-3) return(2); else h->isotope_halflife=f;
201 } else if(strcmp(field, "radiopharmaceutical")==0) {
202 strlcpy(h->radiopharmaceutical, value, 32);
203 } else if(strcmp(field, "gantry_tilt")==0) {
204 h->gantry_tilt=f;
205 } else if(strcmp(field, "gantry_rotation")==0) {
206 h->gantry_rotation=f;
207 } else if(strcmp(field, "bed_elevation")==0) {
208 h->bed_elevation=f;
209 } else if(strcmp(field, "rot_source_speed")==0) {
210 h->rot_source_speed=si;
211 } else if(strcmp(field, "wobble_speed")==0) {
212 h->wobble_speed=si;
213 } else if(strcmp(field, "transm_source_type")==0) {
214 h->transm_source_type=si;
215 } else if(strcmp(field, "axial_fov")==0) {
216 h->axial_fov=f;
217 } else if(strcmp(field, "transaxial_fov")==0) {
218 h->transaxial_fov=f;
219 } else if(strcmp(field, "transaxial_samp_mode")==0) {
221 } else if(strcmp(field, "coin_samp_mode")==0) {
222 h->coin_samp_mode=si;
223 } else if(strcmp(field, "axial_samp_mode")==0) {
224 h->axial_samp_mode=si;
225 } else if(strcmp(field, "calibration_factor")==0) {
227 } else if(strcmp(field, "calibration_units")==0) {
228 h->calibration_units=si;
229 } else if(strcmp(field, "compression_code")==0) {
230 h->compression_code=si;
231 } else if(strcmp(field, "study_name")==0) {
232 strlcpy(h->study_name, value, 12);
233 } else if(strcmp(field, "patient_id")==0) {
234 strlcpy(h->patient_id, value, 16);
235 } else if(strcmp(field, "patient_name")==0) {
236 strlcpy(h->patient_name, value, 32);
237 } else if(strcmp(field, "patient_sex")==0) {
238 h->patient_sex=value[0];
239 } else if(strcmp(field, "patient_age")==0) {
240 strlcpy(h->patient_name, value, 10);
241 } else if(strcmp(field, "patient_height")==0) {
242 strlcpy(h->patient_height, value, 10);
243 } else if(strcmp(field, "patient_weight")==0) {
244 strlcpy(h->patient_weight, value, 10);
245 } else if(strcmp(field, "patient_dexterity")==0) {
246 h->patient_dexterity=value[0];
247 } else if(strcmp(field, "physician_name")==0) {
248 strlcpy(h->physician_name, value, 32);
249 } else if(strcmp(field, "operator_name")==0) {
250 strlcpy(h->operator_name, value, 32);
251 } else if(strcmp(field, "study_description")==0) {
252 strlcpy(h->study_description, value, 32);
253 } else if(strcmp(field, "acquisition_type")==0) {
254 h->acquisition_type=si;
255 } else if(strcmp(field, "bed_type")==0) {
256 h->bed_type=si;
257 } else if(strcmp(field, "septa_type")==0) {
258 h->septa_type=si;
259 } else if(strcmp(field, "facility_name")==0) {
260 strlcpy(h->facility_name, value, 20);
261 } else if(strcmp(field, "num_planes")==0) {
262 h->num_planes=si;
263 } else if(strcmp(field, "num_frames")==0) {
264 h->num_frames=si;
265 } else if(strcmp(field, "num_gates")==0) {
266 h->num_gates=si;
267 } else if(strcmp(field, "num_bed_pos")==0) {
268 h->num_bed_pos=si;
269 } else if(strcmp(field, "init_bed_position")==0) {
271 } else if(strcmp(field, "bed_offset")==0) {
272 sscanf(value, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
273 h->bed_offset+0, h->bed_offset+1, h->bed_offset+2,
274 h->bed_offset+3, h->bed_offset+4, h->bed_offset+5,
275 h->bed_offset+6, h->bed_offset+7, h->bed_offset+8,
276 h->bed_offset+9, h->bed_offset+10, h->bed_offset+11,
277 h->bed_offset+12, h->bed_offset+13, h->bed_offset+14
278 );
279 } else if(strcmp(field, "plane_separation")==0) {
280 h->plane_separation=f;
281 } else if(strcmp(field, "lwr_sctr_thres")==0) {
282 h->lwr_sctr_thres=si;
283 } else if(strcmp(field, "lwr_true_thres")==0) {
284 h->lwr_true_thres=si;
285 } else if(strcmp(field, "upr_true_thres")==0) {
286 h->upr_true_thres=si;
287 } else if(strcmp(field, "collimator")==0) {
288 h->collimator=f;
289 } else if(strcmp(field, "user_process_code")==0) {
290 strlcpy(h->user_process_code, value, 10);
291 } else if(strcasecmp(field, "FILL2")==0) {
292 char *cptr;
293 cptr=strtok(value, " \t,;\n\r");
294 for(int i=0; i<20; i++) {
295 if(cptr==NULL) break;
296 h->fill2[i]=(short int)atoi(cptr);
297 cptr=strtok(NULL, " \t,;\n\r");
298 }
299 } else
300 return(1);
301
302 return(0);
303}

◆ ecat63EmptyMatlist()

void ecat63EmptyMatlist ( MATRIXLIST * mlist)
extern

Free memory allocated for ECAT matrix list

Parameters
mlistmatrix list

Definition at line 31 of file ecat63ml.c.

31 {
32 if(mlist->matrixSpace>0) free((char*)(mlist->matdir));
33 mlist->matrixSpace=mlist->matrixNr=0;
34}

Referenced by atnMake(), ecat63AddImg(), ecat63ReadAllToImg(), ecat63ReadMatlist(), ecat63ReadPlaneToImg(), ecat6PrintSubheader(), imgReadEcat63Frame(), and imgReadEcat63Header().

◆ ecat63GatherMatlist()

int ecat63GatherMatlist ( MATRIXLIST * ml,
short int do_planes,
short int do_frames,
short int do_gates,
short int do_beds )
extern

Matrix numbers in ECAT 6.3 matrix list are edited, when necessary, so that plane, frame, gate and/or bed numbers are continuous, starting from one (planes, frames and gates) or from zero (beds). List order is not changed.

Parameters
mlECAT 6.3 matrix list, where the matrix numbers will be edited
do_planesPlane numbers are gathered together (1) or not (0)
do_framesFrame numbers are gathered together (1) or not (0)
do_gatesGate numbers are gathered together (1) or not (0)
do_bedsBed numbers are gathered together (1) or not (0)
Returns
0 if successful, 1 if invalid input, 3 failed to allocate memory

Definition at line 510 of file ecat63ml.c.

513 {
514 int i, ncurr, n;
515 Matval* matval;
516
517 if(ml==NULL) return(1);
518 if(ml->matrixNr<1) return(0);
519
520 /* Allocate memory for matrix values */
521 matval = (Matval*)calloc(ml->matrixNr,sizeof(Matval));
522 if(matval == NULL) return(3);
523
524 /* And get the matrix values */
525 for(i=0; i<ml->matrixNr; i++) mat_numdoc(ml->matdir[i].matnum, matval+i);
526
527 /* Planes */
528 if(do_planes!=0) {
529 ncurr=1;
530 while(ncurr <= ml->matrixNr) {
531 /* Find any matrix with this number? */
532 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].plane==ncurr) {n=1; break;}
533 /* If yes, then go on to the next matrix number */
534 if(n==1) {ncurr++; continue;}
535 /* If not, then subtract 1 from all matrix numbers that are larger */
536 for(i=0, n=0; i<ml->matrixNr; i++)
537 if(matval[i].plane>ncurr) {
538 matval[i].plane--; n++;
539 }
540 /* If no larger values were found any more, then quit */
541 if(n<1) break;
542 }
543 }
544
545 /* Frames */
546 if(do_frames!=0) {
547 ncurr=1;
548 while(ncurr <= ml->matrixNr) {
549 /* Find any matrix with this number? */
550 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].frame==ncurr) {n=1; break;}
551 /* If yes, then go on to the next matrix number */
552 if(n==1) {ncurr++; continue;}
553 /* If not, then subtract 1 from all matrix numbers that are larger */
554 for(i=0, n=0; i<ml->matrixNr; i++)
555 if(matval[i].frame>ncurr) {matval[i].frame--; n++;}
556 /* If no larger values were found any more, then quit */
557 if(n<1) break;
558 }
559 }
560
561 /* Gates */
562 if(do_gates!=0) {
563 ncurr=1;
564 while(ncurr <= ml->matrixNr) {
565 /* Find any matrix with this number? */
566 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].gate==ncurr) {n=1; break;}
567 /* If yes, then go on to the next matrix number */
568 if(n==1) {ncurr++; continue;}
569 /* If not, then subtract 1 from all matrix numbers that are larger */
570 for(i=0, n=0; i<ml->matrixNr; i++)
571 if(matval[i].gate>ncurr) {matval[i].gate--; n++;}
572 /* If no larger values were found any more, then quit */
573 if(n<1) break;
574 }
575 }
576
577 /* Beds */
578 if(do_beds!=0) {
579 ncurr=1;
580 while(ncurr <= ml->matrixNr) {
581 /* Find any matrix with this number? */
582 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].bed==ncurr) {n=1; break;}
583 /* If yes, then go on to the next matrix number */
584 if(n==1) {ncurr++; continue;}
585 /* If not, then subtract 1 from all matrix numbers that are larger */
586 for(i=0, n=0; i<ml->matrixNr; i++)
587 if(matval[i].bed>ncurr) {matval[i].bed--; n++;}
588 /* If no larger values were found any more, then quit */
589 if(n<1) break;
590 }
591 }
592
593 /* Write matrix values (possibly changed) into matrix list */
594 for(i=0; i<ml->matrixNr; i++) ml->matdir[i].matnum=mat_numcod(
595 matval[i].frame, matval[i].plane,
596 matval[i].gate, matval[i].data,
597 matval[i].bed);
598 free(matval);
599 return(0);
600}

Referenced by ecatFixMatrixlist(), imgReadEcat63Frame(), and imgReadEcat63Header().

◆ ecat63GetMatrixBlockSize()

int ecat63GetMatrixBlockSize ( MATRIXLIST * mlist,
int * blk_nr )
extern

Calculate the size of one data matrix in ECAT 6.3 file matrix list, and check that the size is same in all matrices.

Parameters
mlistEcat 6.3 matrix list; note that this list is here sorted by planes
blk_nrNumber of blocks will be put here; NULL if not needed
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 366 of file ecat63ml.c.

368 {
369 int m, prev_blk, blk;
370
371 /* Check input */
372 if(mlist==NULL) return STATUS_FAULT;
373 if(blk_nr!=NULL) *blk_nr=0;
374
375 /* Calculate the size of first data matrix */
376 m=0; prev_blk=blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
377 for(m=1; m<mlist->matrixNr; m++) {
378 blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
379 if(blk!=prev_blk) return STATUS_VARMATSIZE;
380 else prev_blk=blk;
381 }
382 if(blk_nr!=NULL) *blk_nr=blk;
383 return STATUS_OK;
384}
int endblk
int strtblk

Referenced by imgReadEcat63Frame(), and imgReadEcat63Header().

◆ ecat63GetNums()

int ecat63GetNums ( MATRIXLIST * ml,
short int * num_planes,
short int * num_frames,
short int * num_gates,
short int * num_bed_pos )
extern

Read the maximum plane, frame, gate and bed number from matrixlist.

Parameters
mlPointer to matrixlist
num_planesnumber of planes will be put here; NULL if not needed
num_framesnumber of frames will be put here; NULL if not needed
num_gatesnumber of gates will be put here; NULL if not needed
num_bed_posnumber of gates will be put here; NULL if not needed
Returns
0 if successful, 1 no matrix list, 2 invalid matrix number, 3 failed to allocate memory

Definition at line 450 of file ecat63ml.c.

453 {
454 int i, nmax;
455 Matval* matval;
456
457 if(ml==NULL) return(1);
458 if(ml->matrixNr<1) return(2);
459
460 /* Allocate memory for matrix values */
461 matval = (Matval*)calloc(ml->matrixNr,sizeof(Matval));
462 if(matval == NULL) return(3);
463
464 /* And get the matrix values */
465 for(i=0; i<ml->matrixNr; i++) mat_numdoc(ml->matdir[i].matnum, matval+i);
466
467 /* Planes */
468 if(num_planes!=NULL) {
469 nmax=matval[0].plane;
470 for(i=1; i<ml->matrixNr; i++) if(matval[i].plane>nmax) nmax=matval[i].plane;
471 *num_planes=nmax;
472 }
473 /* Frames */
474 if(num_frames!=NULL) {
475 nmax=matval[0].frame;
476 for(i=1; i<ml->matrixNr; i++) if(matval[i].frame>nmax) nmax=matval[i].frame;
477 *num_frames=nmax;
478 }
479 /* Gates */
480 if(num_gates!=NULL) {
481 nmax=matval[0].gate;
482 for(i=1; i<ml->matrixNr; i++) if(matval[i].gate>nmax) nmax=matval[i].gate;
483 *num_gates=nmax;
484 }
485 /* Beds */
486 if(num_bed_pos!=NULL) {
487 nmax=matval[0].bed;
488 for(i=1; i<ml->matrixNr; i++) if(matval[i].bed>nmax) nmax=matval[i].bed;
489 *num_bed_pos=nmax;
490 }
491 free(matval);
492 return(0);
493}

Referenced by ecatFixMatrixlist().

◆ ecat63GetPlaneAndFrameNr()

int ecat63GetPlaneAndFrameNr ( MATRIXLIST * mlist,
ECAT63_mainheader * h,
int * plane_nr,
int * frame_nr )
extern

Calculate the number of planes and frames/gates from ECAT 6.3 matrix list. Check that all planes have equal nr of frames/gates, that frames/gates are sequentially numbered. This routines sorts the matrix list by planes.

Parameters
mlistEcat 6.3 matrix list; note that this list is here sorted by planes
hEcat 6.3 mainheader
plane_nrNumber of planes will be put here; NULL if not needed
frame_nrNumber of frames/gates will be put here; NULL if not needed
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 400 of file ecat63ml.c.

402 {
403 Matval matval;
404 int m, plane, frame, prev_plane, prev_frame, fnr, pnr;
405
406 /* Check input */
407 if(mlist==NULL) return STATUS_FAULT;
408 if(plane_nr!=NULL) *plane_nr=0;
409 if(frame_nr!=NULL) *frame_nr=0;
410
411 /* Sort matrices by plane so that following computation works */
413
414 prev_plane=plane=-1; prev_frame=frame=-1;
415 fnr=pnr=0;
416 for(m=0; m<mlist->matrixNr; m++) if(mlist->matdir[m].matstat==1) {
417 mat_numdoc(mlist->matdir[m].matnum, &matval);
418 plane=matval.plane;
419 if(h->num_frames>=h->num_gates)
420 frame=matval.frame;
421 else
422 frame=matval.gate;
423 if(plane!=prev_plane) {
424 fnr=1; pnr++;
425 } else {
426 fnr++;
427 if(prev_frame>0 && frame!=prev_frame+1) return STATUS_MISSINGMATRIX;
428 }
429 prev_plane=plane; prev_frame=frame;
430 } /* next matrix */
431 if(fnr*pnr != mlist->matrixNr) return STATUS_MISSINGMATRIX;
432 if(plane_nr!=NULL) *plane_nr=pnr;
433 if(frame_nr!=NULL) *frame_nr=fnr;
434 return STATUS_OK;
435}
void ecat63SortMatlistByPlane(MATRIXLIST *ml)
Definition ecat63ml.c:271

Referenced by imgReadEcat63Header().

◆ ecat63InitMatlist()

void ecat63InitMatlist ( MATRIXLIST * mlist)
extern

Initiate ECAT matrix list. Call this once before first use.

Parameters
mlistmatrix list

Definition at line 20 of file ecat63ml.c.

20 {
21 mlist->matrixSpace=mlist->matrixNr=0; mlist->matdir=NULL;
22}

Referenced by atnMake(), ecat63AddImg(), ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), ecat6PrintSubheader(), ecatFixMatrixlist(), imgReadEcat63Frame(), and imgReadEcat63Header().

◆ ecat63Matenter()

int ecat63Matenter ( FILE * fp,
int matnum,
int blkNr )
extern

Prepare matrix list for additional matrix data and Directory records are written in big endian byte order. Set block_nr to the number of data blocks excluding header;

Parameters
fpfile pointer
matnummatrix number [1..number of matrices]
blkNrmatrix block number [ >= 1]
Returns
block number for matrix header, or 0 in case of an error.

Definition at line 159 of file ecat63ml.c.

161 {
162 unsigned int i=0, dirblk, little, busy=1, nxtblk=0, oldsize;
163 unsigned int dirbuf[MatBLKSIZE/4];
164
165 if(ECAT63_TEST) printf("ecat63Matenter(fp, %d, %d)\n", matnum, blkNr);
166 if(fp==NULL || matnum<1 || blkNr<1) return(0);
167 little=little_endian(); memset(dirbuf, 0, MatBLKSIZE);
168 /* Read first matrix list block */
169 dirblk=MatFirstDirBlk;
170 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
171 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
172 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
173 /* Byte order conversion for ints in big endian platforms */
174 if(!little) swawbip(dirbuf, MatBLKSIZE);
175
176 while(busy) {
177 nxtblk=dirblk+1;
178 for(i=4; i<MatBLKSIZE/4; i+=4) {
179 if(dirbuf[i]==0) { /* Check for end of matrix list */
180 busy=0; break;
181 } else if(dirbuf[i]==(unsigned int)matnum) { /* Check if this matrix already exists */
182 oldsize=dirbuf[i+2]-dirbuf[i+1]+1;
183 if(oldsize<(unsigned int)blkNr) { /* If old matrix is smaller */
184 dirbuf[i] = 0xFFFFFFFF;
185 if(!little) swawbip(dirbuf, MatBLKSIZE);
186 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
187 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
188 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
189 if(!little) swawbip(dirbuf, MatBLKSIZE);
190 nxtblk=dirbuf[i+2]+1;
191 } else { /* old matrix size is ok */
192 nxtblk=dirbuf[i+1]; dirbuf[0]++; dirbuf[3]--; busy=0;
193 break;
194 }
195 } else /* not this one */
196 nxtblk=dirbuf[i+2]+1;
197 }
198 if(!busy) break;
199 if(dirbuf[1]!=MatFirstDirBlk) {
200 dirblk=dirbuf[1];
201 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
202 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
203 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
204 if(!little) swawbip(dirbuf, MatBLKSIZE);
205 } else {
206 dirbuf[1]=nxtblk;
207 if(!little) swawbip(dirbuf, MatBLKSIZE);
208 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
209 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
210 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
211 dirbuf[0]=31; dirbuf[1]=MatFirstDirBlk; dirbuf[2]=dirblk;
212 dirbuf[3]=0; dirblk=nxtblk;
213 for(i=4; i<MatBLKSIZE/4; i++) dirbuf[i]=0;
214 }
215 }
216 dirbuf[i]=matnum;
217 dirbuf[i+1]=nxtblk;
218 dirbuf[i+2]=nxtblk+blkNr;
219 dirbuf[i+3]=1;
220 dirbuf[0]--;
221 dirbuf[3]++;
222 if(!little) swawbip(dirbuf, MatBLKSIZE);
223 fseeko(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
224 if(ftello(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(0);
225 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(0);
226 if(ECAT63_TEST) printf("returning %d from ecat63Matenter()\n", nxtblk);
227 return(nxtblk);
228}

Referenced by ecat63CopyFile(), ecat63WriteAttn(), ecat63WriteImage(), ecat63WriteImageMatrix(), ecat63WriteNorm(), ecat63WriteScan(), and ecat63WriteScanMatrix().

◆ ecat63PrintAttnheader()

void ecat63PrintAttnheader ( ECAT63_attnheader * h,
FILE * fp )
extern

Print ECAT 6.3 attnheader contents to specified file pointer

Parameters
hEcat 6.3 attenuation header
fptarget file pointer

Definition at line 173 of file ecat63p.c.

175 {
176 if(ECAT63_TEST) printf("ecat63PrintAttnheader()\n");
177 fprintf(fp, "data_type := %d (%s)\n", h->data_type, ecat63Datatype(h->data_type));
178 fprintf(fp, "dimension_1 := %d\n", h->dimension_1);
179 fprintf(fp, "dimension_2 := %d\n", h->dimension_2);
180 fprintf(fp, "sample_distance := %g cm\n", h->sample_distance);
181 fprintf(fp, "attenuation_type := %d\n", h->attenuation_type);
182 fprintf(fp, "scale_factor := %g\n", h->scale_factor);
183 fprintf(fp, "x_origin := %g\ny_origin := %g\nx_radius := %g\ny_radius := %g\n",
184 h->x_origin, h->y_origin, h->x_radius, h->y_radius);
185 fprintf(fp, "tilt_angle := %g\nattenuation_coeff := %g\n",
187}
char * ecat63Datatype(short int dtype)
Definition ecat63p.c:218
short int dimension_1
short int dimension_2
short int attenuation_type

Referenced by ecat63ReadAttnMatrix(), and ecat6PrintSubheader().

◆ ecat63PrintImageheader()

void ecat63PrintImageheader ( ECAT63_imageheader * h,
FILE * fp )
extern

Print ECAT 6.3 imageheader contents to specified file pointer

Parameters
hEcat 6.3 image header
fptarget file pointer

Definition at line 94 of file ecat63p.c.

96 {
97 if(ECAT63_TEST) printf("ecat63PrintImageheader()\n");
98 fprintf(fp, "data_type := %d (%s)\n", h->data_type, ecat63Datatype(h->data_type));
99 fprintf(fp, "dimension_1 := %d\n", h->dimension_1);
100 fprintf(fp, "dimension_2 := %d\n", h->dimension_2);
101 fprintf(fp, "x_origin := %g\ny_origin := %g\nrecon_scale := %g\n",
102 h->x_origin, h->y_origin, h->recon_scale);
103 fprintf(fp, "quant_scale := %g\nimage_min := %d\nimage_max := %d\n",
104 h->quant_scale, h->image_min, h->image_max);
105 fprintf(fp, "slice_width := %g\npixel_size := %g\n", h->slice_width, h->pixel_size);
106 fprintf(fp, "frame_start_time := %d\nframe_duration := %d\n",
108/*
109 fprintf(fp, "reconstruction_start := %02d.%02d.%04d %02d:%02d:%02d\n",
110 h->recon_start_day, h->recon_start_month, h->recon_start_year,
111 h->recon_start_hour, h->recon_start_min, h->recon_start_sec);
112*/
113 fprintf(fp, "reconstruction_start := %04d-%02d-%02d %02d:%02d:%02d\n",
116 fprintf(fp, "filter_code := %d\nimage_rotation := %g\nintrinsic_tilt := %g\n",
118 fprintf(fp, "filter_params :=");
119 for(int i=0; i<6; i++) fprintf(fp, " %g", h->filter_params[i]);
120 fprintf(fp, "\n");
121 fprintf(fp, "plane_eff_corr_fctr := %g\ndecay_corr_fctr := %g\nloss_corr_fctr := %g\n",
123 fprintf(fp, "quant_units := %d (%s)\n", h->quant_units, ecat63Unit(h->quant_units));
124 fprintf(fp, "ecat_calibration_fctr := %g\nwell_counter_cal_fctr := %g\n",
126 fprintf(fp, "annotation := %.40s\n", h->annotation);
127}
char * ecat63Unit(short int dunit)
Definition ecat63p.c:243
short int recon_start_month
short int recon_start_day
short int recon_start_min
short int recon_start_year
short int recon_start_hour
short int recon_start_sec

Referenced by ecat63ReadImageMatrix(), ecat63WriteAllImg(), and ecat6PrintSubheader().

◆ ecat63PrintMainheader()

void ecat63PrintMainheader ( ECAT63_mainheader * h,
FILE * fp )
extern

Print ECAT 6.3 mainheader contents to specified file pointer.

Parameters
hEcat 6.3 main header
fpfile pointer

Definition at line 16 of file ecat63p.c.

18 {
19 char tmp[32];
20
21 if(ECAT63_TEST) fprintf(stdout, "ecat63PrintMainheader()\n");
22
23 fprintf(fp, "original_file_name := %.20s\n", h->original_file_name);
24 fprintf(fp, "sw_version := %d\n", h->sw_version);
25 fprintf(fp, "data_type := %d (%s)\n",
27 fprintf(fp, "system_type := %d\n", h->system_type);
28 if(h->file_type==1) strcpy(tmp, "sinogram");
29 else if(h->file_type==2) strcpy(tmp, "image");
30 else if(h->file_type==3) strcpy(tmp, "attenuation");
31 else if(h->file_type==4) strcpy(tmp, "normalization");
32 else strcpy(tmp, "unknown");
33 fprintf(fp, "file_type := %d (%s)\n", h->file_type, tmp);
34 fprintf(fp, "scan_start_time := %04d-%02d-%02d %02d:%02d:%02d\n",
37/*
38 fprintf(fp, "scan start := %02d.%02d.%04d %02d:%02d:%02d\n",
39 h->scan_start_day, h->scan_start_month, h->scan_start_year,
40 h->scan_start_hour, h->scan_start_minute, h->scan_start_second);
41*/
42 fprintf(fp, "isotope_code := %.8s\n", h->isotope_code);
43 fprintf(fp, "isotope_halflife := %E sec\n", h->isotope_halflife);
44 fprintf(fp, "radiopharmaceutical := %.32s\n", h->radiopharmaceutical);
45 fprintf(fp, "gantry_tilt := %g\n", h->gantry_tilt);
46 fprintf(fp, "gantry_rotation := %g\n", h->gantry_rotation);
47 fprintf(fp, "bed_elevation := %g\n", h->bed_elevation);
48 fprintf(fp, "axial_fov := %g\n", h->axial_fov);
49 fprintf(fp, "transaxial_fov := %g\n", h->transaxial_fov);
50 fprintf(fp, "calibration_factor := %g\n", h->calibration_factor);
51 fprintf(fp, "calibration_units := %d (%s)\n",
53 fprintf(fp, "study_name := %.12s\n", h->study_name);
54 fprintf(fp, "patient_id := %.32s\n", h->patient_id);
55 fprintf(fp, "patient_name := %.32s\n", h->patient_name);
56
57 if(isalnum(h->patient_sex))
58 fprintf(fp, "patient_sex := %c\n", h->patient_sex);
59 else fprintf(fp, "patient_sex := \n");
60
61 fprintf(fp, "patient_age := %.10s\n", h->patient_age);
62 fprintf(fp, "patient_height := %.10s\n", h->patient_height);
63 fprintf(fp, "patient_weigth := %.10s\n", h->patient_weight);
64
65 if(isalnum(h->patient_dexterity))
66 fprintf(fp, "patient_dexterity := %c\n", h->patient_dexterity);
67 else fprintf(fp, "patient_dexterity := \n");
68
69 fprintf(fp, "physician_name := %.32s\n", h->physician_name);
70 fprintf(fp, "operator_name := %.32s\n", h->operator_name);
71 fprintf(fp, "study_description := %.32s\n", h->study_description);
72 fprintf(fp, "acquisition_type := %d\n", h->acquisition_type);
73 fprintf(fp, "bed_type := %d\n", h->bed_type);
74 fprintf(fp, "septa_type := %d\n", h->septa_type);
75 fprintf(fp, "facility_name := %.20s\n", h->facility_name);
76
77 fprintf(fp, "num_planes := %d\n", h->num_planes);
78 fprintf(fp, "num_frames := %d\n", h->num_frames);
79 fprintf(fp, "num_gates := %d\n", h->num_gates);
80 fprintf(fp, "num_bed_pos := %d\n", h->num_bed_pos);
81 fprintf(fp, "init_bed_position := %g\n", h->init_bed_position);
82 fprintf(fp, "plane_separation := %g cm\n", h->plane_separation);
83 fprintf(fp, "user_process_code := %.10s\n", h->user_process_code);
84}

Referenced by atnMake(), ecat63AddImg(), ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), ecat63WriteAllImg(), and imgWriteEcat63Frame().

◆ ecat63PrintMatlist()

void ecat63PrintMatlist ( MATRIXLIST * ml)
extern

Print ECAT matrix list on stdout.

Parameters
mlPointer to matrix list to print.

Definition at line 130 of file ecat63ml.c.

133 {
134 int i;
135 Matval matval;
136
137 printf("nr\tmatrix\tpl\tfr\tgate\tbed\tstartblk\tblknr\n");
138 for(i=0; i<ml->matrixNr; i++) {
139 mat_numdoc(ml->matdir[i].matnum, &matval);
140 printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", i+1, ml->matdir[i].matnum,
141 matval.plane, matval.frame, matval.gate, matval.bed,
142 ml->matdir[i].strtblk, 1+ml->matdir[i].endblk-ml->matdir[i].strtblk);
143 }
144 return;
145}

Referenced by ecat63ReadAllToImg(), ecat6PrintSubheader(), and ecatFixMatrixlist().

◆ ecat63PrintNormheader()

void ecat63PrintNormheader ( ECAT63_normheader * h,
FILE * fp )
extern

Print ECAT 6.3 normheader contents to specified file pointer.

Parameters
hEcat 6.3 normalization header
fptarget file pointer

Definition at line 197 of file ecat63p.c.

199 {
200 if(ECAT63_TEST) printf("ecat63PrintNormheader()\n");
201 fprintf(fp, "data_type := %d (%s)\n", h->data_type, ecat63Datatype(h->data_type));
202 fprintf(fp, "dimension_1 := %d\n", h->dimension_1);
203 fprintf(fp, "dimension_2 := %d\n", h->dimension_2);
204 fprintf(fp, "scale_factor := %g\n", h->scale_factor);
205 fprintf(fp, "norm_time := %04d-%02d-%02d %02d:%02d:%02d\n",
206 h->norm_year, h->norm_month, h->norm_day,
208}
short int dimension_1
short int norm_second
short int dimension_2
short int norm_minute

Referenced by ecat6PrintSubheader().

◆ ecat63PrintScanheader()

void ecat63PrintScanheader ( ECAT63_scanheader * h,
FILE * fp )
extern

Print ECAT 6.3 scanheader contents to specified file pointer

Parameters
hEcat 6.3 scan header
fptarget file pointer

Definition at line 137 of file ecat63p.c.

139 {
140 if(ECAT63_TEST) printf("ecat63PrintScanheader()\n");
141 fprintf(fp, "data_type := %d (%s)\n", h->data_type, ecat63Datatype(h->data_type));
142 fprintf(fp, "dimension_1 := %d\n", h->dimension_1);
143 fprintf(fp, "dimension_2 := %d\n", h->dimension_2);
144 fprintf(fp, "sample_distance := %g cm\n", h->sample_distance);
145 fprintf(fp, "isotope_halflife := %g sec\n", h->isotope_halflife);
146 fprintf(fp, "gate_duration := %d\nr_wave_offset := %d\n",
148 fprintf(fp, "scale_factor := %g\n", h->scale_factor);
149 fprintf(fp, "scan_min := %d\nscan_max := %d\n", h->scan_min, h->scan_max);
150 fprintf(fp, "prompts := %d\ndelayed := %d\nmultiples := %d\nnet_trues := %d\n",
151 h->prompts, h->delayed, h->multiples, h->net_trues);
152 fprintf(fp, "cor_singles :=");
153 for(int i=0; i<16; i++) fprintf(fp, " %8.0f", h->cor_singles[i]);
154 printf("\n");
155 fprintf(fp, "uncor_singles :=");
156 for(int i=0; i<16; i++) fprintf(fp, " %8.0f", h->uncor_singles[i]);
157 printf("\n");
158 fprintf(fp, "tot_avg_cor := %g\ntot_avg_uncor := %g\n", h->tot_avg_cor, h->tot_avg_uncor);
159 fprintf(fp, "total_coin_rate := %d\n", h->total_coin_rate);
160 fprintf(fp, "frame_start_time := %d\nframe_duration := %d\n",
162 fprintf(fp, "loss_correction_fctr := %g\n", h->loss_correction_fctr);
163}

Referenced by atnMake(), ecat63ReadScanMatrix(), ecat63WriteAllImg(), and ecat6PrintSubheader().

◆ ecat63pxlbytes()

int ecat63pxlbytes ( short int data_type)
extern

Returns the nr of bytes required for storage of one pixel of specified data_type

Parameters
data_typedata type code
Returns
number of bytes

Definition at line 973 of file ecat63r.c.

975 {
976 int byteNr=0;
977 switch(data_type) {
978 case BYTE_TYPE: byteNr=1; break;
979 case VAX_I2:
980 case SUN_I2: byteNr=2; break;
981 case VAX_I4:
982 case VAX_R4:
983 case IEEE_R4:
984 case SUN_I4: byteNr=4; break;
985 }
986 return(byteNr);
987}
#define SUN_I4
#define VAX_R4
#define IEEE_R4
#define BYTE_TYPE
#define VAX_I4
#define SUN_I2

Referenced by ecat63WriteImageMatrix(), and ecat63WriteScanMatrix().

◆ ecat63ReadAllToImg()

int ecat63ReadAllToImg ( const char * fname,
IMG * img )
extern

Read all matrices in ECAT file to memory.

Sinograms are dead-time corrected.

See also
imgInit
Returns
0 if ok, 1 invalid input, 3 failed to open file for reading, 4 failed to read main header, 5 failed to read matrix list, 6 matrix not found, 7 variable matrix sizes, 8 failed to read matrix sub header, 9 failed to allocate memory for data, 10 failed to read sub header, 11 failed to read matrix data.
Parameters
fnameName of the input ECAT 6.3 file.
imgData structure in which the file is read; must be initialized before using this function.

Definition at line 22 of file img_e63.c.

28 {
29 int m, ret, blkNr=0, dim_x=0, dim_y=0;
30 int frameNr, planeNr, del_nr=0;
31 int frame, plane, prev_frame, prev_plane, seqplane;
32 FILE *fp;
33 ECAT63_mainheader main_header;
34 MATRIXLIST mlist;
35 MatDir tmpMatdir;
36 Matval matval;
37 ECAT63_imageheader image_header;
38 ECAT63_scanheader scan_header;
39 ECAT63_attnheader attn_header;
40 ECAT63_normheader norm_header;
41 float scale=1.0;
42 short int *sptr;
43 char *mdata=NULL, *mptr;
44 /*int *iptr;*/
45
46
47 if(IMG_TEST) printf("ecat63ReadAllToImg(%s, *img)\n", fname);
48 /* Check the arguments */
49 if(fname==NULL || img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
50 if(img) imgSetStatus(img, STATUS_FAULT);
51 return 1;
52 }
53
54 /* Open input CTI file for read */
55 if((fp=fopen(fname, "rb")) == NULL) {
56 imgSetStatus(img, STATUS_NOFILE);
57 return 3;
58 }
59
60 /* Read main header */
61 if((ret=ecat63ReadMainheader(fp, &main_header))) {
62 imgSetStatus(img, STATUS_NOMAINHEADER);
63 return 4;
64 }
65 if(IMG_TEST>5) ecat63PrintMainheader(&main_header, stdout);
66
67 /* Read matrix list and nr */
68 ecat63InitMatlist(&mlist);
69 ret=ecat63ReadMatlist(fp, &mlist, ECAT63_TEST-1);
70 if(ret) {
71 imgSetStatus(img, STATUS_NOMATLIST);
72 return 5;
73 }
74 if(mlist.matrixNr<=0) {
75 strcpy(ecat63errmsg, "matrix list is empty");
76 return 5;
77 }
78 /* Sort matrix list */
79 for(int i=0; i<mlist.matrixNr-1; i++)
80 for(int j=i+1; j<mlist.matrixNr; j++) {
81 if(mlist.matdir[i].matnum>mlist.matdir[j].matnum) {
82 tmpMatdir=mlist.matdir[i];
83 mlist.matdir[i]=mlist.matdir[j]; mlist.matdir[j]=tmpMatdir;
84 }
85 }
86 if(IMG_TEST>6) {
87 printf("matrix list after sorting:\n");
88 ecat63PrintMatlist(&mlist);
89 }
90
91 /* Trim extra frames */
92 if(main_header.num_frames>0) {
93 del_nr=ecat63DeleteLateFrames(&mlist, main_header.num_frames);
94 if(IMG_TEST && del_nr>0)
95 printf(" %d entries in matrix list will not be used.\n", del_nr);
96 }
97 /* Calculate the number of planes, frames and gates */
98 /* Check that all planes have equal nr of frames (gates) */
99 /* and check that frames (gates) are consequentially numbered */
100 prev_plane=plane=-1; prev_frame=frame=-1; frameNr=planeNr=0; ret=0;
101 for(int m=0; m<mlist.matrixNr; m++) if(mlist.matdir[m].matstat==1) {
102 /* get frame and plane */
103 mat_numdoc(mlist.matdir[m].matnum, &matval);
104 plane=matval.plane;
105 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
106 else frame=matval.gate;
107 if(IMG_TEST>2) printf("frame=%d plane=%d\n", frame, plane);
108 /* did plane change? */
109 if(plane!=prev_plane) {
110 frameNr=1; planeNr++;
111 } else {
112 frameNr++;
113 /* In each plane, frame (gate) numbers must be continuous */
114 if(prev_frame>0 && frame!=prev_frame+1) {ret=1; break;}
115 }
116 prev_plane=plane; prev_frame=frame;
117 /* Calculate and check the size of one data matrix */
118 if(m==0) {
119 blkNr=mlist.matdir[m].endblk-mlist.matdir[m].strtblk;
120 } else if(blkNr!=mlist.matdir[m].endblk-mlist.matdir[m].strtblk) {
121 ret=2; break;
122 }
123 } /* next matrix */
124 if(IMG_TEST) printf("frameNr=%d planeNr=%d\n", frameNr, planeNr);
125 if(ret==1 || (frameNr*planeNr != mlist.matrixNr-del_nr)) {
126 strcpy(ecat63errmsg, "missing matrix");
127 ecat63EmptyMatlist(&mlist); fclose(fp);
128 return(6); /* this number is used in imgRead() */
129 }
130 if(ret==2) {
131 strcpy(ecat63errmsg, "matrix sizes are different");
132 ecat63EmptyMatlist(&mlist); fclose(fp); return(7);
133 }
134 /* Read x,y-dimensions from 1st matrix subheader */
135 m=0; if(main_header.file_type==IMAGE_DATA) {
136 ret=ecat63ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header, IMG_TEST-4, NULL);
137 dim_x=image_header.dimension_1; dim_y=image_header.dimension_2;
138 } else if(main_header.file_type==RAW_DATA) {
139 ret=ecat63ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header, IMG_TEST-4, NULL);
140 dim_x=scan_header.dimension_1; dim_y=scan_header.dimension_2;
141 } else if(main_header.file_type==ATTN_DATA) {
142 ret=ecat63ReadAttnheader(fp, mlist.matdir[m].strtblk, &attn_header, IMG_TEST-10, NULL);
143 dim_x=attn_header.dimension_1; dim_y=attn_header.dimension_2;
144 } else if(main_header.file_type==NORM_DATA) {
145 ret=ecat63ReadNormheader(fp, mlist.matdir[m].strtblk, &norm_header, IMG_TEST-10, NULL);
146 dim_x=norm_header.dimension_1; dim_y=norm_header.dimension_2;
147 }
148 if(ret) {
149 sprintf(ecat63errmsg, "cannot read matrix %u subheader",
150 mlist.matdir[m].matnum);
151 ecat63EmptyMatlist(&mlist); fclose(fp); return(8);
152 }
153
154 /* Allocate memory for ECAT data matrix */
155 if(IMG_TEST>1) printf("allocating memory for %d blocks\n", blkNr);
156 mdata=(char*)malloc((size_t)blkNr*MatBLKSIZE); if(mdata==NULL) {
157 strcpy(ecat63errmsg, "out of memory");
158 fclose(fp); ecat63EmptyMatlist(&mlist); return(8);
159 }
160 /* Allocate memory for whole img data */
161 ret=imgAllocate(img, planeNr, dim_y, dim_x, frameNr);
162 if(ret) {
163 sprintf(ecat63errmsg, "out of memory (%d)", ret);
164 fclose(fp); ecat63EmptyMatlist(&mlist); free(mdata); return(9);
165 }
166
167 /* Fill img info with ECAT main and sub header information */
168 img->scanner=main_header.system_type;
169 img->unit=main_header.calibration_units; /* this continues below */
170 strlcpy(img->radiopharmaceutical, main_header.radiopharmaceutical, 32);
171 img->isotopeHalflife=main_header.isotope_halflife;
172 img->scanStart=ecat63Scanstarttime(&main_header);
173 if(img->scanStart==-1) {
174 img->scanStart=0;
175 if(IMG_TEST>0) printf("invalid scan_start_time in mainheader\n");
176 }
177 img->axialFOV=10.*main_header.axial_fov;
178 img->transaxialFOV=10.*main_header.transaxial_fov;
179 strlcpy(img->studyNr, main_header.study_name, MAX_STUDYNR_LEN+1);
180 strlcpy(img->patientName, main_header.patient_name, 32);
181 strlcpy(img->patientID, main_header.patient_id, 16);
182 img->sizez=10.*main_header.plane_separation;
183 if(main_header.file_type==IMAGE_DATA) {
184 img->type=IMG_TYPE_IMAGE;
185 if(img->unit<1) img->unit=image_header.quant_units;
186 img->zoom=image_header.recon_scale;
187 if(image_header.decay_corr_fctr>1.0) img->decayCorrection=IMG_DC_CORRECTED;
189 img->sizex=img->sizey=10.*image_header.pixel_size;
190 if(img->sizez<10.*image_header.slice_width)
191 img->sizez=10.*image_header.slice_width;
192 img->xform[0]=NIFTI_XFORM_UNKNOWN; // qform
193 img->xform[1]=NIFTI_XFORM_SCANNER_ANAT; // sform
194 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
195 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
196 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
197 } else if(main_header.file_type==RAW_DATA) {
198 img->type=IMG_TYPE_RAW;
200 } else if(main_header.file_type==ATTN_DATA) {
201 img->type=IMG_TYPE_ATTN;
203 } else if(main_header.file_type==NORM_DATA) {
204 img->type=IMG_TYPE_RAW;
206 }
207 strlcpy(img->studyDescription, main_header.study_description, 32);
208 strncpy(img->userProcessCode, main_header.user_process_code, 10);
209 img->userProcessCode[10]=(char)0;
210 /* If valid study number is found in user_process_code, then take it */
213
214 /* Set _fileFormat */
215 img->_fileFormat=IMG_E63;
216
217 /* Read one ECAT matrix at a time and put them to img */
218 prev_plane=plane=-1; seqplane=-1;
219 for(int m=0; m<mlist.matrixNr; m++) if(mlist.matdir[m].matstat==1) {
220 /* get plane */
221 mat_numdoc(mlist.matdir[m].matnum, &matval);
222 plane=matval.plane;
223 /* did plane change? */
224 if(plane!=prev_plane) {seqplane++; frame=1;} else frame++;
225 prev_plane=plane;
226 img->planeNumber[seqplane]=plane;
227 /* Read subheader */
228 if(main_header.file_type==IMAGE_DATA) {
229 ret=ecat63ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header, IMG_TEST-10, NULL);
230 if(ret==0 && (dim_x!=image_header.dimension_1 || dim_y!=image_header.dimension_2)) ret=1;
231 scale=image_header.quant_scale;
232 if(image_header.ecat_calibration_fctr>0.0 &&
233 fabs(main_header.calibration_factor/image_header.ecat_calibration_fctr - 1.0)>0.0001)
234 scale*=image_header.ecat_calibration_fctr;
235 if(img->unit==0 && image_header.quant_units>0)
236 img->unit=image_header.quant_units;
237 img->_dataType=image_header.data_type;
238 img->start[frame-1]=image_header.frame_start_time/1000.;
239 img->end[frame-1]=img->start[frame-1]+image_header.frame_duration/1000.;
240 img->mid[frame-1]=0.5*(img->start[frame-1]+img->end[frame-1]);
241 if(image_header.decay_corr_fctr>1.0)
242 img->decayCorrFactor[frame-1]=image_header.decay_corr_fctr;
243 else
244 img->decayCorrFactor[frame-1]=0.0;
245 /* Dead-time correction is assumed to be included in scale factor */
246 } else if(main_header.file_type==RAW_DATA) {
247 ret=ecat63ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header, IMG_TEST-10, NULL);
248 if(ret==0 && (dim_x!=scan_header.dimension_1 || dim_y!=scan_header.dimension_2)) ret=1;
249 scale=scan_header.scale_factor;
250 /* Dead-time correction is done here */
251 if(scan_header.loss_correction_fctr>0.0)
252 scale*=scan_header.loss_correction_fctr;
253 img->_dataType=scan_header.data_type;
254 img->start[frame-1]=scan_header.frame_start_time/1000.;
255 img->end[frame-1]=img->start[frame-1]+scan_header.frame_duration/1000.;
256 img->mid[frame-1]=0.5*(img->start[frame-1]+img->end[frame-1]);
257 img->sampleDistance=10.0*scan_header.sample_distance;
258 img->prompts[frame-1]=(float)scan_header.prompts;
259 img->randoms[frame-1]=(float)scan_header.delayed;
260 } else if(main_header.file_type==ATTN_DATA) {
261 ret=ecat63ReadAttnheader(fp, mlist.matdir[m].strtblk, &attn_header, IMG_TEST-10, NULL);
262 if(ret==0 && (dim_x!=attn_header.dimension_1 || dim_y!=attn_header.dimension_2)) ret=1;
263 img->_dataType=attn_header.data_type;
264 scale=attn_header.scale_factor;
265 img->sampleDistance=10.0*attn_header.sample_distance;
266 } else if(main_header.file_type==NORM_DATA) {
267 ret=ecat63ReadNormheader(fp, mlist.matdir[m].strtblk, &norm_header, IMG_TEST-10, NULL);
268 if(ret==0 && (dim_x!=norm_header.dimension_1 || dim_y!=norm_header.dimension_2)) ret=1;
269 scale=norm_header.scale_factor;
270 img->_dataType=norm_header.data_type;
271 } else img->_dataType=-1;
272 if(ret) {
273 sprintf(ecat63errmsg, "cannot read matrix %u subheader", mlist.matdir[m].matnum);
274 ecat63EmptyMatlist(&mlist); free(mdata); fclose(fp); return(10);
275 }
276 if(main_header.calibration_factor>0.0) scale*=main_header.calibration_factor;
277 if(IMG_TEST>2) printf("scale=%e datatype=%d\n", scale, img->_dataType);
278 /* Read the pixel data */
279 ret=ecat63ReadMatdata(fp, mlist.matdir[m].strtblk+1,
280 mlist.matdir[m].endblk-mlist.matdir[m].strtblk,
281 mdata, img->_dataType);
282 if(ret) {
283 strcpy(ecat63errmsg, "cannot read matrix data");
284 ecat63EmptyMatlist(&mlist); free(mdata); fclose(fp); return(11);
285 }
286 mptr=mdata;
287 if(img->_dataType==BYTE_TYPE) {
288 for(int i=0; i<dim_y; i++) for(int j=0; j<dim_x; j++, mptr++) {
289 img->m[seqplane][i][j][frame-1]=scale*(float)(*mptr);
290 }
291 } else if(img->_dataType==VAX_I2 || img->_dataType==SUN_I2) {
292 for(int i=0; i<dim_y; i++) for(int j=0; j<dim_x; j++, mptr+=2) {
293 sptr=(short int*)mptr;
294 img->m[seqplane][i][j][frame-1]=scale*(float)(*sptr);
295 }
296 } else if(img->_dataType==VAX_I4 || img->_dataType==SUN_I4) {
297 for(int i=0; i<dim_y; i++) for(int j=0; j<dim_x; j++, mptr+=4) {
298 /*iptr=(int*)mptr;*/
299 img->m[seqplane][i][j][frame-1]=1.0; /*scale*(float)(*iptr);*/
300 }
301 } else if(img->_dataType==VAX_R4 || img->_dataType==IEEE_R4) {
302 for(int i=0; i<dim_y; i++) for(int j=0; j<dim_x; j++, mptr+=4) {
303 memcpy(&img->m[seqplane][i][j][frame-1], mptr, 4);
304 img->m[seqplane][i][j][frame-1]*=scale;
305 }
306 }
307 } /* next matrix */
308
309 /* Set the unit */
310 imgUnitFromEcat(img, img->unit);
311
312 /* Free memory and close file */
313 free(mdata);
314 ecat63EmptyMatlist(&mlist);
315 fclose(fp);
316
317 /* For saving, only 2-byte VAX data types are allowed */
318 if(img->_dataType==VAX_I4 || img->_dataType==VAX_R4) img->_dataType=VAX_I2;
319
320 return(0);
321}
int ecat63DeleteLateFrames(MATRIXLIST *ml, int frame_nr)
Definition ecat63ml.c:342
void ecat63PrintMatlist(MATRIXLIST *ml)
Definition ecat63ml.c:130
int ecat63ReadNormheader(FILE *fp, int blk, ECAT63_normheader *h, int verbose, char *errmsg)
Definition ecat63r.c:483
int ecat63ReadScanheader(FILE *fp, int blk, ECAT63_scanheader *h, int verbose, char *errmsg)
Definition ecat63r.c:377
int ecat63ReadMatdata(FILE *fp, int strtblk, int blkNr, char *data, int dtype)
Definition ecat63r.c:568
int ecat63ReadAttnheader(FILE *fp, int blk, ECAT63_attnheader *h, int verbose, char *errmsg)
Definition ecat63r.c:296
int ecat63ReadImageheader(FILE *fp, int blk, ECAT63_imageheader *h, int verbose, char *errmsg)
Definition ecat63r.c:187
time_t ecat63Scanstarttime(const ECAT63_mainheader *h)
Get calendar time from ECAT 6.3 main header.
Definition ecat63w.c:925
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition img.c:194
void imgSetStatus(IMG *img, int status_index)
Definition img.c:345
void imgUnitFromEcat(IMG *img, int ecat_unit)
Definition imgunits.c:95
#define IMG_TYPE_ATTN
#define NIFTI_XFORM_UNKNOWN
#define ATTN_DATA
#define IMG_DC_UNKNOWN
#define IMG_STATUS_INITIALIZED
#define IMG_E63
#define IMG_DC_NONCORRECTED
#define NORM_DATA
#define NIFTI_XFORM_SCANNER_ANAT
#define MAX_STUDYNR_LEN
Definition libtpcmisc.h:163
int studynr_validity_check(char *studynr)
Definition studynr.c:196
short int xform[2]
char unit
int _fileFormat
float sizey
float quatern[18]
float * mid

Referenced by imgRead().

◆ ecat63ReadAttnheader()

int ecat63ReadAttnheader ( FILE * fp,
int blk,
ECAT63_attnheader * h,
int verbose,
char * errmsg )
extern

Read ECAT 6.3 attenuation header

Returns
0 if ok, 1 failed to find block, 3 failed to read block, 4 invalid data type, 5 invalid scale factor.
Parameters
fpFile pointer to ECAT file; position is not important.
blkBlock number from matrix list [2..number of blocks].
hPointer to the header struct where contents are put.
verboseVerbose level; if zero, then only warnings are printed into stderr.
errmsgPointer to error message, at least 128 characters; enter NULL, if not needed.

Definition at line 296 of file ecat63r.c.

307 {
308 unsigned char buf[MatBLKSIZE];
309 int little; /* 1 if current platform is little endian (i386), else 0 */
310 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
311
312 if(ECAT63_TEST) printf("ecat63ReadAttnheader(fp, %d, ah)\n", blk);
313 if(fp==NULL || blk<2 || h==NULL) {
314 if(errmsg!=NULL) strcpy(errmsg, "invalid input");
315 if(verbose>0) fprintf(stderr, "Invalid input.\n");
316 return(1);
317 }
318 little=little_endian();
319 /* Seek the subheader block */
320 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
321 if(ftello(fp)!=(blk-1)*MatBLKSIZE) {
322 if(errmsg!=NULL) sprintf(errmsg, "failed to find block %d", blk);
323 if(verbose>0) fprintf(stderr, "Failed to find block %d.\n", blk);
324 return(2);
325 }
326 /* Read the subheader block */
327 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
328 if(errmsg!=NULL) sprintf(errmsg, "failed to read block %d", blk);
329 if(verbose>0) fprintf(stderr, "Failed to read block %d.\n", blk);
330 return(3);
331 }
332
333 /* Copy short ints */
334 /* in big endian platform, change byte order temporarily */
335 if(!little) swabip(buf, MatBLKSIZE);
336 memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
337 /*printf("data_type=%d\n", h->data_type);*/
338 memcpy(&h->attenuation_type, buf+128, 2);
339 memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
340 /* Change back the byte order */
341 if(!little) swabip(buf, MatBLKSIZE);
342
343 /* Copy floats */
344 h->scale_factor=ecat63rFloat(buf+182, vaxdata, little);
345 h->x_origin=ecat63rFloat(buf+186, vaxdata, little);
346 h->y_origin=ecat63rFloat(buf+190, vaxdata, little);
347 h->x_radius=ecat63rFloat(buf+194, vaxdata, little);
348 h->y_radius=ecat63rFloat(buf+198, vaxdata, little);
349 h->tilt_angle=ecat63rFloat(buf+202, vaxdata, little);
350 h->attenuation_coeff=ecat63rFloat(buf+206, vaxdata, little);
351 h->sample_distance=ecat63rFloat(buf+210, vaxdata, little);
352
353 /* Check that most important contents are ok */
354 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
355 if(errmsg!=NULL) strcpy(errmsg, "invalid data types; probable conversion error");
356 if(verbose>0) fprintf(stderr, "Invalid data types; probable conversion error.\n");
357 if(verbose>1) printf("data_type := %d\n", h->data_type);
358 return(4);
359 }
360 if(h->scale_factor<=0.0 || h->scale_factor>1.0e8) {
361 if(errmsg!=NULL) strcpy(errmsg, "invalid scale factor; probable conversion error");
362 if(verbose>0) fprintf(stderr, "Invalid scale factor; probable conversion error.\n");
363 return(5);
364 }
365 if(errmsg!=NULL) strcpy(errmsg, "ok");
366
367 return(0);
368}
float ecat63rFloat(void *bufi, int isvax, int islittle)
Definition ecat63r.c:928

Referenced by ecat63ReadAllToImg(), ecat63ReadAttnMatrix(), ecat63ReadPlaneToImg(), ecat6PrintSubheader(), imgReadEcat63Frame(), and imgReadEcat63Header().

◆ ecat63ReadAttnMatrix()

int ecat63ReadAttnMatrix ( FILE * fp,
int first_block,
int last_block,
ECAT63_attnheader * h,
float ** fdata )
extern

Read ECAT63 attenuation matrix header and data.

If only header is to be read, set last_block=first_block. Note: data is not calibrated with factor in main header.

Returns
0 if ok, 1 invalid input, 5 failed to read sub header, 6 invalid (x,y,z) dimensions, 8 failed to allocate memory for meta-data, 9 failed to read matrix data, 11 failed to allocate memory for the data
Parameters
fpECAT file pointer.
first_blockSubheader record number.
last_blockLast data block number.
hPointer to subheader data which is filled.
fdataFloat pointer to the address of the matrix data; any old contents are not freed, therefore you must free the pointer after data is copied elsewhere.

Definition at line 830 of file ecat63r.c.

843 {
844 int ret, blockNr;
845 char *mdata, *mptr, errmsg[128];
846 float *_fdata, *fptr;
847 short int *sptr;
848 int *iptr;
849
850
851 if(ECAT63_TEST) printf("ecat63ReadAttnMatrix(fp, %d, %d, hdr, fdata)\n",
852 first_block, last_block);
853 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
854 sprintf(ecat63errmsg, "invalid function parameter.\n");
855 return(1);
856 }
857 *fdata=(float*)NULL;
858
859 /* Read subheader */
860 ret=ecat63ReadAttnheader(fp, first_block, h, ECAT63_TEST-2, errmsg);
861 if(ret) {
862 strcpy(ecat63errmsg, errmsg);
863 return(5);
864 }
865 if(ECAT63_TEST>4) ecat63PrintAttnheader(h, stdout);
866 long long pxlNr=h->dimension_1*h->dimension_2;
867 if(pxlNr<=0) {
868 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
869 return(6);
870 }
871
872 /* Read matrix data */
873 blockNr=last_block-first_block; if(blockNr<1) return(0);
874 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
875 if(mdata==NULL) {
876 sprintf(ecat63errmsg, "cannot allocate memory.\n");
877 return(8);
878 }
879 mptr=mdata;
880 ret=ecat63ReadMatdata(fp, first_block+1, blockNr, mptr, h->data_type);
881 if(ret || mdata==NULL) {
882 sprintf(ecat63errmsg, "cannot read matrix data (%d).\n", ret);
883 free(mdata); return(9);
884 }
885
886 /* Allocate memory for float data */
887 _fdata=(float*)malloc((size_t)pxlNr*sizeof(float));
888 if(_fdata==NULL) {
889 sprintf(ecat63errmsg, "cannot allocate memory.\n");
890 free(mdata); return(11);
891 }
892
893 /* Convert matrix data to floats */
894 fptr=_fdata; mptr=mdata;
895 if(h->data_type==BYTE_TYPE) {
896 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
897 *fptr=h->scale_factor*(float)(*mptr);
898 } else if(h->data_type==VAX_I2 || h->data_type==SUN_I2) {
899 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
900 sptr=(short int*)mptr;
901 *fptr=h->scale_factor*(float)(*sptr);
902 }
903 } else if(h->data_type==VAX_I4 || h->data_type==SUN_I4) {
904 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
905 iptr=(int*)mptr;
906 *fptr=h->scale_factor*(float)(*iptr);
907 }
908 } else if(h->data_type==VAX_R4 || h->data_type==IEEE_R4) {
909 memcpy(fptr, mptr, pxlNr*4);
910 for(long long i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
911 }
912 free(mdata);
913 *fdata=_fdata;
914
915 return(0);
916}
void ecat63PrintAttnheader(ECAT63_attnheader *h, FILE *fp)
Definition ecat63p.c:173

◆ ecat63ReadImageheader()

int ecat63ReadImageheader ( FILE * fp,
int blk,
ECAT63_imageheader * h,
int verbose,
char * errmsg )
extern

Read ECAT 6.3 image header.

Returns
0 if ok, 1 invalid input, 2 failed to find block, 3 failed to read block, 4 invalid data type, 5 invalid calibration factor, 6 invalid frame duration.
Parameters
fpFile pointer to ECAT file; position is not important.
blkBlock number from matrix list [2..number of blocks].
hPointer to the header struct where contents are put.
verboseVerbose level; if zero, then only warnings are printed into stderr.
errmsgPointer to error message, at least 128 characters; enter NULL, if not needed.

Definition at line 187 of file ecat63r.c.

198 {
199 unsigned char buf[MatBLKSIZE];
200 int little; /* 1 if current platform is little endian (i386), else 0 */
201 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
202
203 if(verbose>0) {printf("ecat63ReadImageheader(fp, %d ih)\n", blk); fflush(stdout);}
204 if(fp==NULL || blk<2 || h==NULL) {
205 if(errmsg!=NULL) strcpy(errmsg, "invalid input");
206 if(verbose>0) {fprintf(stderr, "Invalid input.\n"); fflush(stderr);}
207 return(1);
208 }
209 little=little_endian();
210 /* Seek the subheader block */
211 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
212 if(ftello(fp)!=(blk-1)*MatBLKSIZE) {
213 if(errmsg!=NULL) sprintf(errmsg, "failed to find block %d", blk);
214 if(verbose>0) {fprintf(stderr, "Failed to find block %d.\n", blk); fflush(stderr);}
215 return(2);
216 }
217 /* Read the subheader block */
218 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
219 if(errmsg!=NULL) sprintf(errmsg, "failed to read block %d", blk);
220 if(verbose>0) {fprintf(stderr, "Failed to read block %d.\n", blk); fflush(stderr);}
221 return(3);
222 }
223
224 /* Copy char data to header structure */
225 memcpy(h->fill1, buf+0, 126); memcpy(h->annotation, buf+420, 40);
226
227 /* Copy short ints */
228 /* in big endian platform, change byte order temporarily */
229 if(!little) swabip(buf, MatBLKSIZE);
230 memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
231 if(verbose>10) printf("data_type=%d\n", h->data_type);
232 memcpy(&h->num_dimensions, buf+128, 2);
233 memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
234 memcpy(&h->image_min, buf+176, 2); memcpy(&h->image_max, buf+178, 2);
235 memcpy(&h->slice_location, buf+200, 2); memcpy(&h->recon_start_hour, buf+202, 2);
236 memcpy(&h->recon_start_min, buf+204, 2); memcpy(&h->recon_start_sec, buf+206, 2);
237 memcpy(&h->filter_code, buf+236, 2); memcpy(&h->processing_code, buf+376, 2);
238 memcpy(&h->quant_units, buf+380, 2); memcpy(&h->recon_start_day, buf+382, 2);
239 memcpy(&h->recon_start_month, buf+384, 2); memcpy(&h->recon_start_year, buf+386, 2);
240 memcpy(h->fill2, buf+460, 52);
241 /* Change back the byte order */
242 if(!little) swabip(buf, MatBLKSIZE);
243
244 /* Copy ints */
245 h->frame_duration=ecat63rInt(buf+192, vaxdata, little);
246 h->frame_start_time=ecat63rInt(buf+196, vaxdata, little);
247 h->recon_duration=ecat63rInt(buf+208, vaxdata, little);
248 h->scan_matrix_num=ecat63rInt(buf+238, vaxdata, little);
249 h->norm_matrix_num=ecat63rInt(buf+242, vaxdata, little);
250 h->atten_cor_mat_num=ecat63rInt(buf+246, vaxdata, little);
251
252 /* Copy floats */
253 h->x_origin=ecat63rFloat(buf+160, vaxdata, little);
254 h->y_origin=ecat63rFloat(buf+164, vaxdata, little);
255 h->recon_scale=ecat63rFloat(buf+168, vaxdata, little);
256 h->quant_scale=ecat63rFloat(buf+172, vaxdata, little);
257 h->pixel_size=ecat63rFloat(buf+184, vaxdata, little);
258 h->slice_width=ecat63rFloat(buf+188, vaxdata, little);
259 h->image_rotation=ecat63rFloat(buf+296, vaxdata, little);
260 h->plane_eff_corr_fctr=ecat63rFloat(buf+300, vaxdata, little);
261 h->decay_corr_fctr=ecat63rFloat(buf+304, vaxdata, little);
262 h->loss_corr_fctr=ecat63rFloat(buf+308, vaxdata, little);
263 h->intrinsic_tilt=ecat63rFloat(buf+312, vaxdata, little);
264 h->ecat_calibration_fctr=ecat63rFloat(buf+388, vaxdata, little);
265 h->well_counter_cal_fctr=ecat63rFloat(buf+392, vaxdata, little);
266 for(int i=0; i<6; i++) h->filter_params[i]=ecat63rFloat(buf+396+i*4, vaxdata, little);
267
268 /* Check that most important contents are ok */
269 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
270 if(errmsg!=NULL) strcpy(errmsg, "invalid data types; probable conversion error");
271 if(verbose>0) {fprintf(stderr, "Invalid data types; probable conversion error.\n"); fflush(stderr);}
272 if(verbose>1) {printf("data_type := %d\n", h->data_type); fflush(stdout);}
273 return(4);
274 }
275 if(h->ecat_calibration_fctr<0.0 || h->ecat_calibration_fctr>1.0e10) {
276 if(errmsg!=NULL) strcpy(errmsg, "invalid calibration factor; probable conversion error");
277 if(verbose>0) {fprintf(stderr, "Invalid calibration factor; probable conversion error.\n"); fflush(stderr);}
278 return(5);
279 }
280 if(h->frame_duration<0.0 || h->frame_duration>1.0e12) {
281 if(errmsg!=NULL) strcpy(errmsg, "invalid frame duration; probable conversion error");
282 if(verbose>0) {fprintf(stderr, "Invalid frame duration; probable conversion error.\n"); fflush(stderr);}
283 return(6);
284 }
285 if(errmsg!=NULL) strcpy(errmsg, "ok");
286
287 return(0);
288}
int ecat63rInt(void *bufi, int isvax, int islittle)
Definition ecat63r.c:953
short int fill2[26]
short int slice_location
short int processing_code

Referenced by ecat63ReadAllToImg(), ecat63ReadImageMatrix(), ecat63ReadPlaneToImg(), ecat6PrintSubheader(), imgReadEcat63Frame(), and imgReadEcat63Header().

◆ ecat63ReadImageMatrix()

int ecat63ReadImageMatrix ( FILE * fp,
int first_block,
int last_block,
ECAT63_imageheader * h,
float ** fdata )
extern

Read ECAT63 image matrix header and data.

If only header is to be read, set last_block=first_block. Note: data is not calibrated with factor in main header.

Returns
0 if ok, 1 invalid input, 5 failed to read sub header, 6 invalid (x,y,z) dimensions, 8 failed to allocate memory for meta-data, 9 failed to read matrix data, 11 failed to allocate memory for image data
Parameters
fpECAT file pointer
first_blockSubheader record number
last_blockLast data block number
hPtr to subheader data which is filled
fdataPtr to the address of the matrix data; any old contents are not freed, therefore you must free the pointer after data is copied elsewhere.

Definition at line 627 of file ecat63r.c.

639 {
640 int ret, blockNr;
641 char *mdata, *mptr, errmsg[128];
642 float *_fdata, *fptr;
643 short int *sptr;
644 int *iptr;
645
646
647 if(ECAT63_TEST) printf("ecat63ReadImageMatrix(fp, %d, %d, hdr, fdata)\n",
648 first_block, last_block);
649 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
650 sprintf(ecat63errmsg, "invalid function parameter.\n");
651 return(1);
652 }
653 *fdata=(float*)NULL;
654
655 /* Read subheader */
656 ret=ecat63ReadImageheader(fp, first_block, h, ECAT63_TEST-2, errmsg);
657 if(ret) {
658 strcpy(ecat63errmsg, errmsg);
659 return(5);
660 }
661 if(ECAT63_TEST>4) ecat63PrintImageheader(h, stdout);
662 long long pxlNr=h->dimension_1*h->dimension_2;
663 if(pxlNr<=0) {
664 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
665 return(6);
666 }
667
668 /* Read matrix data */
669 blockNr=last_block-first_block; if(blockNr<1) return(0);
670 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
671 if(mdata==NULL) {
672 sprintf(ecat63errmsg, "cannot allocate memory.\n");
673 return(8);
674 }
675 mptr=mdata;
676 ret=ecat63ReadMatdata(fp, first_block+1, blockNr, mptr, h->data_type);
677 if(ret || mdata==NULL) {
678 sprintf(ecat63errmsg, "cannot read matrix data (%d).\n", ret);
679 free(mdata); return(9);
680 }
681
682 /* Allocate memory for float data */
683 _fdata=(float*)malloc((size_t)pxlNr*sizeof(float));
684 if(_fdata==NULL) {
685 sprintf(ecat63errmsg, "cannot allocate memory.\n");
686 free(mdata); return(11);
687 }
688
689 /* Convert matrix data to floats */
691 fptr=_fdata; mptr=mdata;
692 if(h->data_type==BYTE_TYPE) {
693 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
694 *fptr=h->quant_scale*(float)(*mptr);
695 } else if(h->data_type==VAX_I2 || h->data_type==SUN_I2) {
696 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
697 sptr=(short int*)mptr;
698 *fptr=h->quant_scale*(float)(*sptr);
699 if(!(*fptr>-1.0E+22 && *fptr<1.0E+22)) *fptr=0.0;
700 }
701 } else if(h->data_type==VAX_I4 || h->data_type==SUN_I4) {
702 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
703 iptr=(int*)mptr;
704 *fptr=h->quant_scale*(float)(*iptr);
705 if(!(*fptr>-1.0E+22 && *fptr<1.0E+22)) *fptr=0.0;
706 }
707 } else if(h->data_type==VAX_R4 || h->data_type==IEEE_R4) {
708 memcpy(fptr, mptr, pxlNr*4);
709 for(long long i=0; i<pxlNr; i++, fptr++) {
710 *fptr *= h->quant_scale;
711 if(!(*fptr>-1.0E+22 && *fptr<1.0E+22)) *fptr=0.0;
712 }
713 }
714 free(mdata);
715 *fdata=_fdata;
716
717 return(0);
718}
void ecat63PrintImageheader(ECAT63_imageheader *h, FILE *fp)
Definition ecat63p.c:94

◆ ecat63ReadMainheader()

int ecat63ReadMainheader ( FILE * fp,
ECAT63_mainheader * h )
extern

Read ECAT 6.3 main header.

Returns
0 if ok, 1 invalid input, 2 failed to find subheader block, 3 invalid magic number (should be "ECAT63") at start of file, 5 invalid data type, 6 invalid calibration factor, 7 invalid file type.
Parameters
fpfile pointer
htarget Ecat 6.3 main header structure

Definition at line 25 of file ecat63r.c.

30 {
31 unsigned char buf[MatBLKSIZE];
32 int little; /* 1 if current platform is little endian (i386), else 0 */
33 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
34
35 if(ECAT63_TEST>0) {printf("ecat63ReadMainheader()\n"); fflush(stdout);}
36 if(fp==NULL || h==NULL) return(1);
37 little=little_endian(); if(ECAT63_TEST>1) {printf("little := %d\n", little); fflush(stdout);}
38 /* Seek the first block */
39 fseek(fp, 0, SEEK_SET); if(ftell(fp)!=0) return(1);
40 /* Read the main header block */
41 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(2);
42
43 /* Copy char data to header structure */
44 memcpy(h->ecat_format, buf+0, 14);
45 memcpy(h->fill1, buf+14, 14);
46 memcpy(h->original_file_name, buf+28, 20);
47 if(ECAT63_TEST>10) {
48 printf("original_file_name := '%.20s'\n", h->original_file_name); fflush(stdout);}
49 memcpy(h->node_id, buf+56, 10);
50 memcpy(h->isotope_code, buf+78, 8);
51 memcpy(h->radiopharmaceutical, buf+90, 32);
52 memcpy(h->study_name, buf+162, 12);
53 memcpy(h->patient_id, buf+174, 16);
54 memcpy(h->patient_name, buf+190, 32);
55 h->patient_sex=buf[222];
56 memcpy(h->patient_age, buf+223, 10);
57 memcpy(h->patient_height, buf+233, 10);
58 memcpy(h->patient_weight, buf+243, 10);
59 h->patient_dexterity=buf[253];
60 memcpy(h->physician_name, buf+254, 32);
61 memcpy(h->operator_name, buf+286, 32);
62 memcpy(h->study_description, buf+318, 32);
63 memcpy(h->facility_name, buf+356, 20);
64 memcpy(h->user_process_code, buf+462, 10);
65
66 /* Copy short ints; in big endian platform, change byte order */
67 if(!little) swabip(buf+50, 2);
68 memcpy(&h->data_type, buf+50, 2);
69 if(ECAT63_TEST>10) {printf("main_header.data_type=%d\n", h->data_type); fflush(stdout);}
70 if(h->data_type<1) {
71 if(ECAT63_TEST>1) {printf("invalid data_type; assuming VAX_I2\n"); fflush(stdout);}
73 }
74 if(h->data_type>4) vaxdata=0;
75
76 if(!little) swabip(buf+48, 2);
77 memcpy(&h->sw_version, buf+48, 2);
78 if(!little) swabip(buf+52, 2);
79 memcpy(&h->system_type, buf+52, 2);
80 if(!little) swabip(buf+54, 2);
81 memcpy(&h->file_type, buf+54, 2);
82 if(ECAT63_TEST>10) {printf("main_header.file_type=%d\n", h->file_type); fflush(stdout);}
83 if(!little) swabip(buf+66, 2);
84 memcpy(&h->scan_start_day, buf+66, 2);
85 if(!little) swabip(buf+68, 2);
86 memcpy(&h->scan_start_month, buf+68, 2);
87 if(!little) swabip(buf+70, 2);
88 memcpy(&h->scan_start_year, buf+70, 2);
89 if(!little) swabip(buf+72, 2);
90 memcpy(&h->scan_start_hour, buf+72, 2);
91 if(!little) swabip(buf+74, 2);
92 memcpy(&h->scan_start_minute, buf+74, 2);
93 if(!little) swabip(buf+76, 2);
94 memcpy(&h->scan_start_second, buf+76, 2);
95 if(!little) swabip(buf+134, 2);
96 memcpy(&h->rot_source_speed, buf+134, 2);
97 if(!little) swabip(buf+136, 2);
98 memcpy(&h->wobble_speed, buf+136, 2);
99 if(!little) swabip(buf+138, 2);
100 memcpy(&h->transm_source_type, buf+138, 2);
101 if(!little) swabip(buf+148, 2);
102 memcpy(&h->transaxial_samp_mode, buf+148, 2);
103 if(!little) swabip(buf+150, 2);
104 memcpy(&h->coin_samp_mode, buf+150, 2);
105 if(!little) swabip(buf+152, 2);
106 memcpy(&h->axial_samp_mode, buf+152, 2);
107 if(!little) swabip(buf+158, 2);
108 memcpy(&h->calibration_units, buf+158, 2);
109 if(!little) swabip(buf+160, 2);
110 memcpy(&h->compression_code, buf+160, 2);
111 if(!little) swabip(buf+350, 2);
112 memcpy(&h->acquisition_type, buf+350, 2);
113 if(!little) swabip(buf+352, 2);
114 memcpy(&h->bed_type, buf+352, 2);
115 if(!little) swabip(buf+354, 2);
116 memcpy(&h->septa_type, buf+354, 2);
117 if(!little) swabip(buf+376, 2);
118 memcpy(&h->num_planes, buf+376, 2);
119 if(!little) swabip(buf+378, 2);
120 memcpy(&h->num_frames, buf+378, 2);
121 if(!little) swabip(buf+380, 2);
122 memcpy(&h->num_gates, buf+380, 2);
123 if(!little) swabip(buf+382, 2);
124 memcpy(&h->num_bed_pos, buf+382, 2);
125 if(!little) swabip(buf+452, 2);
126 memcpy(&h->lwr_sctr_thres, buf+452, 2);
127 if(!little) swabip(buf+454, 2);
128 memcpy(&h->lwr_true_thres, buf+454, 2);
129 if(!little) swabip(buf+456, 2);
130 memcpy(&h->upr_true_thres, buf+456, 2);
131 if(!little) swabip(buf+472, 40);
132 memcpy(h->fill2, buf+472, 40);
133
134 /* Copy floats */
135 h->isotope_halflife=ecat63rFloat(buf+86, vaxdata, little);
136 h->gantry_tilt=ecat63rFloat(buf+122, vaxdata, little);
137 h->gantry_rotation=ecat63rFloat(buf+126, vaxdata, little);
138 h->bed_elevation=ecat63rFloat(buf+130, vaxdata, little);
139 h->axial_fov=ecat63rFloat(buf+140, vaxdata, little);
140 h->transaxial_fov=ecat63rFloat(buf+144, vaxdata, little);
141 h->calibration_factor=ecat63rFloat(buf+154, vaxdata, little);
142 h->init_bed_position=ecat63rFloat(buf+384, vaxdata, little);
143 for(int i=0; i<15; i++) h->bed_offset[i]=ecat63rFloat(buf+388+i*4, vaxdata, little);
144 h->plane_separation=ecat63rFloat(buf+448, vaxdata, little);
145 h->collimator=ecat63rFloat(buf+458, vaxdata, little);
146
147 /* Check file format and platform */
148 if(ECAT63_TEST>1) {printf("ecat_format='%.14s'\n", h->ecat_format); fflush(stdout);}
149 /* if format is not specified, ECAT63 is assumed */
150 if(h->ecat_format[0]==(char)0) {
151 strcpy(h->ecat_format, "ECAT63");
152 }
153 /* only ECAT63 format is approved here */
154 if(ECAT63_TEST>1) {printf("ecat_format='%.14s'\n", h->ecat_format); fflush(stdout);}
155 if(strncmp(h->ecat_format, "ECAT63", 6)!=0) return(3);
156
157 /* Check that most important contents are ok */
158 if(ECAT63_TEST>3) {
159 printf(" mhdr.data_type := %s\n", ecat63Datatype(h->data_type));
160 fflush(stdout);
161 }
162 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
163 if(ECAT63_TEST>1) {printf("Invalid data types; probable conversion error.\n"); fflush(stdout);}
164 return(5);
165 }
166 if(h->calibration_factor<0.0 || h->calibration_factor>1.0e12) {
167 if(ECAT63_TEST>1) {
168 printf("Invalid calibration factor; possible conversion error.\n"); fflush(stdout);}
169 return(6);
170 }
171 if(h->file_type!=RAW_DATA && h->file_type!=IMAGE_DATA &&
173 if(ECAT63_TEST>1) {printf("Invalid file types; probable conversion error.\n"); fflush(stdout);}
174 return(7);
175 }
176
177 return(0);
178}

Referenced by atnMake(), ecat63AddImg(), ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), ecatFixMatrixlist(), imgRead(), imgReadEcat63Frame(), imgReadEcat63Header(), and imgWriteEcat63Frame().

◆ ecat63ReadMatdata()

int ecat63ReadMatdata ( FILE * fp,
int strtblk,
int blkNr,
char * data,
int dtype )
extern

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

Parameters
fpfile pointer from where data is read
strtblkstarting block [>= 1]
blkNrnumber of block to be read [>= 0]
datapointer to block where data is read
dtypedata type code
Returns
0 if ok, 1 invalid input, 2 failed to read data, 9 failed to find starting block from file,

Definition at line 568 of file ecat63r.c.

568 {
569 int n, little, err=0;
570 char *cptr;
571 float f;
572
573
574 if(ECAT63_TEST) printf("ecat63ReadMatdata(fp, %d, %d, data, %d)\n", strtblk, blkNr, dtype);
575 /* Check the arguments */
576 if(blkNr<=0 || strtblk<1 || data==NULL) return(1);
577 /* Seek the first data block */
578 fseeko(fp, (strtblk-1)*MatBLKSIZE, SEEK_SET);
579 if(ftello(fp)!=(strtblk-1)*MatBLKSIZE) return(9);
580 /* Read the data blocks */
581 if(fread(data, MatBLKSIZE, blkNr, fp) < (unsigned int)blkNr) return(2);
582 /* Translate data if necessary */
583 little=little_endian();
584 switch(dtype) {
585 case BYTE_TYPE: /* byte format...no translation necessary */
586 break;
587 case VAX_I2: /* byte conversion necessary on big endian platform */
588 if(!little) {cptr=data; swabip(cptr, blkNr*MatBLKSIZE);}
589 break;
590 case VAX_I4:
591 cptr=data;
592 for(long long int i=0; i<blkNr*MatBLKSIZE; i+=4, cptr+=4) {
593 n=ecat63rInt(cptr, 1, little); memcpy(cptr, &n, 4);
594 }
595 break;
596 case VAX_R4:
597 cptr=data;
598 for(long long i=0; i<blkNr*MatBLKSIZE; i+=4, cptr+=4) {
599 f=ecat63rFloat(cptr, 1, little); memcpy(cptr, &f, 4);
600 }
601 break;
602 case IEEE_R4: /* IEEE float ; byte conversion necessary on big end platforms */
603 case SUN_I4: /* SUN int ; byte conversion necessary on big end platforms */
604 if(!little) swawbip(data, blkNr*MatBLKSIZE);
605 break;
606 case SUN_I2: /* SUN short ; byte conversion necessary on big end platforms */
607 if(!little) swabip(data, blkNr*MatBLKSIZE);
608 break;
609 default: /* if something else, for now think it as an error */
610 err=2;
611 break;
612 }
613 return(err);
614}

Referenced by ecat63ReadAllToImg(), ecat63ReadAttnMatrix(), ecat63ReadImageMatrix(), ecat63ReadPlaneToImg(), ecat63ReadScanMatrix(), and imgReadEcat63Frame().

◆ ecat63ReadMatlist()

int ecat63ReadMatlist ( FILE * fp,
MATRIXLIST * ml,
int verbose )
extern

Read ECAT 6.3 matrix list.

Matrix list must be initiated (once) before calling this.

Returns
Returns 0 if ok, 1 if invalid input, 2 first matrix is not found, 3 if failed to read matrix, 4 failed to allocate memory, 5 other error.
Parameters
fpFile pointer.
mlPointer to initiated matrix list.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 46 of file ecat63ml.c.

53 {
54 int i, err=0, little;
55 int blk=MatFirstDirBlk, next_blk=0;
56 size_t sn;
57 unsigned int dirbuf[MatBLKSIZE/4];
58
59
60 if(verbose>0) {printf("ecat63ReadMatlist(fp, mlist)\n"); fflush(stdout);}
61 if(fp==NULL) return(1);
62 little=little_endian();
63 /* Make sure that matrix list is empty */
65 /* Seek the first list block */
66 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
67 do {
68 /* Read the data block */
69 if(verbose>1) {printf(" reading dirblock %d\n", blk); fflush(stdout);}
70 sn=fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp);
71 if(sn==0) { /* this never happens in valid ECAT file, but it does happen... */
72 if(verbose>0) {printf("sn=%d\n", (int)sn); fflush(stdout);}
73 //ml->matrixNr--;
74 break;
75 }
76 if(sn<MatBLKSIZE/4) { /* this would be a real error in file */
77 if(verbose>0) {printf("sn=%d\n", (int)sn); fflush(stdout);}
78 err=2; break;
79 }
80 /* Allocate (more) memory for one block */
81 if(ml->matrixSpace==0) {
83 ml->matdir=(MatDir*)malloc(ml->matrixSpace*sizeof(MatDir));
84 } else if(ml->matrixSpace<(ml->matrixNr+MatBLKSIZE/4)) {
86 ml->matdir=(MatDir*)realloc(ml->matdir, sizeof(MatDir)*ml->matrixSpace);
87 }
88 if(ml->matdir==NULL) return(4);
89 /* Byte order conversion for ints in big endian platforms */
90 if(!little) swawbip(dirbuf, MatBLKSIZE);
91 /* Read "header" integers */
92 /*nr_free = dirbuf[0];*/
93 next_blk = dirbuf[1];
94 /*prev_blk = dirbuf[2];*/
95 /*nr_used = dirbuf[3];*/
96 if(verbose>3) printf("next_blk=%d\n", next_blk);
97 fpos_t current_fp; fgetpos(fp, &current_fp); // save current file position
98 for(i=4; i<MatBLKSIZE/4; i+=4) if(dirbuf[i]>0) {
99 ml->matdir[ml->matrixNr].matnum=dirbuf[i];
100 ml->matdir[ml->matrixNr].strtblk=dirbuf[i+1];
101 ml->matdir[ml->matrixNr].endblk=dirbuf[i+2];
102 ml->matdir[ml->matrixNr].matstat=dirbuf[i+3];
103 if(verbose>4) printf("matnum=%d strtblk=%d endblk=%d matstat=%d matrixNr=%d\n",
104 ml->matdir[ml->matrixNr].matnum, ml->matdir[ml->matrixNr].strtblk,
105 ml->matdir[ml->matrixNr].endblk, ml->matdir[ml->matrixNr].matstat,
106 ml->matrixNr);
107 /* verify that these block can be found in the file */
108 int ret=fseek(fp, (ml->matdir[ml->matrixNr].endblk-1)*MatBLKSIZE, SEEK_SET);
109 fsetpos(fp, &current_fp); // back to saved file position
110 if(ret==0) { // end block can be found
111 ml->matrixNr++;
112 } else { // not found, file probably broken
113 if(verbose>0) {
114 printf("matnum %d points to data outside of file.\n", ml->matdir[ml->matrixNr].matnum);
115 fflush(stdout);
116 }
117 }
118 }
119 blk=next_blk;
120 /* Seek the next list block */
121 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftello(fp)!=(blk-1)*MatBLKSIZE) err=1;
122 } while(err==0 && feof(fp)==0 && blk!=MatFirstDirBlk);
123 if(err) {ecat63EmptyMatlist(ml); return(5);}
124 return(0);
125}

Referenced by atnMake(), ecat63AddImg(), ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), ecat6PrintSubheader(), ecatFixMatrixlist(), imgReadEcat63Frame(), and imgReadEcat63Header().

◆ ecat63ReadNormheader()

int ecat63ReadNormheader ( FILE * fp,
int blk,
ECAT63_normheader * h,
int verbose,
char * errmsg )
extern

Read ECAT 6.3 normalization header.

Note that ECAT 6.3 normalization data is usually stored in scan file format, not in normalization format.

Returns
0 if ok, 1 invalid input, 2 failed to find block, 3 failed to read block, 4 invalid data type, 5 invalid scale factor.
Parameters
fpFile pointer to ECAT file; position is not important.
blkBlock number from matrix list [2..number of blocks].
hPointer to the header struct where contents are put.
verboseVerbose level; if zero, then only warnings are printed into stderr.
errmsgPointer to error message, at least 128 characters; enter NULL, if not needed.

Definition at line 483 of file ecat63r.c.

494 {
495 unsigned char buf[MatBLKSIZE];
496 int little; /* 1 if current platform is little endian (i386), else 0 */
497 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
498
499 if(ECAT63_TEST) printf("ecat63ReadNormheader(fp, %d, nh)\n", blk);
500 if(fp==NULL || blk<2 || h==NULL) {
501 if(errmsg!=NULL) strcpy(errmsg, "invalid input");
502 if(verbose>0) fprintf(stderr, "Invalid input.\n");
503 return(1);
504 }
505 little=little_endian();
506 /* Seek the subheader block */
507 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
508 if(ftello(fp)!=(blk-1)*MatBLKSIZE) {
509 if(errmsg!=NULL) sprintf(errmsg, "failed to find block %d", blk);
510 if(verbose>0) fprintf(stderr, "Failed to find block %d.\n", blk);
511 return(2);
512 }
513 /* Read the subheader block */
514 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
515 if(errmsg!=NULL) sprintf(errmsg, "failed to read block %d", blk);
516 if(verbose>0) fprintf(stderr, "Failed to read block %d.\n", blk);
517 return(3);
518 }
519
520 /* Copy short ints */
521 /* in big endian platform, change byte order temporarily */
522 if(!little) swabip(buf, MatBLKSIZE);
523 memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
524 if(verbose>10) printf("data_type=%d\n", h->data_type);
525 memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
526 memcpy(&h->norm_hour, buf+186, 2); memcpy(&h->norm_minute, buf+188, 2);
527 memcpy(&h->norm_second, buf+190, 2); memcpy(&h->norm_day, buf+192, 2);
528 memcpy(&h->norm_month, buf+194, 2); memcpy(&h->norm_year, buf+196, 2);
529 /* Change back the byte order */
530 if(!little) swabip(buf, MatBLKSIZE);
531
532 /* Copy floats */
533 h->scale_factor=ecat63rFloat(buf+182, vaxdata, little);
534 h->fov_source_width=ecat63rFloat(buf+198, vaxdata, little);
535
536 /* Check that most important contents are ok */
537 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
538 if(errmsg!=NULL) strcpy(errmsg, "invalid data types; probable conversion error");
539 if(verbose>0) fprintf(stderr, "Invalid data types; probable conversion error.\n");
540 if(verbose>1) printf("data_type := %d\n", h->data_type);
541 return(4);
542 }
543 if(h->scale_factor<=0.0 || h->scale_factor>1.0e8) {
544 if(errmsg!=NULL) strcpy(errmsg, "invalid scale factor; probable conversion error");
545 if(verbose>0) fprintf(stderr, "Invalid scale factor; probable conversion error.\n");
546 return(5);
547 }
548 if(errmsg!=NULL) strcpy(errmsg, "ok");
549
550 return(0);
551}

Referenced by ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), ecat6PrintSubheader(), imgReadEcat63Frame(), and imgReadEcat63Header().

◆ ecat63ReadPlaneToImg()

int ecat63ReadPlaneToImg ( const char * fname,
IMG * img )
extern

Reads one CTI ECAT 6.3 plane (all frames or gates) at a time to memory. Img data must be initialized before this procedure. Existing img->_dataType is not changed. If img data structure is empty, reads the first plane. If img data structure contains data, reads the next plane. Any existing data in img is cleared and replaced by the new plane.

Parameters
fnamename of the input ECAT 6.3 file
imgdata structure in which the file is read
Returns
0 if ok, 1 next plane was requested but not found any more, 2 invalid input data, 3 failed to open file, 4 failed to read main header, 5 failed to read matrix list, 6 invalid matrix data, 7 failed to read matrix sub header, 8 failed to allocate memory, 9 failed to read matrix data

Definition at line 550 of file img_e63.c.

550 {
551 int m, ret, blkNr=0, dim_x=0, dim_y=0, del_nr=0;
552 int frameNr, planeNr, datatype=0, firstm=0, isFirst=0;
553 int frame, plane, prev_frame, prev_plane, prev_frameNr=0;
554 FILE *fp;
555 ECAT63_mainheader main_header;
556 MATRIXLIST mlist;
557 MatDir tmpMatdir;
558 Matval matval;
559 ECAT63_imageheader image_header;
560 ECAT63_scanheader scan_header;
561 ECAT63_attnheader attn_header;
562 ECAT63_normheader norm_header;
563 float scale=1.0;
564 short int *sptr;
565 char *mdata=NULL, *mptr;
566 int *iptr;
567
568
569 if(IMG_TEST) printf("ecat63ReadPlaneToImg(%s, *img)\n", fname);
570 /* Check the arguments */
571 if(fname==NULL) {strcpy(ecat63errmsg, "invalid ECAT filename"); return(2);}
572 if(img==NULL || img->status==IMG_STATUS_UNINITIALIZED) {
573 strcpy(ecat63errmsg, "image data not initialized"); return(2);}
574
575 /* Open input CTI file for read */
576 if((fp=fopen(fname, "rb")) == NULL) {
577 strcpy(ecat63errmsg, "cannot open ECAT file"); return(3);}
578
579 /* Read main header */
580 if((ret=ecat63ReadMainheader(fp, &main_header))) {
581 sprintf(ecat63errmsg, "cannot read main header (%d)", ret);
582 fclose(fp); return(4);
583 }
584 if(IMG_TEST) ecat63PrintMainheader(&main_header, stdout);
585
586 /* Read matrix list and nr */
587 ecat63InitMatlist(&mlist);
588 ret=ecat63ReadMatlist(fp, &mlist, IMG_TEST);
589 if(ret) {
590 sprintf(ecat63errmsg, "cannot read matrix list (%d)", ret);
591 fclose(fp); return(5);
592 }
593 if(mlist.matrixNr<=0) {
594 strcpy(ecat63errmsg, "matrix list is empty"); fclose(fp); return(5);}
595 /* Sort matrix list */
596 for(int i=0; i<mlist.matrixNr-1; i++) for(int j=i+1; j<mlist.matrixNr; j++) {
597 if(mlist.matdir[i].matnum>mlist.matdir[j].matnum) {
598 tmpMatdir=mlist.matdir[i];
599 mlist.matdir[i]=mlist.matdir[j]; mlist.matdir[j]=tmpMatdir;
600 }
601 }
602 /* Trim extra frames */
603 if(main_header.num_frames>0) {
604 del_nr=ecat63DeleteLateFrames(&mlist, main_header.num_frames);
605 if(IMG_TEST && del_nr>0)
606 printf(" %d entries in matrix list will not be used.\n", del_nr);
607 }
608
609 /* Decide the plane to read */
610 if(img->status==IMG_STATUS_OCCUPIED) {
611 /* img contains data */
612 isFirst=0; prev_frameNr=img->dimt;
613 /* get the current plane in there */
614 prev_plane=img->planeNumber[img->dimz-1];
615 /* Clear all data in img: not here but only after finding new data */
616 } else {
617 /* img does not contain any data */
618 isFirst=1;
619 /* set "current plane" to -1 */
620 prev_plane=-1;
621 }
622 /* from sorted matrix list, find first plane larger than the current one */
623 plane=-1;
624 for(int m=0; m<mlist.matrixNr; m++) if(mlist.matdir[m].matstat==1) {
625 mat_numdoc(mlist.matdir[m].matnum, &matval);
626 if(matval.plane>prev_plane) {plane=matval.plane; break;}
627 }
628 /* If not found, return an error or 1 if this was not the first one */
629 if(plane<0) {
630 fclose(fp); ecat63EmptyMatlist(&mlist);
631 if(isFirst) {
632 sprintf(ecat63errmsg, "ECAT file contains no matrices");
633 return(7);
634 } else {
635 sprintf(ecat63errmsg, "ECAT file contains no more planes");
636 if(IMG_TEST) printf("%s\n", ecat63errmsg);
637 return(1);
638 }
639 }
640 if(IMG_TEST) printf("Next plane to read: %d\n", plane);
641 /* Clear all data in img */
642 imgEmpty(img);
643
644 /* Calculate the number of frames and gates */
645 prev_frame=frame=-1; frameNr=0; ret=0; planeNr=1;
646 for(int m=0; m<mlist.matrixNr; m++) if(mlist.matdir[m].matstat==1) {
647 /* get frame and plane; work only with current plane */
648 mat_numdoc(mlist.matdir[m].matnum, &matval);
649 if(matval.plane<plane) continue; else if(matval.plane>plane) break;
650 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
651 else frame=matval.gate;
652 frameNr++;
653 /* frame (gate) numbers must be continuous */
654 if(prev_frame>0 && frame!=prev_frame+1) {ret=1; break;}
655 prev_frame=frame;
656 /* Calculate and check the size of one data matrix */
657 if(frameNr==1) {
658 firstm=m;
659 blkNr=mlist.matdir[m].endblk-mlist.matdir[m].strtblk;
660 } else if(blkNr!=mlist.matdir[m].endblk-mlist.matdir[m].strtblk) {
661 ret=2; break;
662 }
663 prev_frame=frame;
664 } /* next matrix */
665 if(ret==1) {
666 strcpy(ecat63errmsg, "missing matrix");
667 ecat63EmptyMatlist(&mlist); fclose(fp); return(6);
668 }
669 if(ret==2) {
670 strcpy(ecat63errmsg, "matrix sizes are different");
671 ecat63EmptyMatlist(&mlist); fclose(fp); return(6);
672 }
673 /* Check that frameNr is equal to the dimt in IMG */
674 if(!isFirst && frameNr!=prev_frameNr) {
675 strcpy(ecat63errmsg, "different frame nr in different planes");
676 ecat63EmptyMatlist(&mlist); fclose(fp); return(6);
677 }
678
679 /* Read x,y-dimensions from 1st matrix subheader on current plane */
680 m=firstm; if(main_header.file_type==IMAGE_DATA) {
681 ret=ecat63ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header, IMG_TEST-10, NULL);
682 dim_x=image_header.dimension_1; dim_y=image_header.dimension_2;
683 } else if(main_header.file_type==RAW_DATA) {
684 ret=ecat63ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header, IMG_TEST-10, NULL);
685 dim_x=scan_header.dimension_1; dim_y=scan_header.dimension_2;
686 } else if(main_header.file_type==ATTN_DATA) {
687 ret=ecat63ReadAttnheader(fp, mlist.matdir[m].strtblk, &attn_header, IMG_TEST-10, NULL);
688 dim_x=attn_header.dimension_1; dim_y=attn_header.dimension_2;
689 } else if(main_header.file_type==NORM_DATA) {
690 ret=ecat63ReadNormheader(fp, mlist.matdir[m].strtblk, &norm_header, IMG_TEST-10, NULL);
691 dim_x=norm_header.dimension_1; dim_y=norm_header.dimension_2;
692 }
693 if(ret) {
694 sprintf(ecat63errmsg, "cannot read matrix %u subheader",
695 mlist.matdir[m].matnum);
696 ecat63EmptyMatlist(&mlist); fclose(fp); return(7);
697 }
698
699 /* Allocate memory for ECAT data matrix */
700 if(IMG_TEST) printf("allocating memory for %d blocks\n", blkNr);
701 mdata=(char*)malloc((size_t)blkNr*MatBLKSIZE); if(mdata==NULL) {
702 strcpy(ecat63errmsg, "out of memory");
703 fclose(fp); ecat63EmptyMatlist(&mlist); return(8);
704 }
705 /* Allocate memory for whole img data */
706 ret=imgAllocate(img, planeNr, dim_y, dim_x, frameNr);
707 if(ret) {
708 sprintf(ecat63errmsg, "out of memory (%d)", ret);
709 fclose(fp); ecat63EmptyMatlist(&mlist); free(mdata); return(8);
710 }
711
712 /* Fill img info with ECAT main and sub header information */
713 img->scanner=main_header.system_type;
714 img->unit=main_header.calibration_units; /* this continues below */
715 strlcpy(img->radiopharmaceutical, main_header.radiopharmaceutical, 32);
716 img->isotopeHalflife=main_header.isotope_halflife;
717 img->scanStart=ecat63Scanstarttime(&main_header);
718 if(img->scanStart==-1) {
719 img->scanStart=0;
720 if(IMG_TEST>0) printf("invalid scan_start_time in mainheader\n");
721 }
722 img->axialFOV=10.*main_header.axial_fov;
723 img->transaxialFOV=10.*main_header.transaxial_fov;
724 strlcpy(img->studyNr, main_header.study_name, MAX_STUDYNR_LEN);
725 strlcpy(img->patientName, main_header.patient_name, 32);
726 strlcpy(img->patientID, main_header.patient_id, 16);
727 img->sizez=10.*main_header.plane_separation;
728 if(main_header.file_type==IMAGE_DATA) {
729 img->type=IMG_TYPE_IMAGE;
730 if(img->unit<1) img->unit=image_header.quant_units;
731 img->zoom=image_header.recon_scale;
732 if(image_header.decay_corr_fctr>1.0) img->decayCorrection=IMG_DC_CORRECTED;
734 img->sizex=img->sizey=10.*image_header.pixel_size;
735 if(img->sizez<10.*image_header.slice_width)
736 img->sizez=10.*image_header.slice_width;
737 img->xform[0]=NIFTI_XFORM_UNKNOWN; // qform
738 img->xform[1]=NIFTI_XFORM_SCANNER_ANAT; // sform
739 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
740 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
741 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
742 } else if(main_header.file_type==RAW_DATA) {
743 img->type=IMG_TYPE_RAW;
745 } else if(main_header.file_type==ATTN_DATA) {
746 img->type=IMG_TYPE_ATTN;
748 } else if(main_header.file_type==NORM_DATA) {
749 img->type=IMG_TYPE_RAW;
751 }
752 img->planeNumber[0]=plane;
753 strlcpy(img->studyDescription, main_header.study_description, 32);
754 strlcpy(img->userProcessCode, main_header.user_process_code, 10);
755 //img->userProcessCode[10]=(char)0;
756 /* If valid study number is found in user_process_code, then take it */
759 /* Set _fileFormat */
760 img->_fileFormat=IMG_E63;
761
762 /* Read one ECAT matrix at a time and put them to img */
763 for(m=firstm, frame=1; m<mlist.matrixNr; m++) if(mlist.matdir[m].matstat==1) {
764 /* get plane */
765 mat_numdoc(mlist.matdir[m].matnum, &matval);
766 if(matval.plane>plane) break; /* Quit when current plane is read */
767 /* Read subheader */
768 if(main_header.file_type==IMAGE_DATA) {
769 ret=ecat63ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header, IMG_TEST-10, NULL);
770 if(ret==0 && (dim_x!=image_header.dimension_1 || dim_y!=image_header.dimension_2)) ret=1;
771 scale=image_header.quant_scale;
772 if(image_header.ecat_calibration_fctr>0.0 &&
773 fabs(main_header.calibration_factor/image_header.ecat_calibration_fctr - 1.0)>0.0001)
774 scale*=image_header.ecat_calibration_fctr;
775 if(img->unit==0 && image_header.quant_units>0)
776 img->unit=image_header.quant_units;
777 datatype=image_header.data_type;
778 img->start[frame-1]=image_header.frame_start_time/1000.;
779 img->end[frame-1]=img->start[frame-1]+image_header.frame_duration/1000.;
780 img->mid[frame-1]=0.5*(img->start[frame-1]+img->end[frame-1]);
781 if(image_header.decay_corr_fctr>1.0)
782 img->decayCorrFactor[frame-1]=image_header.decay_corr_fctr;
783 else
784 img->decayCorrFactor[frame-1]=0.0;
785 } else if(main_header.file_type==RAW_DATA) {
786 ret=ecat63ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header, IMG_TEST-10, NULL);
787 if(ret==0 && (dim_x!=scan_header.dimension_1 ||dim_y!=scan_header.dimension_2)) ret=1;
788 scale=scan_header.scale_factor;
789 if(scan_header.loss_correction_fctr>0.0) // dead-time correction
790 scale*=scan_header.loss_correction_fctr;
791 datatype=scan_header.data_type;
792 img->start[frame-1]=scan_header.frame_start_time/1000.;
793 img->end[frame-1]=img->start[frame-1]+scan_header.frame_duration/1000.;
794 img->mid[frame-1]=0.5*(img->start[frame-1]+img->end[frame-1]);
795 img->sampleDistance=10.0*scan_header.sample_distance;
796 img->prompts[frame-1]=(float)scan_header.prompts;
797 img->randoms[frame-1]=(float)scan_header.delayed;
798 } else if(main_header.file_type==ATTN_DATA) {
799 ret=ecat63ReadAttnheader(fp, mlist.matdir[m].strtblk, &attn_header, IMG_TEST-10, NULL);
800 if(ret==0 && (dim_x!=attn_header.dimension_1 ||dim_y!=attn_header.dimension_2)) ret=1;
801 img->sampleDistance=10.0*attn_header.sample_distance;
802 scale=attn_header.scale_factor;
803 datatype=attn_header.data_type;
804 } else if(main_header.file_type==NORM_DATA) {
805 ret=ecat63ReadNormheader(fp, mlist.matdir[m].strtblk, &norm_header, IMG_TEST-10, NULL);
806 if(ret==0 && (dim_x!=norm_header.dimension_1 ||dim_y!=norm_header.dimension_2)) ret=1;
807 scale=norm_header.scale_factor;
808 datatype=norm_header.data_type;
809 } else datatype=-1;
810 if(ret) {
811 sprintf(ecat63errmsg, "cannot read matrix %u subheader",
812 mlist.matdir[m].matnum);
813 ecat63EmptyMatlist(&mlist); free(mdata); fclose(fp); return(7);
814 }
815 if(main_header.calibration_factor>0.0)
816 scale*=main_header.calibration_factor;
817 if(IMG_TEST>2) printf("scale=%e datatype=%d\n", scale, datatype);
818 /* Read the pixel data */
819 ret=ecat63ReadMatdata(fp, mlist.matdir[m].strtblk+1,
820 mlist.matdir[m].endblk-mlist.matdir[m].strtblk,
821 mdata, datatype);
822 if(ret) {
823 strcpy(ecat63errmsg, "cannot read matrix data");
824 ecat63EmptyMatlist(&mlist); free(mdata); fclose(fp); return(9);
825 }
826 mptr=mdata;
827 if(datatype==BYTE_TYPE) {
828 for(int i=0; i<dim_y; i++) for(int j=0; j<dim_x; j++, mptr++) {
829 img->m[0][i][j][frame-1]=scale*(float)(*mptr);
830 }
831 } else if(datatype==VAX_I2 || datatype==SUN_I2) {
832 for(int i=0; i<dim_y; i++) for(int j=0; j<dim_x; j++, mptr+=2) {
833 sptr=(short int*)mptr;
834 img->m[0][i][j][frame-1]=scale*(float)(*sptr);
835 }
836 } else if(datatype==VAX_I4 || datatype==SUN_I4) {
837 for(int i=0; i<dim_y; i++) for(int j=0; j<dim_x; j++, mptr+=4) {
838 iptr=(int*)mptr;
839 img->m[0][i][j][frame-1]=scale*(float)(*iptr);
840 }
841 } else if(datatype==VAX_R4 || datatype==IEEE_R4) {
842 for(int i=0; i<dim_y; i++) for(int j=0; j<dim_x; j++, mptr+=4) {
843 memcpy(&img->m[0][i][j][frame-1], mptr, 4);
844 img->m[0][i][j][frame-1]*=scale;
845 }
846 }
847 frame++;
848 } /* next matrix (frame) */
849 /* Set the unit */
850 imgUnitFromEcat(img, img->unit);
851
852 /* Free memory and close file */
853 free(mdata);
854 ecat63EmptyMatlist(&mlist);
855 fclose(fp);
856
857 /* Set _dataType if it has not been set before */
858 if(img->_dataType<1) img->_dataType=datatype;
859 /* For saving, only 2-byte VAX data types are allowed */
860 if(img->_dataType==VAX_I4 || img->_dataType==VAX_R4) img->_dataType=VAX_I2;
861
862 return(0);
863}
void imgEmpty(IMG *image)
Definition img.c:121
#define IMG_STATUS_UNINITIALIZED

◆ ecat63ReadScanheader()

int ecat63ReadScanheader ( FILE * fp,
int blk,
ECAT63_scanheader * h,
int verbose,
char * errmsg )
extern

Read ECAT 6.3 scan header.

Returns
0 if ok, 1 invalid input, 2 failed to find block, 3 failed to read block, 4 invalid data type, 5 invalid scale factor, 6 invalid frame duration.
Parameters
fpFile pointer to ECAT file; position is not important.
blkBlock number from matrix list [2..number of blocks].
hPointer to the header struct where contents are put.
verboseVerbose level; if zero, then only warnings are printed into stderr.
errmsgPointer to error message, at least 128 characters; enter NULL, if not needed.

Definition at line 377 of file ecat63r.c.

388 {
389 unsigned char buf[MatBLKSIZE];
390 int little; /* 1 if current platform is little endian (i386), else 0 */
391 int vaxdata=1; /* 1 if data is in VAX format, else 0 */
392
393 if(ECAT63_TEST) printf("ecat63ReadScanheader(fp, %d, sh)\n", blk);
394 if(fp==NULL || blk<2 || h==NULL) {
395 if(errmsg!=NULL) strcpy(errmsg, "invalid input");
396 if(verbose>0) fprintf(stderr, "Invalid input.\n");
397 return(1);
398 }
399 little=little_endian();
400 /* Seek the subheader block */
401 fseeko(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
402 if(ftello(fp)!=(blk-1)*MatBLKSIZE) {
403 if(errmsg!=NULL) sprintf(errmsg, "failed to find block %d", blk);
404 if(verbose>0) fprintf(stderr, "Failed to find block %d.\n", blk);
405 return(2);
406 }
407 /* Read the subheader block */
408 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
409 if(errmsg!=NULL) sprintf(errmsg, "failed to read block %d", blk);
410 if(verbose>0) fprintf(stderr, "Failed to read block %d.\n", blk);
411 return(3);
412 }
413
414 /* Copy char data to header structure */
415 memcpy(h->fill1, buf+0, 126);
416
417 /* Copy short ints */
418 /* in big endian platform, change byte order temporarily */
419 if(!little) swabip(buf, MatBLKSIZE);
420 memcpy(&h->data_type, buf+126, 2); if(h->data_type>4) vaxdata=0;
421 /*printf("data_type=%d\n", h->data_type);*/
422 memcpy(&h->dimension_1, buf+132, 2); memcpy(&h->dimension_2, buf+134, 2);
423 memcpy(&h->smoothing, buf+136, 2); memcpy(&h->processing_code, buf+138, 2);
424 memcpy(&h->frame_duration_sec, buf+170, 2);
425 memcpy(&h->scan_min, buf+192, 2); memcpy(&h->scan_max, buf+194, 2);
426 memcpy(h->fill2, buf+468, 44);
427 /* Change back the byte order */
428 if(!little) swabip(buf, MatBLKSIZE);
429
430 /* Copy ints */
431 h->gate_duration=ecat63rInt(buf+172, vaxdata, little);
432 h->r_wave_offset=ecat63rInt(buf+176, vaxdata, little);
433 h->prompts=ecat63rInt(buf+196, vaxdata, little);
434 h->delayed=ecat63rInt(buf+200, vaxdata, little);
435 h->multiples=ecat63rInt(buf+204, vaxdata, little);
436 h->net_trues=ecat63rInt(buf+208, vaxdata, little);
437 h->total_coin_rate=ecat63rInt(buf+452, vaxdata, little);
438 h->frame_start_time=ecat63rInt(buf+456, vaxdata, little);
439 h->frame_duration=ecat63rInt(buf+460, vaxdata, little);
440
441 /* Copy floats */
442 h->sample_distance=ecat63rFloat(buf+146, vaxdata, little);
443 h->isotope_halflife=ecat63rFloat(buf+166, vaxdata, little);
444 h->scale_factor=ecat63rFloat(buf+182, vaxdata, little);
445 for(int i=0; i<16; i++) h->cor_singles[i]=ecat63rFloat(buf+316+i*4, vaxdata, little);
446 for(int i=0; i<16; i++) h->uncor_singles[i]=ecat63rFloat(buf+380+i*4, vaxdata, little);
447 h->tot_avg_cor=ecat63rFloat(buf+444, vaxdata, little);
448 h->tot_avg_uncor=ecat63rFloat(buf+448, vaxdata, little);
449 h->loss_correction_fctr=ecat63rFloat(buf+464, vaxdata, little);
450
451 /* Check that most important contents are ok */
452 if(h->data_type<BYTE_TYPE || h->data_type>SUN_I4) {
453 if(errmsg!=NULL) strcpy(errmsg, "invalid data types; probable conversion error");
454 if(verbose>0) fprintf(stderr, "Invalid data types; probable conversion error.\n");
455 if(verbose>1) printf("data_type := %d\n", h->data_type);
456 return(4);
457 }
458 if(h->scale_factor<=0.0 || h->scale_factor>1.0e8) {
459 if(errmsg!=NULL) strcpy(errmsg, "invalid calibration factor; probable conversion error");
460 if(verbose>0) fprintf(stderr, "Invalid calibration factor; probable conversion error.\n");
461 return(5);
462 }
463 if(h->frame_duration<0.0 || h->frame_duration>1.0e12) {
464 if(errmsg!=NULL) strcpy(errmsg, "invalid frame duration; probable conversion error");
465 if(verbose>0) fprintf(stderr, "Invalid frame duration; probable conversion error.\n");
466 return(6);
467 }
468 if(errmsg!=NULL) strcpy(errmsg, "ok");
469
470 return(0);
471}

Referenced by ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), ecat63ReadScanMatrix(), ecat6PrintSubheader(), imgReadEcat63Frame(), and imgReadEcat63Header().

◆ ecat63ReadScanMatrix()

int ecat63ReadScanMatrix ( FILE * fp,
int first_block,
int last_block,
ECAT63_scanheader * h,
float ** fdata )
extern

Read ECAT63 scan matrix header and data.

If only header is to be read, set last_block=first_block. Note: data is not calibrated with factor in main header.

Returns
0 if ok, 1 invalid input, 5 failed to read sub header, 6 invalid (x,y,z) dimensions, 8 failed to allocate memory for meta-data, 9 failed to read matrix data, 11 failed to allocate memory for the data
Parameters
fpECAT file pointer.
first_blockSubheader record number.
last_blockLast data block number.
hPointer to subheader data which is filled.
fdataDouble pointer to the address of the matrix data; any old contents are not freed, therefore you must free the pointer after data is copied elsewhere.

Definition at line 731 of file ecat63r.c.

744 {
745 int ret, blockNr;
746 char *mdata, *mptr, errmsg[128];
747 float *_fdata, *fptr;
748 short int *sptr;
749 int *iptr;
750
751
752 if(ECAT63_TEST) printf("ecat63ReadScanMatrix(fp, %d, %d, hdr, fdata)\n",
753 first_block, last_block);
754 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
755 sprintf(ecat63errmsg, "invalid function parameter.\n");
756 return(1);
757 }
758 *fdata=(float*)NULL;
759
760 /* Read subheader */
761 ret=ecat63ReadScanheader(fp, first_block, h, ECAT63_TEST-2, errmsg);
762 if(ret) {
763 strcpy(ecat63errmsg, errmsg);
764 return(5);
765 }
766 if(ECAT63_TEST>4) ecat63PrintScanheader(h, stdout);
767 long long pxlNr=h->dimension_1*h->dimension_2;
768 if(pxlNr<=0) {
769 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
770 return(6);
771 }
772
773 /* Read matrix data */
774 blockNr=last_block-first_block; if(blockNr<1) return(0);
775 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
776 if(mdata==NULL) {
777 sprintf(ecat63errmsg, "cannot allocate memory.\n");
778 return(8);
779 }
780 mptr=mdata;
781 ret=ecat63ReadMatdata(fp, first_block+1, blockNr, mptr, h->data_type);
782 if(ret || mdata==NULL) {
783 sprintf(ecat63errmsg, "cannot read matrix data (%d).\n", ret);
784 free(mdata); return(9);
785 }
786
787 /* Allocate memory for float data */
788 _fdata=(float*)malloc((size_t)pxlNr*sizeof(float));
789 if(_fdata==NULL) {
790 sprintf(ecat63errmsg, "cannot allocate memory.\n");
791 free(mdata); return(11);
792 }
793
794 /* Convert matrix data to floats */
795 fptr=_fdata; mptr=mdata;
796 if(h->data_type==BYTE_TYPE) {
797 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
798 *fptr=h->scale_factor*(float)(*mptr);
799 } else if(h->data_type==VAX_I2 || h->data_type==SUN_I2) {
800 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
801 sptr=(short int*)mptr;
802 *fptr=h->scale_factor*(float)(*sptr);
803 }
804 } else if(h->data_type==VAX_I4 || h->data_type==SUN_I4) {
805 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
806 iptr=(int*)mptr;
807 *fptr=h->scale_factor*(float)(*iptr);
808 }
809 } else if(h->data_type==VAX_R4 || h->data_type==IEEE_R4) {
810 memcpy(fptr, mptr, pxlNr*4);
811 for(long long i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
812 }
813 free(mdata);
814 *fdata=_fdata;
815
816 return(0);
817}
void ecat63PrintScanheader(ECAT63_scanheader *h, FILE *fp)
Definition ecat63p.c:137

Referenced by atnMake().

◆ ecat63rFloat()

float ecat63rFloat ( void * bufi,
int isvax,
int islittle )
extern

Reading ECAT 6.3 floats

Parameters
bufipointer to 32-bit long data block
isvax1 for VAX format
islittle1 for little endian
Returns
read float value

Definition at line 928 of file ecat63r.c.

930 {
931 union {unsigned int ul; float f;} t;
932
933 memcpy(&t.ul, bufi, 4); if(t.ul==0) {return(0.0);}
934 if(isvax) { /* if input is in VAX format */
935 /* Swap words on i386 and bytes on SUN */
936 if(islittle) swawip(&t.ul, 4); else swabip(&t.ul, 4);
937 t.ul-=(2L<<23); /* subtract 2 from exp */
938 } else { /* input is in i386 format */
939 if(!islittle) swawbip(&t.ul, 4); /* Switch words and bytes on SUN */
940 }
941 return(t.f);
942}
void swawip(void *buf, long long int size)
Definition swap.c:114

Referenced by ecat63ReadAttnheader(), ecat63ReadImageheader(), ecat63ReadMainheader(), ecat63ReadMatdata(), ecat63ReadNormheader(), and ecat63ReadScanheader().

◆ ecat63rInt()

int ecat63rInt ( void * bufi,
int isvax,
int islittle )
extern

Reading and writing ECAT 6.3 32-bit ints. 32-bit int format is same in VAX and i386

Parameters
bufipointer to 32-bit long data block
isvax1 for VAX format
islittle1 for littel endian
Returns
read data as interger number

Definition at line 953 of file ecat63r.c.

955 {
956 int i;
957
958 if(isvax==0) {} // just to prevent compiler warning
959 /* Swap both words and bytes on SUN */
960 memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4);
961 return(i);
962}

Referenced by ecat63ReadImageheader(), ecat63ReadMatdata(), and ecat63ReadScanheader().

◆ ecat63Scanstarttime()

time_t ecat63Scanstarttime ( const ECAT63_mainheader * h)
extern

Get calendar time from ECAT 6.3 main header.

Author
Vesa Oikonen
Returns
Returns time_t, or -1 in case of an error.
Parameters
hPointer to ECAT 6.3 main header

Definition at line 925 of file ecat63w.c.

928 {
929 if(h==NULL) return((time_t)-1);
930 struct tm tm;
931 tm.tm_mday=h->scan_start_day;
932 tm.tm_mon=h->scan_start_month-1;
933 tm.tm_year=h->scan_start_year-1900;
934 tm.tm_hour=h->scan_start_hour;
935 tm.tm_min=h->scan_start_minute;
936 tm.tm_sec=h->scan_start_second;
937 tm.tm_isdst=-1;
938 return(timegm(&tm));
939}
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
Definition datetime.c:69

Referenced by atnMake(), ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), ecatCopy63to7mainheader(), and imgGetEcat63MHeader().

◆ ecat63ScanstarttimeInt()

char * ecat63ScanstarttimeInt ( const ECAT63_mainheader * h,
char * buf )
extern

Convert scan_start_time in ECAT 6.3 main header into a null-terminated string of the form YYYY-MM-DD hh:mm:ss, with length of 19 characters and the null.

Author
Vesa Oikonen
Returns
Returns pointer to the string, or null in case of an error.
Parameters
hPointer to ECAT 6.3 main header.
bufPointer to string where the date and time will be written. It must be pre-allocated for at least 20 characters.

Definition at line 391 of file ecat63p.c.

397 {
398 //printf("ecat63ScanstarttimeInt()\n");
399 if(buf==NULL) return(NULL);
400 buf[0]=(char)0;
401 if(h==NULL) return(NULL);
402 if(h->scan_start_year<0 || h->scan_start_year>9999) return(NULL);
403 if(h->scan_start_month<0 || h->scan_start_month>12) return(NULL);
404 if(h->scan_start_day<0 || h->scan_start_day>31) return(NULL);
405 if(h->scan_start_hour<0 || h->scan_start_hour>24) return(NULL);
406 if(h->scan_start_minute<0 || h->scan_start_minute>59) return(NULL);
407 if(h->scan_start_second<0 || h->scan_start_second>59) return(NULL);
408 sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d",
411 return(buf);
412}

Referenced by imgGetEcat63MHeader(), and imgWriteEcat63Frame().

◆ ecat63ScanstarttimeToTm()

struct tm * ecat63ScanstarttimeToTm ( const ECAT63_mainheader * h,
struct tm * tm )
extern

Convert scan_start_time in ECAT 6.3 main header into a struct tm.

Author
Vesa Oikonen
Returns
Returns pointer to the struct_tm, or null in case of an error.
Parameters
hPointer to ECAT 6.3 main header
tmPointer to pre-allocated struct tm.

Definition at line 900 of file ecat63w.c.

905 {
906 if(tm==NULL || h==NULL) return(NULL);
907 memset(tm, 0, sizeof(struct tm));
908 tm->tm_mday=h->scan_start_day;
909 tm->tm_mon=h->scan_start_month-1;
910 tm->tm_year=h->scan_start_year-1900;
911 tm->tm_hour=h->scan_start_hour;
912 tm->tm_min=h->scan_start_minute;
913 tm->tm_sec=h->scan_start_second;
914 tm->tm_isdst=-1;
915 if(timegm(tm)==-1) return(NULL);
916 return(tm);
917}

◆ ecat63SortMatlistByFrame()

void ecat63SortMatlistByFrame ( MATRIXLIST * ml)
extern

Sort matrixlist by frame and plane. Bubble sorting algorithm.

Parameters
mlmatrix list

Definition at line 297 of file ecat63ml.c.

299 {
300 Matval mv1, mv2;
301 MatDir tmpMatdir;
302
303 for(int i=0; i<ml->matrixNr-1; i++) {
304 mat_numdoc(ml->matdir[i].matnum, &mv1);
305 for(int j=i+1; j<ml->matrixNr; j++) {
306 mat_numdoc(ml->matdir[j].matnum, &mv2);
307 if(mv2.frame<mv1.frame||(mv2.frame==mv1.frame&&mv2.plane<mv1.plane)) {
308 tmpMatdir=ml->matdir[i];
309 ml->matdir[i]=ml->matdir[j]; ml->matdir[j]=tmpMatdir;
310 mat_numdoc(ml->matdir[i].matnum, &mv1);
311 }
312 }
313 }
314}

Referenced by imgReadEcat63Frame().

◆ ecat63SortMatlistByPlane()

void ecat63SortMatlistByPlane ( MATRIXLIST * ml)
extern

Sort matrixlist by plane and frame. Bubble sorting algorithm.

Parameters
mlmarix list.

Definition at line 271 of file ecat63ml.c.

273 {
274 Matval mv1, mv2;
275 MatDir tmpMatdir;
276
277 for(int i=0; i<ml->matrixNr-1; i++) {
278 mat_numdoc(ml->matdir[i].matnum, &mv1);
279 for(int j=i+1; j<ml->matrixNr; j++) {
280 mat_numdoc(ml->matdir[j].matnum, &mv2);
281 if(mv2.plane<mv1.plane||(mv2.plane==mv1.plane&&mv2.frame<mv1.frame)) {
282 tmpMatdir=ml->matdir[i];
283 ml->matdir[i]=ml->matdir[j]; ml->matdir[j]=tmpMatdir;
284 mat_numdoc(ml->matdir[i].matnum, &mv1);
285 }
286 }
287 }
288}

Referenced by ecat63GetPlaneAndFrameNr(), and imgReadEcat63Header().

◆ ecat63Unit()

char * ecat63Unit ( short int dunit)
extern

Returns pointer to string describing the calibrated data unit (ECAT 6.3).

Parameters
dunitdata unit code
Returns
pointer to static string

Definition at line 243 of file ecat63p.c.

245 {
246 static char *ecat63_unit[]={
247 /* 0 */ "Unknown",
248 /* 1 */ "Unknown",
249 /* 2 */ "ECAT counts",
250 /* 3 */ "uCi/ml",
251 /* 4 */ "LMRGlu",
252 /* 5 */ "LMRUGlu umol/min/100g",
253 /* 6 */ "LMRUGlu mg/min/100g",
254 /* 7 */ "nCi/mL",
255 /* 8 */ "Well counts",
256 /* 9 */ "Becquerels",
257 /* 10 */ "kBq/mL",
258 /* 11 */ "1/min",
259 /* 12 */ "mL/min/100g",
260 /* 13 */ "sec*kBq/mL",
261 /* 14 */ "sec*nCi/mL",
262 /* 15 */ "1/sec",
263 /* 16 */ "Unitless",
264 /* 17 */ "Unknown"
265 };
266 if(dunit>=0 && dunit<18) return(ecat63_unit[dunit]);
267 else return(ecat63_unit[0]);
268}

Referenced by ecat63PrintImageheader(), and ecat63PrintMainheader().

◆ ecat63wFloat()

void ecat63wFloat ( float * bufi,
void * bufo,
int tovax,
int islittle )
extern

Writing ECAT 6.3 floats

Parameters
bufipointer to 4-byte long input (float data)
bufopointer to 4-byte long output
tovax1 for VAX format
islittle1 for little endian

Definition at line 860 of file ecat63w.c.

862 {
863 unsigned int ul;
864
865 memcpy(&ul, bufi, 4); if(ul==0) {memcpy(bufo, bufi, 4); return;}
866 if(tovax) { /* If VAX format is needed */
867 ul+=(2L<<23); /* increase exp by 2 */
868 /* Swap words on i386 and bytes on SUN */
869 if(islittle) swawip(&ul, 4); else swabip(&ul, 4);
870 } else {
871 if(!islittle) swawbip(&ul, 4); /* Switch words and bytes on SUN */
872 }
873 memcpy(bufo, &ul, 4);
874}

Referenced by ecat63WriteAttnheader(), ecat63WriteImageheader(), ecat63WriteMainheader(), ecat63WriteNormheader(), and ecat63WriteScanheader().

◆ ecat63wInt()

void ecat63wInt ( int * bufi,
void * bufo,
int tovax,
int islittle )
extern

Writing ECAT 6.3 32-bit ints. 32-bit int format is same in VAX and i386

Parameters
bufipointer to 4-byte long input (integer data)
bufopointer to 4-byte long output
tovax1 for VAX format
islittle1 for little endian

Definition at line 884 of file ecat63w.c.

884 {
885 int i;
886
887 if(tovax==0) {} // to prevent compiler warning
888 /* Swap both words and bytes on SUN */
889 memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4);
890 memcpy(bufo, &i, 4);
891}

Referenced by ecat63WriteImageheader(), and ecat63WriteScanheader().

◆ ecat63WriteAllImg()

int ecat63WriteAllImg ( const char * fname,
IMG * img )
extern

Write all matrices in memory to the ECAT file.

Parameters
fnamename of the output ECAT 6.3 file, If ECAT file exists, it is renamed as filename%
imgdata structure from which the data is written
Returns
0 if ok, 1 invalid data, 2 image status is not 'occupied', 3 failed to create file, 4 failed to allocate memory for data, 9 failed to write data

Definition at line 335 of file img_e63.c.

335 {
336 int frame, plane, m, ret=0;
337 float f, fmax, fmin, g, scale;
338 short int *sdata, *sptr, smin, smax;
339 FILE *fp;
340 ECAT63_mainheader main_header;
341 ECAT63_imageheader image_header;
342 ECAT63_scanheader scan_header;
343 struct tm tm;
344
345 if(IMG_TEST) printf("ecat63WriteAllImg(%s, *img)\n", fname);
346 /* Check the arguments */
347 if(fname==NULL) {strcpy(ecat63errmsg, "invalid ECAT filename"); return(1);}
348 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
349 strcpy(ecat63errmsg, "image data is empty"); return(2);}
350 if(img->_dataType<1) img->_dataType=VAX_I2;
351
352 /* Check image size */
353 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024) {
354 strcpy(ecat63errmsg, "too large matrix size"); return(1);}
355
356 /* Initiate headers */
357 memset(&main_header, 0, sizeof(ECAT63_mainheader));
358 memset(&image_header,0, sizeof(ECAT63_imageheader));
359 memset(&scan_header, 0, sizeof(ECAT63_scanheader));
360
361 /* Make a main header */
362 main_header.sw_version=2;
363 main_header.num_planes=img->dimz;
364 main_header.num_frames=img->dimt;
365 main_header.num_gates=1;
366 main_header.num_bed_pos=1;
367 if(img->type==IMG_TYPE_IMAGE) main_header.file_type=IMAGE_DATA;
368 else if(img->type==IMG_TYPE_RAW) main_header.file_type=RAW_DATA;
369 else {strcpy(ecat63errmsg, "invalid filetype"); return(1);}
370 main_header.data_type=img->_dataType;
371 if(img->scanner>0) main_header.system_type=img->scanner;
373 main_header.calibration_factor=1.0;
374 main_header.axial_fov=img->axialFOV/10.0;
375 main_header.transaxial_fov=img->transaxialFOV/10.0;
376 main_header.plane_separation=img->sizez/10.0;
377 main_header.calibration_units=imgUnitToEcat6(img);
378 strncpy(main_header.radiopharmaceutical, img->radiopharmaceutical, 32);
379 if(gmtime_r((time_t*)&img->scanStart, &tm)!=NULL) {
380 main_header.scan_start_year=tm.tm_year+1900;
381 main_header.scan_start_month=tm.tm_mon+1;
382 main_header.scan_start_day=tm.tm_mday;
383 main_header.scan_start_hour=tm.tm_hour;
384 main_header.scan_start_minute=tm.tm_min;
385 main_header.scan_start_second=tm.tm_sec;
386 if(IMG_TEST>2) {
387 printf(" img->scanStart := %ld\n", (long int)img->scanStart);
388 printf(" -> tm_year := %d\n", tm.tm_year);
389 printf(" -> tm_hour := %d\n", tm.tm_hour);
390 }
391 } else {
392 main_header.scan_start_year=1900;
393 main_header.scan_start_month=1;
394 main_header.scan_start_day=1;
395 main_header.scan_start_hour=0;
396 main_header.scan_start_minute=0;
397 main_header.scan_start_second=0;
398 if(IMG_TEST>0) printf("invalid scan_start_time in IMG\n");
399 }
400 main_header.isotope_halflife=img->isotopeHalflife;
401 strcpy(main_header.isotope_code, imgIsotope(img));
402 strlcpy(main_header.study_name, img->studyNr, 12);
403 strcpy(main_header.patient_name, img->patientName);
404 strcpy(main_header.patient_id, img->patientID);
405 strlcpy(main_header.user_process_code, img->userProcessCode, 10);
406 strncpy(main_header.study_description, img->studyDescription, 32);
407 if(IMG_TEST) ecat63PrintMainheader(&main_header, stdout);
408
409 /* Allocate memory for matrix data */
410 sdata=(short int*)malloc((size_t)img->dimx*img->dimy*sizeof(short int));
411 if(sdata==NULL) {strcpy(ecat63errmsg, "out of memory"); return(4);}
412
413 /* Open output ECAT file */
414 fp=ecat63Create(fname, &main_header);
415 if(fp==NULL) {strcpy(ecat63errmsg, "cannot write ECAT file"); return(3);}
416
417 /* Set the subheader contents, as far as possible */
418 switch(main_header.file_type) {
419 case RAW_DATA:
420 scan_header.data_type=main_header.data_type;
421 scan_header.dimension_1=img->dimx;
422 scan_header.dimension_2=img->dimy;
423 scan_header.frame_duration_sec=1;
424 scan_header.scale_factor=1.0;
425 scan_header.frame_start_time=0;
426 scan_header.frame_duration=1000;
427 /* Deadtime correction was done when reading, set to 1.0 to prevent
428 second correction when reading again. */
429 scan_header.loss_correction_fctr=1.0;
430 /*if(IMG_TEST) ecat63PrintScanheader(&scan_header);*/
431 break;
432 case IMAGE_DATA:
433 image_header.data_type=main_header.data_type;
434 image_header.num_dimensions=2;
435 image_header.dimension_1=img->dimx;
436 image_header.dimension_2=img->dimy;
437 image_header.recon_scale=img->zoom;
438 image_header.quant_scale=1.0;
439 image_header.slice_width=img->sizez/10.;
440 image_header.pixel_size=img->sizex/10.;
441 image_header.frame_start_time=0;
442 image_header.frame_duration=1000;
443 image_header.plane_eff_corr_fctr=1.0;
444 image_header.decay_corr_fctr=1.0;
445 image_header.loss_corr_fctr=1.0;
446 image_header.ecat_calibration_fctr=1.0;
447 image_header.well_counter_cal_fctr=1.0;
448 image_header.quant_units=main_header.calibration_units;
449 /*if(IMG_TEST) ecat63PrintImageheader(&image_header);*/
450 break;
451 }
452
453 /* Write one matrix at a time */
454 int n=0;
455 for(plane=1; plane<=img->dimz;plane++) for(frame=1;frame<=img->dimt;frame++) {
456 /* Scale data to short ints */
457 /* Search min and max */
458 fmin=fmax=f=img->m[plane-1][0][0][frame-1];
459 for(int i=0; i<img->dimy; i++) for(int j=0; j<img->dimx; j++) {
460 f=img->m[plane-1][i][j][frame-1];
461 if(f>fmax) fmax=f; else if(f<fmin) fmin=f;
462 }
463 /* Calculate scaling factor */
464 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
465 if(!isfinite(g)) {
466 sprintf(ecat63errmsg, "invalid pixel values on pl%02d fr%02d (%d).", plane, frame, ret);
467 fclose(fp); remove(fname); free(sdata);
468 return(1);
469 }
470 if(g>0.0) scale=32766./g; else scale=1.0;
471 if(!isfinite(scale)) scale=1.0;
472 // printf("fmin=%e fmax=%e g=%e scale=%e\n", fmin, fmax, g, scale);
473 /* Scale matrix data to shorts */
474 sptr=sdata;
475 for(int i=0; i<img->dimy; i++) for(int j=0; j<img->dimx; j++) {
476 *sptr=(short int)temp_roundf(scale*img->m[plane-1][i][j][frame-1]);
477 sptr++;
478 }
479 /* Calculate and set subheader min&max and scale */
480 smin=(short int)temp_roundf(scale*fmin);
481 smax=(short int)temp_roundf(scale*fmax);
482 if(main_header.file_type==RAW_DATA) {
483 scan_header.scan_min=smin; scan_header.scan_max=smax;
484 scan_header.scale_factor=1.0/scale;
485 scan_header.frame_start_time=(int)temp_roundf(1000.*img->start[frame-1]);
486 scan_header.frame_duration=
487 (int)temp_roundf(1000.*(img->end[frame-1]-img->start[frame-1]));
488 scan_header.sample_distance=(img->sampleDistance)/10.0;
489 scan_header.prompts=temp_roundf(img->prompts[frame-1]);
490 scan_header.delayed=temp_roundf(img->randoms[frame-1]);
491 } else if(main_header.file_type==IMAGE_DATA) {
492 image_header.image_min=smin; image_header.image_max=smax;
493 image_header.quant_scale=1.0/scale;
494 //if(!isfinite(image_header.quant_scale))
495 // printf("g=%g scale=%g quant_scale=%g\n", g, scale, image_header.quant_scale);
496 image_header.frame_start_time=(int)temp_roundf(1000.*img->start[frame-1]);
497 image_header.frame_duration=
498 (int)temp_roundf(1000.*(img->end[frame-1]-img->start[frame-1]));
499 /* Set decay correction factor */
501 image_header.decay_corr_fctr=img->decayCorrFactor[frame-1];
502 else
503 image_header.decay_corr_fctr=0.0;
504 }
505 /* Write matrix data */
506 m=mat_numcod(frame, img->planeNumber[plane-1], 1, 0, 0);
507 sptr=sdata;
508 if(IMG_TEST) printf(" writing matnum=%d\n", m);
509 if(main_header.file_type==RAW_DATA) {
510 if(IMG_TEST) ecat63PrintScanheader(&scan_header, stdout);
511 ret=ecat63WriteScan(fp, m, &scan_header, sptr);
512 } else if(main_header.file_type==IMAGE_DATA) {
513 if(IMG_TEST) ecat63PrintImageheader(&image_header, stdout);
514 ret=ecat63WriteImage(fp, m, &image_header, sptr);
515 }
516 if(ret) {
517 sprintf(ecat63errmsg, "cannot write data on pl%02d fr%02d (%d).",
518 plane, frame, ret);
519 fclose(fp); remove(fname); free(sdata);
520 return(9);
521 }
522 n++;
523 } /* next matrix */
524 if(IMG_TEST) printf(" %d matrices written in %s\n", n, fname);
525
526 /* Close file and free memory */
527 fclose(fp); free(sdata);
528
529 return(0);
530}

Referenced by imgWrite().

◆ ecat63WriteAttn()

int ecat63WriteAttn ( FILE * fp,
int matnum,
ECAT63_attnheader * h,
void * data )
extern

Write ECAT 6.3 attenuation matrix header and data

Parameters
fptarget file pointer
matnummatrix number [1..number of matrixes]
hEcat 6.3 attenuation header
datapointer to data that is written
Returns
0 if ok, 1 invalid input or invalid image dimensions, 2 failed to resolve data type 3 too little data size, 4 failed to resolve next block size in file

Definition at line 563 of file ecat63w.c.

565 {
566 int nxtblk, blkNr, pxlSize, ret;
567
568 if(ECAT63_TEST) printf("ecat63WriteAttn(fp, %d, ah, data)\n", matnum);
569 if(fp==NULL || matnum<1 || h==NULL || data==NULL) return(1);
570 /* nr of pixels */
571 long long pxlNr=h->dimension_1*h->dimension_2; if(pxlNr<1) return(1);
572 /* mem taken by one pixel */
573 switch(h->data_type) {
574 case BYTE_TYPE: pxlSize=1;
575 break;
576 case VAX_I2:
577 case SUN_I2: pxlSize=2;
578 break;
579 case VAX_I4: return(3);
580 case VAX_R4: return(3);
581 case IEEE_R4:
582 case SUN_I4: pxlSize=4;
583 break;
584 default: return(2);
585 }
586 /* mem taken by all pixels */
587 long long data_size=pxlNr*pxlSize;
588 /* block nr taken by all pixels */
589 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(3);
590 /* Get block number for matrix header and data */
591 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) return(4);
592 if(ECAT63_TEST) printf(" block=%d\n", nxtblk);
593 /* Write header */
594 ret=ecat63WriteAttnheader(fp, nxtblk, h); if(ret) return(40+ret);
595 /* Write matrix data */
596 ret=ecat63WriteMatdata(fp, nxtblk+1, data, pxlNr, pxlSize);
597 if(ret) return(50+ret);
598 return 0;
599}
int ecat63Matenter(FILE *fp, int matnum, int blkNr)
Definition ecat63ml.c:159
int ecat63WriteMatdata(FILE *fp, int strtblk, char *data, long long pxlNr, int pxlSize)
Definition ecat63w.c:618
int ecat63WriteAttnheader(FILE *fp, int block, ECAT63_attnheader *h)
Definition ecat63w.c:190

Referenced by atnMake().

◆ ecat63WriteAttnheader()

int ecat63WriteAttnheader ( FILE * fp,
int block,
ECAT63_attnheader * h )
extern

Write ECAT 6.3 attenuation header

Parameters
fptarget file pointer
blockblock number [>=3]
hEcat 6.3 attenuation header
Returns
0 if ok, 1 invalid input, 2 failed to find block, 3 failed to write block

Definition at line 190 of file ecat63w.c.

192 {
193 unsigned char buf[MatBLKSIZE];
194 int little, tovax;
195
196 if(ECAT63_TEST) printf("ecat63WriteAttnheader(fp, %d, ah)\n", block);
197 little=little_endian();
198 /* Clear buf */
199 memset(buf, 0, MatBLKSIZE);
200 /* Check arguments */
201 if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
202 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
203 tovax=1; else tovax=0;
204
205 /* Copy short ints to buf */
206 memcpy(buf+126, &h->data_type, 2);
207 memcpy(buf+128, &h->attenuation_type, 2);
208 memcpy(buf+132, &h->dimension_1, 2);
209 memcpy(buf+134, &h->dimension_2, 2);
210 /* big to little endian if necessary */
211 if(!little) swabip(buf, MatBLKSIZE);
212
213 /* Copy floats to buf */
214 ecat63wFloat(&h->scale_factor, buf+182, tovax, little);
215 ecat63wFloat(&h->x_origin, buf+186, tovax, little);
216 ecat63wFloat(&h->y_origin, buf+190, tovax, little);
217 ecat63wFloat(&h->x_radius, buf+194, tovax, little);
218 ecat63wFloat(&h->y_radius, buf+198, tovax, little);
219 ecat63wFloat(&h->tilt_angle, buf+202, tovax, little);
220 ecat63wFloat(&h->attenuation_coeff, buf+206, tovax, little);
221 ecat63wFloat(&h->sample_distance, buf+210, tovax, little);
222
223 /* Write subheader */
224 fseeko(fp, (block-1)*MatBLKSIZE, SEEK_SET);
225 if(ftello(fp)!=(block-1)*MatBLKSIZE) return(2);
226 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
227
228 return(0);
229}
void ecat63wFloat(float *bufi, void *bufo, int tovax, int islittle)
Definition ecat63w.c:860

Referenced by ecat63WriteAttn().

◆ ecat63WriteImage()

int ecat63WriteImage ( FILE * fp,
int matnum,
ECAT63_imageheader * h,
void * data )
extern

Write ECAT 6.3 image matrix header and data

Parameters
fptarget file pointer
matnummatrix number [1..number of matrixes]
hEcat 6.3 image header
datapointer to data that is written
Returns
0 if ok, 1 invalid input or invalid image dimensions, 2 failed to resolve data type 3 too little data size, 4 failed to resolve next block size in file

Definition at line 410 of file ecat63w.c.

412 {
413 int nxtblk, blkNr, pxlSize, ret;
414
415 if(ECAT63_TEST) printf("ecat63WriteImage(fp, %d, ih, data)\n", matnum);
416 if(fp==NULL || matnum<1 || h==NULL || data==NULL) return(1);
417 /* nr of pixels */
418 long long pxlNr=h->dimension_1*h->dimension_2; if(pxlNr<1) return(2);
419 /* mem taken by one pixel */
420 switch(h->data_type) {
421 case BYTE_TYPE: pxlSize=1;
422 break;
423 case VAX_I2:
424 case SUN_I2: pxlSize=2;
425 break;
426 case VAX_I4: return(3);
427 case VAX_R4: return(3);
428 case IEEE_R4:
429 case SUN_I4: pxlSize=4;
430 break;
431 default: return(2);
432 }
433 /* mem taken by all pixels */
434 long long data_size=pxlNr*pxlSize;
435 /* block nr taken by all pixels */
436 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(3);
437 /* Get block number for matrix header and data */
438 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) return(4);
439 if(ECAT63_TEST) printf(" block=%d\n", nxtblk);
440 /* Write header */
441 ret=ecat63WriteImageheader(fp, nxtblk, h); if(ret) return(40+ret);
442 /* Write matrix data */
443 ret=ecat63WriteMatdata(fp, nxtblk+1, data, pxlNr, pxlSize);
444 if(ret) return(50+ret);
445 return 0;
446}
int ecat63WriteImageheader(FILE *fp, int block, ECAT63_imageheader *h)
Definition ecat63w.c:106

Referenced by ecat63AddImg(), and ecat63WriteAllImg().

◆ ecat63WriteImageheader()

int ecat63WriteImageheader ( FILE * fp,
int block,
ECAT63_imageheader * h )
extern

Write ECAT 6.3 image header

Parameters
fptarget file pointer
blockblock number [>= 3]
hEcat 6.3 image header
Returns
0, if ok, 1 invalid input, 2 failed to find block, 3 failed to write block

Definition at line 106 of file ecat63w.c.

108 {
109 char buf[MatBLKSIZE];
110 int little, tovax;
111
112
113 if(ECAT63_TEST) printf("ecat63WriteImageheader(fp, %d, ih)\n", block);
114 little=little_endian();
115 /* Clear buf */
116 memset(buf, 0, MatBLKSIZE);
117 /* Check arguments */
118 if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
119 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
120 tovax=1; else tovax=0;
121
122 /* Copy short ints to buf */
123 memcpy(buf+126, &h->data_type, 2);
124 memcpy(buf+128, &h->num_dimensions, 2);
125 memcpy(buf+132, &h->dimension_1, 2);
126 memcpy(buf+134, &h->dimension_2, 2);
127 memcpy(buf+176, &h->image_min, 2);
128 memcpy(buf+178, &h->image_max, 2);
129 memcpy(buf+200, &h->slice_location, 2);
130 memcpy(buf+202, &h->recon_start_hour, 2);
131 memcpy(buf+204, &h->recon_start_min, 2);
132 memcpy(buf+206, &h->recon_start_sec, 2);
133 memcpy(buf+236, &h->filter_code, 2);
134 memcpy(buf+376, &h->processing_code, 2);
135 memcpy(buf+380, &h->quant_units, 2);
136 memcpy(buf+382, &h->recon_start_day, 2);
137 memcpy(buf+384, &h->recon_start_month, 2);
138 memcpy(buf+386, &h->recon_start_year, 2);
139 memcpy(buf+460, h->fill2, 52);
140 /* big to little endian if necessary */
141 if(!little) swabip(buf, MatBLKSIZE);
142
143 /* Copy floats to buf */
144 ecat63wFloat(&h->x_origin, buf+160, tovax, little);
145 ecat63wFloat(&h->y_origin, buf+164, tovax, little);
146 ecat63wFloat(&h->recon_scale, buf+168, tovax, little);
147 ecat63wFloat(&h->quant_scale, buf+172, tovax, little);
148 ecat63wFloat(&h->pixel_size, buf+184, tovax, little);
149 ecat63wFloat(&h->slice_width, buf+188, tovax, little);
150 ecat63wFloat(&h->image_rotation, buf+296, tovax, little);
151 ecat63wFloat(&h->plane_eff_corr_fctr, buf+300, tovax, little);
152 ecat63wFloat(&h->decay_corr_fctr, buf+304, tovax, little);
153 ecat63wFloat(&h->loss_corr_fctr, buf+308, tovax, little);
154 ecat63wFloat(&h->intrinsic_tilt, buf+312, tovax, little);
155 ecat63wFloat(&h->ecat_calibration_fctr, buf+388, tovax, little);
156 ecat63wFloat(&h->well_counter_cal_fctr, buf+392, tovax, little);
157 for(int i=0; i<6; i++)
158 ecat63wFloat(&h->filter_params[i], buf+396+4*i, tovax, little);
159
160 /* Copy ints to buf */
161 ecat63wInt(&h->frame_duration, buf+192, tovax, little);
162 ecat63wInt(&h->frame_start_time, buf+196, tovax, little);
163 ecat63wInt(&h->scan_matrix_num, buf+238, tovax, little);
164 ecat63wInt(&h->norm_matrix_num, buf+242, tovax, little);
165 ecat63wInt(&h->atten_cor_mat_num, buf+246, tovax, little);
166
167 /* Copy chars */
168 memcpy(buf+0, h->fill1, 126);
169 memcpy(buf+420, h->annotation, 40);
170
171 /* Write subheader */
172 fseeko(fp, (block-1)*MatBLKSIZE, SEEK_SET);
173 if(ftello(fp)!=(block-1)*MatBLKSIZE) return(2);
174 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
175
176 return(0);
177}
void ecat63wInt(int *bufi, void *bufo, int tovax, int islittle)
Definition ecat63w.c:884

Referenced by ecat63WriteImage(), and ecat63WriteImageMatrix().

◆ ecat63WriteImageMatrix()

int ecat63WriteImageMatrix ( FILE * fp,
int matnum,
ECAT63_imageheader * h,
float * fdata )
extern

Write ECAT 6.3 image matrix header and data

Parameters
fptarget file pointer
matnum
hEcat 6.3 image header
fdata
Returns
0 if ok, 1 invalid input, 3 invalid matrix dimensions, 4 invalid block number, 5 failed to allocate memory, 8 failed to resolve new matrix block number, 10 failed to write image sub header, 13 failed to write matrix data

Definition at line 697 of file ecat63w.c.

699 {
700 int nxtblk, blkNr, ret;
701 float *fptr, fmin, fmax, g, f;
702 char *mdata, *mptr;
703 short int *sptr;
704
705
706
707 if(ECAT63_TEST) printf("ecat63WriteImageMatrix(fp, %d, h, data)\n", matnum);
708 if(fp==NULL || matnum<1 || h==NULL || fdata==NULL) {
709 sprintf(ecat63errmsg, "invalid function parameter.\n");
710 return(1);
711 }
712 /* nr of pixels */
713 long long pxlNr=h->dimension_1*h->dimension_2;
714 if(pxlNr<1) {
715 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
716 return(3);
717 }
718 /* How much memory is needed for ALL pixels */
719 long long data_size=pxlNr*ecat63pxlbytes(h->data_type);
720 /* block nr taken by all pixels */
721 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
722 sprintf(ecat63errmsg, "invalid block number.\n");
723 return(4);
724 }
725 /* Allocate memory for matrix data */
726 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
727 sprintf(ecat63errmsg, "out of memory.\n");
728 return(5);
729 }
730 /* Search for min and max for calculation of scale factor */
731 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
732 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
733 if(g>0) f=32766./g; else f=1.0;
734 /* Check if pixels values can be left as such with scale_factor = 1 */
735 fptr=fdata;
736 if(f>=1.0 && ecat63_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
737 /* Scale matrix data to shorts */
738 h->quant_scale=1.0/f;
739 sptr=(short int*)mdata; fptr=fdata;
740 for(long long i=0; i<pxlNr; i++, sptr++, fptr++)
741 *sptr=(short int)temp_roundf(f*(*fptr));
742 /* Set header short min & max */
743 h->image_min=(short int)temp_roundf(f*fmin);
744 h->image_max=(short int)temp_roundf(f*fmax);
745 /* Get block number for matrix header and data */
746 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) {
747 sprintf(ecat63errmsg, "cannot determine matrix block (%d).\n", -nxtblk);
748 free(mdata); return(8);
749 }
750 if(ECAT63_TEST>2) printf(" block=%d fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
751 /* Write header */
752 ret=ecat63WriteImageheader(fp, nxtblk, h); if(ret) {
753 sprintf(ecat63errmsg, "cannot write subheader (%d).\n", ret);
754 free(mdata); return(10);
755 }
756 /* Write matrix data */
757 mptr=mdata;
758 ret=ecat63WriteMatdata(fp, nxtblk+1, mptr, pxlNr, ecat63pxlbytes(h->data_type));
759 free(mdata);
760 if(ret) {
761 sprintf(ecat63errmsg, "cannot write matrix data (%d).\n", ret);
762 return(13);
763 }
764 return(0);
765}
int ecat63pxlbytes(short int data_type)
Definition ecat63r.c:973
int ecat63_is_scaling_needed(float amax, float *data, long long nr)
Definition ecat63w.c:662
void fMinMaxFin(float *data, long long int n, float *fmin, float *fmax)
Definition imgminmax.c:649

Referenced by atnMake(), and imgWriteEcat63Frame().

◆ ecat63WriteMainheader()

int ecat63WriteMainheader ( FILE * fp,
ECAT63_mainheader * h )
extern

Write ECAT 6.3 main header.

Parameters
fptarget file pointer
hEcat 6.3 main header
Returns
0, if ok, 1 invalid input, 2 failed to find block, 3 failed to write block

Definition at line 24 of file ecat63w.c.

26 {
27 char buf[MatBLKSIZE];
28 int little, tovax;
29
30
31 if(ECAT63_TEST) printf("ecat63WriteMainheader()\n");
32 little=little_endian();
33 /* Clear buf */
34 memset(buf, 0, MatBLKSIZE);
35 /* Check arguments */
36 if(fp==NULL || h->data_type<1 || h->data_type>7) return(1);
37 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
38 tovax=1; else tovax=0;
39
40 /* Copy short ints to buf */
41 memcpy(buf+50, &h->data_type, 2); memcpy(buf+48, &h->sw_version, 2);
42 memcpy(buf+52, &h->system_type, 2); memcpy(buf+54, &h->file_type, 2);
43 memcpy(buf+66, &h->scan_start_day, 2); memcpy(buf+68, &h->scan_start_month, 2);
44 memcpy(buf+70, &h->scan_start_year, 2); memcpy(buf+72, &h->scan_start_hour, 2);
45 memcpy(buf+74, &h->scan_start_minute, 2);
46 memcpy(buf+76, &h->scan_start_second, 2);
47 memcpy(buf+134, &h->rot_source_speed, 2); memcpy(buf+136, &h->wobble_speed, 2);
48 memcpy(buf+138, &h->transm_source_type, 2);
49 memcpy(buf+148, &h->transaxial_samp_mode, 2);
50 memcpy(buf+150, &h->coin_samp_mode, 2); memcpy(buf+152, &h->axial_samp_mode, 2);
51 memcpy(buf+158, &h->calibration_units, 2);
52 memcpy(buf+160, &h->compression_code, 2);
53 memcpy(buf+350, &h->acquisition_type, 2); memcpy(buf+352, &h->bed_type, 2);
54 memcpy(buf+354, &h->septa_type, 2); memcpy(buf+376, &h->num_planes, 2);
55 memcpy(buf+378, &h->num_frames, 2); memcpy(buf+380, &h->num_gates, 2);
56 memcpy(buf+382, &h->num_bed_pos, 2); memcpy(buf+452, &h->lwr_sctr_thres, 2);
57 memcpy(buf+454, &h->lwr_true_thres, 2); memcpy(buf+456, &h->upr_true_thres, 2);
58 memcpy(buf+472, h->fill2, 40);
59 /* big to little endian if necessary */
60 if(!little) swabip(buf, MatBLKSIZE);
61
62 /* Copy floats to buf */
63 ecat63wFloat(&h->isotope_halflife, buf+86, tovax, little);
64 ecat63wFloat(&h->gantry_tilt, buf+122, tovax, little);
65 ecat63wFloat(&h->gantry_rotation, buf+126, tovax, little);
66 ecat63wFloat(&h->bed_elevation, buf+130, tovax, little);
67 ecat63wFloat(&h->axial_fov, buf+140, tovax, little);
68 ecat63wFloat(&h->transaxial_fov, buf+144, tovax, little);
69 ecat63wFloat(&h->calibration_factor, buf+154, tovax, little);
70 ecat63wFloat(&h->init_bed_position, buf+384, tovax, little);
71 for(int i=0; i<15; i++) ecat63wFloat(&h->bed_offset[i], buf+388+4*i, tovax, little);
72 ecat63wFloat(&h->plane_separation, buf+448, tovax, little);
73 ecat63wFloat(&h->init_bed_position, buf+458, tovax, little);
74
75 /* Copy chars */
76 /*memcpy(buf+0, h->ecat_format, 14);*/
77 memcpy(buf+14, h->fill1, 14);
78 memcpy(buf+28, h->original_file_name, 20); memcpy(buf+56, h->node_id, 10);
79 memcpy(buf+78, h->isotope_code, 8); memcpy(buf+90, h->radiopharmaceutical, 32);
80 memcpy(buf+162, h->study_name, 12); memcpy(buf+174, h->patient_id, 16);
81 memcpy(buf+190, h->patient_name, 32); buf[222]=h->patient_sex;
82 memcpy(buf+223, h->patient_age, 10); memcpy(buf+233, h->patient_height, 10);
83 memcpy(buf+243, h->patient_weight, 10); buf[253]=h->patient_dexterity;
84 memcpy(buf+254, h->physician_name, 32); memcpy(buf+286, h->operator_name, 32);
85 memcpy(buf+318, h->study_description, 32); memcpy(buf+356, h->facility_name, 20);
86 memcpy(buf+462, h->user_process_code, 10);
87
88 /* Write main header */
89 fseek(fp, 0*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=0*MatBLKSIZE) return(2);
90 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
91
92 return(0);
93}

Referenced by ecat63AddImg(), ecat63Create(), and imgWriteEcat63Frame().

◆ ecat63WriteMatdata()

int ecat63WriteMatdata ( FILE * fp,
int strtblk,
char * data,
long long pxlNr,
int pxlSize )
extern

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.

Parameters
fptarget file pointer
strtblkstarting image block [>=1]
datapointer to data that is written
pxlNrnumber of items to be written [>=1]
pxlSizesize of one data item in bytes [>=1]
Returns
0 if ok, 1 invalid input, 2 failed to find starting block, 3 failed to write data

Definition at line 618 of file ecat63w.c.

620 {
621 unsigned char buf[MatBLKSIZE];
622 char *dptr;
623 int blkNr, byteNr;
624
625 if(ECAT63_TEST)
626 printf("ecat63WriteMatdata(fp, %d, data, %lld, %d)\n", strtblk, pxlNr, pxlSize);
627 if(fp==NULL || strtblk<1 || data==NULL || pxlNr<1 || pxlSize<1) return(1);
628 memset(buf, 0, MatBLKSIZE);
629 long long dataSize=pxlNr*pxlSize; if(dataSize<1) return(1);
630 /* block nr taken by all pixels */
631 blkNr=(dataSize+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(1);
632 if(ECAT63_TEST>1) printf(" blkNr=%d\n", blkNr);
633 /* Search the place for writing */
634 fseeko(fp, (strtblk-1)*MatBLKSIZE, SEEK_SET);
635 if(ftello(fp)!=(strtblk-1)*MatBLKSIZE) return(2);
636 /* Save blocks one at a time */
637 dptr=data;
638 for(int i=0; i<blkNr && dataSize>0; i++) {
639 byteNr=(dataSize<MatBLKSIZE)?dataSize:MatBLKSIZE;
640 memcpy(buf, dptr, byteNr);
641 /* Change matrix byte order in big endian platforms */
642 if(!little_endian()) {
643 if(pxlSize==2) swabip(buf, byteNr);
644 else if(pxlSize==4) swawbip(buf, byteNr);
645 }
646 /* Write block */
647 if(fwrite(buf, 1, MatBLKSIZE, fp)!=MatBLKSIZE) return(3);
648 /* Prepare for the next block */
649 dptr+=byteNr;
650 dataSize-=byteNr;
651 } /* next block */
652 return(0);
653}

Referenced by ecat63WriteAttn(), ecat63WriteImage(), ecat63WriteImageMatrix(), ecat63WriteNorm(), ecat63WriteScan(), and ecat63WriteScanMatrix().

◆ ecat63WriteNorm()

int ecat63WriteNorm ( FILE * fp,
int matnum,
ECAT63_normheader * h,
void * data )
extern

Write ECAT 6.3 normalization matrix header and data

Parameters
fptarget file pointer
matnummatrix number [1..number of matrixes]
hEcat 6.3 normalization header
datapointer to data that is written
Returns
0 if ok, 1 invalid input or invalid image dimensions, 2 failed to resolve data type 3 too little data size, 4 failed to resolve next block size in file

Definition at line 512 of file ecat63w.c.

514 {
515 int nxtblk, blkNr, pxlSize, ret;
516
517 if(ECAT63_TEST) printf("ecat63WriteNorm(fp, %d, nh, data)\n", matnum);
518 if(fp==NULL || matnum<1 || h==NULL || data==NULL) return(1);
519 /* nr of pixels */
520 long long pxlNr=h->dimension_1*h->dimension_2; if(pxlNr<1) return(1);
521 /* mem taken by one pixel */
522 switch(h->data_type) {
523 case BYTE_TYPE: pxlSize=1;
524 break;
525 case VAX_I2:
526 case SUN_I2: pxlSize=2;
527 break;
528 case VAX_I4: return(3);
529 case VAX_R4: return(3);
530 case IEEE_R4:
531 case SUN_I4: pxlSize=4;
532 break;
533 default: return(2);
534 }
535 /* mem taken by all pixels */
536 long long data_size=pxlNr*pxlSize;
537 /* block nr taken by all pixels */
538 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(3);
539 /* Get block number for matrix header and data */
540 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) return(4);
541 if(ECAT63_TEST) printf(" block=%d\n", nxtblk);
542 /* Write header */
543 ret=ecat63WriteNormheader(fp, nxtblk, h); if(ret) return(40+ret);
544 /* Write matrix data */
545 ret=ecat63WriteMatdata(fp, nxtblk+1, data, pxlNr, pxlSize);
546 if(ret) return(50+ret);
547 return 0;
548}
int ecat63WriteNormheader(FILE *fp, int block, ECAT63_normheader *h)
Definition ecat63w.c:313

◆ ecat63WriteNormheader()

int ecat63WriteNormheader ( FILE * fp,
int block,
ECAT63_normheader * h )
extern

Write ECAT 6.3 normalization header

Parameters
fptarget file pointer
blockblock number [>=3]
hEcat 6.3 normalization header
Returns
0 if ok, 1 invalid input, 2 failed to find block, 3 failed to write block

Definition at line 313 of file ecat63w.c.

315 {
316 unsigned char buf[MatBLKSIZE];
317 int little, tovax;
318
319 if(ECAT63_TEST) printf("ecat63WriteNormheader(fp, %d, nh)\n", block);
320 little=little_endian();
321 /* Clear buf */
322 memset(buf, 0, MatBLKSIZE);
323 /* Check arguments */
324 if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
325 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
326 tovax=1; else tovax=0;
327
328 /* Copy short ints to buf */
329 memcpy(buf+126, &h->data_type, 2);
330 memcpy(buf+132, &h->dimension_1, 2);
331 memcpy(buf+134, &h->dimension_2, 2);
332 memcpy(buf+372, &h->norm_hour, 2);
333 memcpy(buf+376, &h->norm_minute, 2);
334 memcpy(buf+380, &h->norm_second, 2);
335 memcpy(buf+384, &h->norm_day, 2);
336 memcpy(buf+388, &h->norm_month, 2);
337 memcpy(buf+392, &h->norm_year, 2);
338 /* big to little endian if necessary */
339 if(!little) swabip(buf, MatBLKSIZE);
340
341 /* Copy floats to buf */
342 ecat63wFloat(&h->scale_factor, buf+182, tovax, little);
343 ecat63wFloat(&h->fov_source_width, buf+198, tovax, little);
344
345 /* Write subheader */
346 fseeko(fp, (block-1)*MatBLKSIZE, SEEK_SET);
347 if(ftello(fp)!=(block-1)*MatBLKSIZE) return(2);
348 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
349
350 return(0);
351}

Referenced by ecat63WriteNorm().

◆ ecat63WriteScan()

int ecat63WriteScan ( FILE * fp,
int matnum,
ECAT63_scanheader * h,
void * data )
extern

Write ECAT 6.3 sinogram matrix header and data

Parameters
fptarget file pointer
matnummatrix number [1..number of matrixes]
hEcat 6.3 scan header
datapointer to data that is written
Returns
0 if ok, 1 invalid input or invalid image dimensions, 2 failed to resolve data type 3 too little data size, 4 failed to resolve next block size in file

Definition at line 461 of file ecat63w.c.

463 {
464 int nxtblk, blkNr, pxlSize, ret;
465
466 if(ECAT63_TEST) printf("ecat63WriteScan(fp, %d, sh, data)\n", matnum);
467 if(fp==NULL || matnum<1 || h==NULL || data==NULL) return(1);
468 /* nr of pixels */
469 long long pxlNr=h->dimension_1*h->dimension_2; if(pxlNr<1) return(1);
470 /* mem taken by one pixel */
471 switch(h->data_type) {
472 case BYTE_TYPE: pxlSize=1;
473 break;
474 case VAX_I2:
475 case SUN_I2: pxlSize=2;
476 break;
477 case VAX_I4: return(3);
478 case VAX_R4: return(3);
479 case IEEE_R4:
480 case SUN_I4: pxlSize=4;
481 break;
482 default: return(2);
483 }
484 /* mem taken by all pixels */
485 long long data_size=pxlNr*pxlSize;
486 /* block nr taken by all pixels */
487 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(3);
488 /* Get block number for matrix header and data */
489 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) return(4);
490 if(ECAT63_TEST) printf(" block=%d\n", nxtblk);
491 /* Write header */
492 ret=ecat63WriteScanheader(fp, nxtblk, h); if(ret) return(40+ret);
493 /* Write matrix data */
494 ret=ecat63WriteMatdata(fp, nxtblk+1, data, pxlNr, pxlSize);
495 if(ret) return(50+ret);
496 return 0;
497}
int ecat63WriteScanheader(FILE *fp, int block, ECAT63_scanheader *h)
Definition ecat63w.c:242

Referenced by ecat63AddImg(), and ecat63WriteAllImg().

◆ ecat63WriteScanheader()

int ecat63WriteScanheader ( FILE * fp,
int block,
ECAT63_scanheader * h )
extern

Write ECAT 6.3 scan header

Parameters
fptarget file pointer
blockblock number [>=3]
hEcat 6.3 scan header
Returns
0 if ok, 1 invalid input, 2 failed to find block, 3 failed to write block

Definition at line 242 of file ecat63w.c.

244 {
245 unsigned char buf[MatBLKSIZE];
246 int little, tovax;
247
248
249 if(ECAT63_TEST) printf("ecat63WriteScanheader(fp, %d, ih)\n", block);
250 little=little_endian();
251 /* Clear buf */
252 memset(buf, 0, MatBLKSIZE);
253 /* Check arguments */
254 if(fp==NULL || block<3 || h->data_type<1 || h->data_type>7) return(1);
255 if(h->data_type==VAX_I2 || h->data_type==VAX_I4 || h->data_type==VAX_R4)
256 tovax=1; else tovax=0;
257
258 /* Copy short ints to buf */
259 memcpy(buf+126, &h->data_type, 2);
260 memcpy(buf+132, &h->dimension_1, 2); memcpy(buf+134, &h->dimension_2, 2);
261 memcpy(buf+136, &h->smoothing, 2); memcpy(buf+138, &h->processing_code, 2);
262 memcpy(buf+170, &h->frame_duration_sec, 2);
263 memcpy(buf+192, &h->scan_min, 2); memcpy(buf+194, &h->scan_max, 2);
264 memcpy(buf+468, h->fill2, 44);
265 /* big to little endian if necessary */
266 if(!little) swabip(buf, MatBLKSIZE);
267
268 /* Copy floats to buf */
269 ecat63wFloat(&h->sample_distance, buf+146, tovax, little);
270 ecat63wFloat(&h->isotope_halflife, buf+166, tovax, little);
271 ecat63wFloat(&h->scale_factor, buf+182, tovax, little);
272 for(int i=0; i<16; i++) {
273 ecat63wFloat(&h->cor_singles[i], buf+316+4*i, tovax, little);
274 ecat63wFloat(&h->uncor_singles[i], buf+380+4*i, tovax, little);
275 }
276 ecat63wFloat(&h->tot_avg_cor, buf+444, tovax, little);
277 ecat63wFloat(&h->tot_avg_uncor, buf+448, tovax, little);
278 ecat63wFloat(&h->loss_correction_fctr, buf+464, tovax, little);
279
280 /* Copy ints to buf */
281 ecat63wInt(&h->gate_duration, buf+172, tovax, little);
282 ecat63wInt(&h->r_wave_offset, buf+176, tovax, little);
283 ecat63wInt(&h->prompts, buf+196, tovax, little);
284 ecat63wInt(&h->delayed, buf+200, tovax, little);
285 ecat63wInt(&h->multiples, buf+204, tovax, little);
286 ecat63wInt(&h->net_trues, buf+208, tovax, little);
287 ecat63wInt(&h->total_coin_rate, buf+452, tovax, little);
288 ecat63wInt(&h->frame_start_time, buf+456, tovax, little);
289 ecat63wInt(&h->frame_duration, buf+460, tovax, little);
290
291 /* Copy chars */
292 memcpy(buf+0, h->fill1, 126);
293
294 /* Write subheader */
295 fseeko(fp, (block-1)*MatBLKSIZE, SEEK_SET);
296 if(ftello(fp)!=(block-1)*MatBLKSIZE) return(2);
297 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(3);
298
299 return(0);
300}

Referenced by ecat63WriteScan(), and ecat63WriteScanMatrix().

◆ ecat63WriteScanMatrix()

int ecat63WriteScanMatrix ( FILE * fp,
int matnum,
ECAT63_scanheader * h,
float * fdata )
extern

Write ECAT 6.3 sinogram matrix header and data

Parameters
fptarget file pointer
matnummatrix number [1..number of matrixes]
hEcat 6.3 scan header
fdatamatrix data
Returns
0 if ok, 1 invalid input, 3 invalid matrix dimension, 4 invalid block number, 5 failed to allocate memory for data, 8 failed to resolve next block number, 10 cannot write sub header, 13 failed to write data

Definition at line 781 of file ecat63w.c.

783 {
784 int nxtblk, blkNr, ret;
785 float *fptr, fmin, fmax, g, f;
786 char *mdata, *mptr;
787 short int *sptr;
788
789
790 if(ECAT63_TEST) printf("ecat63WriteScanMatrix(fp, %d, h, data)\n", matnum);
791 if(fp==NULL || matnum<1 || h==NULL || fdata==NULL) {
792 sprintf(ecat63errmsg, "invalid function parameter.\n");
793 return(1);
794 }
795 /* nr of pixels */
796 long long pxlNr=h->dimension_1*h->dimension_2;
797 if(pxlNr<1) {
798 sprintf(ecat63errmsg, "invalid matrix dimension.\n");
799 return(3);
800 }
801 /* How much memory is needed for ALL pixels */
802 long long data_size=pxlNr*ecat63pxlbytes(h->data_type);
803 /* block nr taken by all pixels */
804 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
805 sprintf(ecat63errmsg, "invalid block number.\n");
806 return(4);
807 }
808 /* Allocate memory for matrix data */
809 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
810 sprintf(ecat63errmsg, "out of memory.\n");
811 return(5);
812 }
813 /* Search for min and max for calculation of scale factor */
814 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
815 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
816 if(g>0) f=32766./g; else f=1.0;
817 /* Check if pixels values can be left as such with scale_factor = 1 */
818 fptr=fdata;
819 if(f>=1.0 && ecat63_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
820 /* Scale matrix data to shorts */
821 h->scale_factor=1.0/f;
822 sptr=(short int*)mdata; fptr=fdata;
823 for(long long i=0; i<pxlNr; i++, sptr++, fptr++)
824 *sptr=(short int)temp_roundf(f*(*fptr));
825 /* Set header short min & max */
826 h->scan_min=(short int)temp_roundf(f*fmin);
827 h->scan_max=(short int)temp_roundf(f*fmax);
828 /* Get block number for matrix header and data */
829 nxtblk=ecat63Matenter(fp, matnum, blkNr); if(nxtblk<1) {
830 sprintf(ecat63errmsg, "cannot determine matrix block (%d).\n", -nxtblk);
831 free(mdata); return(8);
832 }
833 if(ECAT63_TEST>2) printf(" block=%d fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
834 /* Write header */
835 ret=ecat63WriteScanheader(fp, nxtblk, h); if(ret) {
836 sprintf(ecat63errmsg, "cannot write subheader (%d).\n", ret);
837 free(mdata); return(10);
838 }
839 /* Write matrix data */
840 mptr=mdata;
841 ret=ecat63WriteMatdata(fp, nxtblk+1, mptr, pxlNr, ecat63pxlbytes(h->data_type));
842 free(mdata);
843 if(ret) {
844 sprintf(ecat63errmsg, "cannot write matrix data (%d).\n", ret);
845 return(13);
846 }
847 return(0);
848}

Referenced by imgWriteEcat63Frame().

◆ ecat6PrintSubheader()

int ecat6PrintSubheader ( ECAT63_mainheader mh,
FILE * fp,
int plane,
int frame,
FILE * ofp )
extern

Print ECAT63 subheader contents into specified file pointer.

Returns
Returns 0 when successful.
Parameters
mhECAT 6.3 mainheader (not printed but needed here)
fpFile pointer to ECAT 6.3 file.
planeECAT 6.3 plane; enter <0 to print all planes.
frameECAT 6.3 frame; enter <0 to print all frames.
ofpOutput is written to this file pointer; it can be stdout

Definition at line 293 of file ecat63p.c.

304 {
305 int mi, ret, nr=0;
306 static MATRIXLIST mlist;
307 ECAT63_imageheader image_header;
308 ECAT63_scanheader scan_header;
309 ECAT63_attnheader attn_header;
310 ECAT63_normheader norm_header;
311 Matval matval;
312
313
314 /* Read matrix list and nr */
315 ecat63InitMatlist(&mlist);
316 ret=ecat63ReadMatlist(fp, &mlist, ECAT63_TEST);
317 if(ret) {
318 fprintf(stderr, "Error (%d): cannot read matrix list.\n", ret);
319 return 2;
320 }
321 if(mlist.matrixNr<=0) {
322 fprintf(stderr, "Error: matrix list is empty.\n");
323 return 2;
324 }
325 if(ECAT63_TEST>1) ecat63PrintMatlist(&mlist);
326
327 /*
328 * Read and print subheaders one at a time
329 */
330 char errmsg[128]; int errCount=0;
331 for(mi=nr=0; mi<mlist.matrixNr; mi++) {
332 /* Get plane and frame nr */
333 mat_numdoc(mlist.matdir[mi].matnum, &matval);
334 /* Check if this is supposed to be listed or not */
335 if(frame>=0 && frame!=matval.frame) continue;
336 if(plane>=0 && plane!=matval.plane) continue;
337 fprintf(ofp, "\nMatrix: plane %d frame %d gate %d bed %d\n",
338 matval.plane, matval.frame, matval.gate, matval.bed);
339 fflush(ofp);
340 /* Read subheader */
341 if(mh.file_type==IMAGE_DATA)
342 ret=ecat63ReadImageheader(fp, mlist.matdir[mi].strtblk, &image_header, ECAT63_TEST-1, errmsg);
343 else if(mh.file_type==RAW_DATA)
344 ret=ecat63ReadScanheader(fp, mlist.matdir[mi].strtblk, &scan_header, ECAT63_TEST-1, errmsg);
345 else if(mh.file_type==ATTN_DATA)
346 ret=ecat63ReadAttnheader(fp, mlist.matdir[mi].strtblk, &attn_header, ECAT63_TEST-1, errmsg);
347 else if(mh.file_type==NORM_DATA)
348 ret=ecat63ReadNormheader(fp, mlist.matdir[mi].strtblk, &norm_header, ECAT63_TEST-1, errmsg);
349 if(ret) {
350 fprintf(stderr, "Error: %s.\n", errmsg);
351 //fprintf(stderr, "Error: cannot read matrix %u subheader.\n", mlist.matdir[mi].matnum);
352 //if(ECAT63_TEST>0) printf(" ret=%d\n", ret);
353 /*ecat63EmptyMatlist(&mlist); return 4;*/
354 errCount++;
355 continue;
356 }
357 /* Print subheader */
358 if(mh.file_type==IMAGE_DATA)
359 ecat63PrintImageheader(&image_header, ofp);
360 else if(mh.file_type==RAW_DATA)
361 ecat63PrintScanheader(&scan_header, ofp);
362 else if(mh.file_type==ATTN_DATA)
363 ecat63PrintAttnheader(&attn_header, ofp);
364 else if(mh.file_type==NORM_DATA)
365 ecat63PrintNormheader(&norm_header, ofp);
366 nr++; // counter
367 } /* next matrix */
368 ecat63EmptyMatlist(&mlist);
369
370 if(errCount>0 && nr>0 && (plane<0 || frame<0)) {
371 if(errCount==1) fprintf(stderr, "\nWarning: one matrix could not be read.\n");
372 else fprintf(stderr, "\nWarning: %d matrices could not be read.\n", errCount);
373 }
374
375 if(nr==0 && (plane>=0 || frame>=0)) {
376 fprintf(stderr, "Error: specified matrices not found.\n");
377 return(11);
378 }
379
380 return(0);
381}
void ecat63PrintNormheader(ECAT63_normheader *h, FILE *fp)
Definition ecat63p.c:197

◆ ecat7_id_to_val()

void ecat7_id_to_val ( int matrix_id,
ECAT7_Matval * matval )
extern

Conversion of matrix identifier to numerical values

Parameters
matrix_idmatrix identifier coding
matvalmatrix values structure

Definition at line 262 of file ecat7ml.c.

262 {
263 matval->frame = matrix_id & 0x1FF;
264 matval->plane = ((matrix_id >> 16) & 0xFF) + ((matrix_id >> 1) & 0x300);
265 matval->gate = (matrix_id >> 24) & 0x3F;
266 matval->data = ((matrix_id >> 30) & 0x3) + ((matrix_id >> 9) & 0x4);
267 matval->bed = (matrix_id >> 12) & 0xF;
268}

Referenced by ecat7DeleteLateFrames(), ecat7GatherMatlist(), ecat7GetNums(), ecat7GetPlaneAndFrameNr(), ecat7PrintMatlist(), ecat7PrintSubheader(), ecat7ReadHeaders(), ecat7SortMatlistByFrame(), ecat7SortMatlistByPlane(), ecat7WriteHeaders(), imgReadEcat7(), and imgReadEcat7Frame().

◆ ecat7_is_scaling_needed()

int ecat7_is_scaling_needed ( float amax,
float * data,
long long nr )
extern

Check if pixel float values need to be scaled to be saved as short ints, or if they are already all very close to integers.

Returns
1, if scaling is necessary, and 0 if not.
Parameters
amaxAbsolute maximum value.
dataFloat array.
nrNumber of float values in float array.

Definition at line 604 of file ecat7w.c.

611 {
612 double d;
613
614 if(nr<1 || data==NULL) return(0);
615 /* scaling is necessary if all values are between -1 - 1 */
616 if(amax<0.9999) return(1);
617 /* Lets check first if at least the max value is close to integers or not */
618 if(modf(amax, &d)>0.0001) return(1);
619 /* if it is, then check all pixels */
620 for(long long i=0; i<nr; i++) if(modf(*data++, &d)>0.0001) return(1);
621 return(0);
622}

Referenced by ecat7Write2DScanMatrix(), ecat7WriteImageMatrix(), ecat7WritePolarmapMatrix(), and ecat7WriteScanMatrix().

◆ ecat7_val_to_id()

int ecat7_val_to_id ( int frame,
int plane,
int gate,
int data,
int bed )
extern

Returns the matrix identifier.

Parameters
frameframe number [0..65536]
planeplane number [0..65536]
gategate number [0..64]
datadata [0..1]
bedbed position [0..16]
Returns
matrix identifier coding

Definition at line 245 of file ecat7ml.c.

245 {
246 return(
247 ((bed & 0xF) << 12) | /* bed */
248 (frame & 0x1FF) | /* frame */
249 ((gate & 0x3F) << 24) | /* gate */
250 ((plane & 0xFF) << 16) | /* plane low */
251 ((plane & 0x300) << 1) | /* plane high */
252 ((data & 0x3) << 30) | /* data low */
253 ((data & 0x4) << 9) /* data high */
254 );
255}

Referenced by ecat7GatherMatlist(), imgWrite2DEcat7(), imgWriteEcat7(), imgWriteEcat7Frame(), and imgWritePolarmap().

◆ ecat7acquisitiontype()

char * ecat7acquisitiontype ( short int acquisition_type)
extern

Returns pointer to a string describing the ECAT7 acquisition_type

Parameters
acquisition_typeacquisition type code
Returns
pointer to static string

Definition at line 468 of file ecat7p.c.

470 {
471 static char *info[] = {
472 "undefined", "blank", "transmission", "static emission",
473 "dynamic emission", "gated emission", "transmission rectilinear",
474 "emission rectilinear",
475 0};
476 if(acquisition_type>=0 && acquisition_type<=7)
477 return((char*)info[acquisition_type]);
478 else return((char*)info[0]);
479}

Referenced by ecat7PrintMainheader().

◆ ecat7CheckMatlist()

int ecat7CheckMatlist ( ECAT7_MATRIXLIST * ml)
extern

Checks that all matrixlist entries have read/write status.

Parameters
mlchecked matrix list
Returns
0 if ok, or 1 if an entry is marked as deleted or unfinished

Definition at line 329 of file ecat7ml.c.

329 {
330 int i;
331
332 if(ml==NULL) return(1);
333 for(i=0; i<ml->matrixNr; i++) if(ml->matdir[i].status!=1) return(1);
334 return(0);
335}
ECAT7_MatDir * matdir

Referenced by ecat7ReadHeaders(), ecat7WriteHeaders(), ecatFixMatrixlist(), imgReadEcat7(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7Create()

FILE * ecat7Create ( const char * fname,
ECAT7_mainheader * h )
extern

Create a new ECAT 7.x file. If file exists, it is renamed as fname% if possible. Directory list is written in big endian byte order.

Parameters
fnamefilename
hEcat7 main header
Returns
file pointer or NULL in case of an error.

Definition at line 567 of file ecat7w.c.

567 {
568 FILE *fp;
569 char tmp[FILENAME_MAX];
570 int buf[MatBLKSIZE/4];
571
572 if(ECAT7_TEST) printf("ecat7Create(%s, h)\n", fname);
573 /* Check the arguments */
574 if(fname==NULL || h==NULL) return(NULL);
575 /* Check if file exists; backup, if necessary */
576 if(access(fname, 0) != -1) {
577 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
578 if(access(tmp, 0) != -1) remove(tmp);
579 if(ECAT7_TEST) printf("Renaming %s -> %s\n", fname, tmp);
580 rename(fname, tmp);
581 }
582 /* Open file */
583 fp=fopen(fname, "wb+"); if(fp==NULL) return(fp);
584 /* Write main header */
585 if(ecat7WriteMainheader(fp, h)) return(NULL);
586 /* Construct an empty matrix list ; convert to little endian if necessary */
587 memset(buf, 0, MatBLKSIZE);
588 buf[0]=31; buf[1]=MatFirstDirBlk; if(little_endian()) swawbip(buf, MatBLKSIZE);
589 /* Write data buffer */
590 fseek(fp, (MatFirstDirBlk-1)*MatBLKSIZE, SEEK_SET);
591 if(ftell(fp)!=(MatFirstDirBlk-1)*MatBLKSIZE) return(NULL);
592 if(fwrite(buf, 4, MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(NULL);
593 /* OK, then return file pointer */
594 return(fp);
595}
int ECAT7_TEST
Definition ecat7h.c:6
int ecat7WriteMainheader(FILE *fp, ECAT7_mainheader *h)
Definition ecat7w.c:16

Referenced by ecat7CopyFile(), imgWrite2DEcat7(), imgWriteEcat7(), imgWriteEcat7Frame(), and imgWritePolarmap().

◆ ecat7datatype()

char * ecat7datatype ( short int data_type)
extern

Returns pointer to a string describing the ECAT7 data_type

Parameters
data_typedata type code
Returns
pointer to static string

Definition at line 489 of file ecat7p.c.

491 {
492 static char *info[] = {
493 "unknown", "byte", "VAX 2 byte integer", "VAX 4 byte integer",
494 "VAX 4 byte float", "IEEE 4 byte float", "SUN 2 byte integer",
495 "SUN 4 byte integer",
496 0};
497 if(data_type>=0 && data_type<=7) return((char*)info[data_type]);
498 else return((char*)info[0]);
499}

Referenced by ecat7Print2DNormheader(), ecat7Print2DScanheader(), ecat7PrintAttenheader(), ecat7PrintImageheader(), ecat7PrintNormheader(), ecat7PrintPolmapheader(), and ecat7PrintScanheader().

◆ ecat7DeleteLateFrames()

int ecat7DeleteLateFrames ( ECAT7_MATRIXLIST * ml,
int frame_nr )
extern

Mark deleted the frames after the specified frame number.

Parameters
mltarget matrix list
frame_nrfirst index to be marked as deleted [1..number of frames]
Returns
Returns the number of deleted matrices.

Definition at line 346 of file ecat7ml.c.

346 {
347 int i, del_nr=0;
348 ECAT7_Matval matval;
349
350 for(i=0; i<ml->matrixNr; i++) {
351 ecat7_id_to_val(ml->matdir[i].id, &matval);
352 if(matval.frame>frame_nr) {del_nr++; ml->matdir[i].status=-1;}
353 }
354 return(del_nr);
355}
void ecat7_id_to_val(int matrix_id, ECAT7_Matval *matval)
Definition ecat7ml.c:262

◆ ecat7EditMHeader()

int ecat7EditMHeader ( ECAT7_mainheader * h,
char * field,
char * value,
int verbose )
extern

Edit ECAT 7 main header.

Returns
Returns 0, if ok, and 1 or 2, if field name or or value is invalid.
Parameters
hPointer to ECAT 7 mainheader structure
fieldField name to be changed
valueNew value for the field
verboseVerbose level; if <=0, then nothing is printed into stdout

Definition at line 16 of file ecat7h.c.

25 {
26 int yy, mm, dd;
27 short int si;
28 float f;
29
30 if(verbose>0) printf("ecat7EditMHeader('%s', '%s')\n", field, value);
31 si=atoi(value); f=atof(value);
32 if(strcmp(field, "magic_number")==0) {
33 strlcpy(h->magic_number, value, 14);
34 } else if(strcmp(field, "original_file_name")==0) {
35 strlcpy(h->original_file_name, value, 32);
36 } else if(strcmp(field, "sw_version")==0) {
37 if(si<=0) return(2); else h->sw_version=si;
38 } else if(strcmp(field, "system_type")==0) {
39 if(si<0) return(2); else h->system_type=si;
40 } else if(strcmp(field, "file_type")==0) {
41 if(si<0) return(2); else h->file_type=si;
42 } else if(strcmp(field, "serial_number")==0) {
43 strlcpy(h->serial_number, value, 10);
44 } else if(strcmp(field, "scan_start_time")==0) {
45 struct tm stm;
46 time_t t;
47 if(get_datetime(value, &stm, verbose-1)!=0) return(2);
48 if(verbose>3) printf(" year=%d\n", stm.tm_year);
49 if(verbose>1) printf(" hour=%d\n", stm.tm_hour);
50 /* ECAT 7 main header saves int, not time_t (long int),
51 therefore checking whether time can be saved correctly */
52 t=timegm(&stm);
53 h->scan_start_time=timegm(&stm);
54 if(t!=(time_t)h->scan_start_time) {
55 /* no it can't be saved as required; set negative time as time base */
56 if(t<(time_t)0) h->scan_start_time=0;
57 else return(2); /* if too far in future, return error */
58 }
59 if(verbose>1) printf(" scan_start_time := %d\n", h->scan_start_time);
60 if(h->scan_start_time==-1) h->scan_start_time=0; //return(2);
61 } else if(strcmp(field, "isotope_name")==0) {
62 strlcpy(h->isotope_name, value, 8);
63 } else if(strcmp(field, "isotope_halflife")==0) {
64 if(f<=1.0E-3) return(2); else h->isotope_halflife=f;
65 } else if(strcmp(field, "radiopharmaceutical")==0) {
66 strlcpy(h->radiopharmaceutical, value, 32);
67 } else if(strcmp(field, "gantry_tilt")==0) {
68 h->gantry_tilt=f;
69 } else if(strcmp(field, "gantry_rotation")==0) {
70 h->gantry_rotation=f;
71 } else if(strcmp(field, "bed_elevation")==0) {
72 h->bed_elevation=f;
73 } else if(strcmp(field, "intrinsic_tilt")==0) {
74 h->intrinsic_tilt=f;
75 } else if(strcmp(field, "wobble_speed")==0) {
76 h->wobble_speed=si;
77 } else if(strcmp(field, "transm_source_type")==0) {
79 } else if(strcmp(field, "distance_scanned")==0) {
81 } else if(strcmp(field, "transaxial_fov")==0) {
82 h->transaxial_fov=f;
83 } else if(strcmp(field, "angular_compression")==0) {
85 } else if(strcmp(field, "coin_samp_mode")==0) {
86 h->coin_samp_mode=si;
87 } else if(strcmp(field, "axial_samp_mode")==0) {
88 h->axial_samp_mode=si;
89 } else if(strcmp(field, "ecat_calibration_factor")==0) {
91 } else if(strcmp(field, "calibration_units")==0) {
93 } else if(strcmp(field, "calibration_units_label")==0) {
95 } else if(strcmp(field, "compression_code")==0) {
96 h->compression_code=si;
97 } else if(strcmp(field, "study_type")==0) {
98 strlcpy(h->study_type, value, 12);
99 } else if(strcmp(field, "patient_id")==0) {
100 strlcpy(h->patient_id, value, 16);
101 } else if(strcmp(field, "patient_name")==0) {
102 strlcpy(h->patient_name, value, 32);
103 } else if(strcmp(field, "patient_sex")==0) {
104 h->patient_sex=value[0];
105 } else if(strcmp(field, "patient_dexterity")==0) {
106 h->patient_dexterity=value[0];
107 } else if(strcmp(field, "patient_age")==0) {
108 h->patient_age=f;
109 } else if(strcmp(field, "patient_height")==0) {
110 h->patient_height=f;
111 } else if(strcmp(field, "patient_weight")==0) {
112 h->patient_weight=f;
113 } else if(strcmp(field, "patient_birth_date")==0) {
114 struct tm st;
115 time_t timet;
116 timet=time(NULL); gmtime_r(&timet, &st);
117 if(sscanf(value, "%d-%d-%d", &yy, &mm, &dd)!=3) return(2);
118 st.tm_mday=dd; st.tm_mon=mm-1; st.tm_year=yy-1900;
119 st.tm_hour=12; st.tm_min=0; st.tm_sec=0; st.tm_isdst=-1;
121 } else if(strcmp(field, "physician_name")==0) {
122 strlcpy(h->physician_name, value, 32);
123 } else if(strcmp(field, "operator_name")==0) {
124 strlcpy(h->operator_name, value, 32);
125 } else if(strcmp(field, "study_description")==0) {
126 strlcpy(h->study_description, value, 32);
127 } else if(strcmp(field, "acquisition_type")==0) {
128 h->acquisition_type=si;
129 } else if(strcmp(field, "patient_orientation")==0) {
131 } else if(strcmp(field, "facility_name")==0) {
132 strlcpy(h->facility_name, value, 20);
133 } else if(strcmp(field, "num_planes")==0) {
134 h->num_planes=si;
135 } else if(strcmp(field, "num_frames")==0) {
136 h->num_frames=si;
137 } else if(strcmp(field, "num_gates")==0) {
138 h->num_gates=si;
139 } else if(strcmp(field, "num_bed_pos")==0) {
140 h->num_bed_pos=si;
141 } else if(strcmp(field, "init_bed_position")==0) {
143 } else if(strcmp(field, "bed_position")==0) {
144 sscanf(value, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
145 h->bed_position+0, h->bed_position+1, h->bed_position+2,
146 h->bed_position+3, h->bed_position+4, h->bed_position+5,
147 h->bed_position+6, h->bed_position+7, h->bed_position+8,
148 h->bed_position+9, h->bed_position+10, h->bed_position+11,
149 h->bed_position+12, h->bed_position+13, h->bed_position+14
150 );
151 } else if(strcmp(field, "plane_separation")==0) {
152 h->plane_separation=f;
153 } else if(strcmp(field, "lwr_sctr_thres")==0) {
154 h->lwr_sctr_thres=si;
155 } else if(strcmp(field, "lwr_true_thres")==0) {
156 h->lwr_true_thres=si;
157 } else if(strcmp(field, "upr_true_thres")==0) {
158 h->upr_true_thres=si;
159 } else if(strcmp(field, "user_process_code")==0) {
160 strlcpy(h->user_process_code, value, 10);
161 } else if(strcmp(field, "acquisition_mode")==0) {
162 h->acquisition_mode=si;
163 } else if(strcmp(field, "bin_size")==0) {
164 h->bin_size=f;
165 } else if(strcmp(field, "branching_fraction")==0) {
167 } else if(strcmp(field, "dose_start_time")==0) {
168 struct tm stm;
169 if(get_datetime(value, &stm, verbose-1)!=0) return(2);
170 h->dose_start_time=timegm(&stm);
171 } else if(strcmp(field, "dosage")==0) {
172 h->dosage=f;
173 } else if(strcmp(field, "well_counter_corr_factor")==0) {
175 } else if(strcmp(field, "data_units")==0) {
176 strlcpy(h->data_units, value, 32);
177 } else if(strcmp(field, "septa_state")==0) {
178 h->septa_state=si;
179 } else if(strncasecmp(field, "FILL_CTI", 8)==0) {
180 char *cptr;
181 cptr=strtok(value, " \t,;\n\r");
182 for(int i=0; i<6; i++) {
183 if(cptr==NULL) break;
184 h->fill_cti[i]=(short int)atoi(cptr);
185 cptr=strtok(NULL, " \t,;\n\r");
186 }
187 } else
188 return(1);
189
190 return(0);
191}
int get_datetime(char *str, struct tm *date, int verbose)
Definition datetime.c:322
short int file_type
short int compression_code
float bed_position[15]
short int system_type
char facility_name[20]
short int num_frames
char operator_name[32]
short int coin_samp_mode
char data_units[32]
char magic_number[14]
float well_counter_corr_factor
char study_type[12]
char user_process_code[10]
short int angular_compression
short int calibration_units
char patient_name[32]
short int fill_cti[6]
short int septa_state
short int num_gates
short int num_planes
short int lwr_true_thres
char physician_name[32]
short int wobble_speed
short int acquisition_mode
short int calibration_units_label
char serial_number[10]
short int num_bed_pos
float ecat_calibration_factor
short int sw_version
short int transm_source_type
short int acquisition_type
char study_description[32]
short int axial_samp_mode
char patient_id[16]
char radiopharmaceutical[32]
short int patient_orientation
short int upr_true_thres
short int lwr_sctr_thres
char original_file_name[32]

Referenced by ecat7MainheaderFromIFT().

◆ ecat7EditSHeader()

int ecat7EditSHeader ( ECAT7_scanheader * h,
char * field,
char * value,
int verbose )
extern

Edit ECAT 7 3Dscan header.

Returns
Returns 0, if ok, and 1 or 2, if field name or or value is invalid.
Parameters
hPointer to ECAT 7 3D scan header structure
fieldField name to be changed
valueNew value for the field
verboseVerbose level; if <=0, then nothing is printed into stdout

Definition at line 199 of file ecat7h.c.

208 {
209 int i, ii;
210 short int si;
211 float f;
212 char *cptr;
213
214 if(verbose>0) printf("ecat7EditSHeader('%s', '%s')\n", field, value);
215
216 si=atoi(value); ii=atoi(value); f=atof(value);
217
218 if(strcasecmp(field, "DATA_TYPE")==0) {
219 h->data_type=si;
220 } else if(strcasecmp(field, "NUM_DIMENSIONS")==0) {
221 h->num_dimensions=si;
222 } else if(strcasecmp(field, "NUM_R_ELEMENTS")==0) {
223 h->num_r_elements=si;
224 } else if(strcasecmp(field, "NUM_ANGLES")==0) {
225 h->num_angles=si;
226 } else if(strcasecmp(field, "CORRECTIONS_APPLIED")==0) {
228 } else if(strncasecmp(field, "NUM_Z_ELEMENTS", 14)==0) {
229 cptr=strtok(value, " \t,;\n\r");
230 for(i=0; i<64; i++) {
231 if(cptr==NULL) break;
232 h->num_z_elements[i]=(short int)atoi(cptr);
233 cptr=strtok(NULL, " \t,;\n\r");
234 }
235 } else if(strcasecmp(field, "RING_DIFFERENCE")==0) {
236 h->ring_difference=si;
237 } else if(strcasecmp(field, "STORAGE_ORDER")==0) {
238 h->storage_order=si;
239 } else if(strcasecmp(field, "AXIAL_COMPRESSION")==0) {
240 h->axial_compression=si;
241 } else if(strcasecmp(field, "X_RESOLUTION")==0) {
242 h->x_resolution=f;
243 } else if(strcasecmp(field, "V_RESOLUTION")==0) {
244 h->v_resolution=f;
245 } else if(strcasecmp(field, "Z_RESOLUTION")==0) {
246 h->z_resolution=f;
247 } else if(strcasecmp(field, "W_RESOLUTION")==0) {
248 h->w_resolution=f;
249 } else if(strncasecmp(field, "FILL_GATE", 9)==0) {
250 cptr=strtok(value, " \t,;\n\r");
251 for(i=0; i<6; i++) {
252 if(cptr==NULL) break;
253 h->fill_gate[i]=(short int)atoi(cptr);
254 cptr=strtok(NULL, " \t,;\n\r");
255 }
256 } else if(strcasecmp(field, "GATE_DURATION")==0) {
257 h->gate_duration=ii;
258 } else if(strcasecmp(field, "R_WAVE_OFFSET")==0) {
259 h->r_wave_offset=ii;
260 } else if(strcasecmp(field, "NUM_ACCEPTED_BEATS")==0) {
261 h->num_accepted_beats=ii;
262 } else if(strcasecmp(field, "SCALE_FACTOR")==0) {
263 h->scale_factor=f;
264 } else if(strcasecmp(field, "SCAN_MIN")==0) {
265 h->scan_min=si;
266 } else if(strcasecmp(field, "SCAN_MAX")==0) {
267 h->scan_max=si;
268 } else if(strcasecmp(field, "PROMPTS")==0) {
269 h->prompts=ii;
270 } else if(strcasecmp(field, "DELAYED")==0) {
271 h->delayed=ii;
272 } else if(strcasecmp(field, "MULTIPLES")==0) {
273 h->multiples=ii;
274 } else if(strcasecmp(field, "NET_TRUES")==0) {
275 h->net_trues=ii;
276 } else if(strcasecmp(field, "TOT_AVG_COR")==0) {
277 h->tot_avg_cor=f;
278 } else if(strcasecmp(field, "TOT_AVG_UNCOR")==0) {
279 h->tot_avg_uncor=f;
280 } else if(strcasecmp(field, "TOTAL_COIN_RATE")==0) {
281 h->total_coin_rate=ii;
282 } else if(strcasecmp(field, "FRAME_START_TIME")==0) {
283 h->frame_start_time=ii;
284 } else if(strcasecmp(field, "FRAME_DURATION")==0) {
285 h->frame_duration=ii;
286 } else if(strcasecmp(field, "DEADTIME_CORRECTION_FACTOR")==0) {
288 } else if(strncasecmp(field, "FILL_CTI", 8)==0) {
289 cptr=strtok(value, " \t,;\n\r");
290 for(i=0; i<90; i++) {
291 if(cptr==NULL) break;
292 h->fill_cti[i]=(short int)atoi(cptr);
293 cptr=strtok(NULL, " \t,;\n\r");
294 }
295 } else if(strncasecmp(field, "FILL_USER", 9)==0) {
296 cptr=strtok(value, " \t,;\n\r");
297 for(i=0; i<50; i++) {
298 if(cptr==NULL) break;
299 h->fill_user[i]=(short int)atoi(cptr);
300 cptr=strtok(NULL, " \t,;\n\r");
301 }
302 } else if(strncasecmp(field, "UNCOR_SINGLES", 13)==0) {
303 cptr=strtok(value, " \t,;\n\r");
304 for(i=0; i<128; i++) {
305 if(cptr==NULL) break;
306 h->fill_user[i]=(float)atof(cptr);
307 cptr=strtok(NULL, " \t,;\n\r");
308 }
309 } else
310 return(1);
311 return(0);
312}
short int scan_min
short int num_r_elements
short int num_angles
short int data_type
float deadtime_correction_factor
short int fill_cti[90]
short int num_dimensions
short int axial_compression
short int fill_gate[6]
short int storage_order
short int scan_max
short int num_z_elements[64]
short int fill_user[50]
short int ring_difference
short int corrections_applied

Referenced by ecat7WriteSubheaderFromIFT().

◆ ecat7EditVHeader()

int ecat7EditVHeader ( ECAT7_imageheader * h,
char * field,
char * value,
int verbose )
extern

Edit ECAT 7 image volume header.

Returns
Returns 0, if ok, and 1 or 2, if field name or or value is invalid.
Parameters
hPointer to ECAT 7 image volume header structure
fieldField name to be changed
valueNew value for the field
verboseVerbose level; if <=0, then nothing is printed into stdout

Definition at line 320 of file ecat7h.c.

329 {
330 int ii;
331 short int si;
332 float f;
333
334 if(verbose>0) printf("ecat7EditVHeader('%s', '%s')\n", field, value);
335
336 si=atoi(value); ii=atoi(value); f=atof(value);
337
338 if(strcasecmp(field, "DATA_TYPE")==0) {
339 h->data_type=si;
340 } else if(strcasecmp(field, "NUM_DIMENSIONS")==0) {
341 h->num_dimensions=si;
342 } else if(strcasecmp(field, "X_DIMENSION")==0) {
343 h->x_dimension=si;
344 } else if(strcasecmp(field, "Y_DIMENSION")==0) {
345 h->y_dimension=si;
346 } else if(strcasecmp(field, "Z_DIMENSION")==0) {
347 h->z_dimension=si;
348 } else if(strcasecmp(field, "X_OFFSET")==0) {
349 h->x_offset=f;
350 } else if(strcasecmp(field, "Y_OFFSET")==0) {
351 h->y_offset=f;
352 } else if(strcasecmp(field, "Z_OFFSET")==0) {
353 h->z_offset=f;
354 } else if(strcasecmp(field, "RECON_ZOOM")==0) {
355 h->recon_zoom=f;
356 } else if(strcasecmp(field, "SCALE_FACTOR")==0) {
357 h->scale_factor=f;
358 } else if(strcasecmp(field, "IMAGE_MIN")==0) {
359 h->image_min=si;
360 } else if(strcasecmp(field, "IMAGE_MAX")==0) {
361 h->image_max=si;
362 } else if(strcasecmp(field, "X_PIXEL_SIZE")==0) {
363 h->x_pixel_size=f;
364 } else if(strcasecmp(field, "Y_PIXEL_SIZE")==0) {
365 h->y_pixel_size=f;
366 } else if(strcasecmp(field, "Z_PIXEL_SIZE")==0) {
367 h->z_pixel_size=f;
368 } else if(strcasecmp(field, "FRAME_DURATION")==0) {
369 h->frame_duration=ii;
370 } else if(strcasecmp(field, "FRAME_START_TIME")==0) {
371 h->frame_start_time=ii;
372 } else if(strcasecmp(field, "FILTER_CODE")==0) {
373 h->filter_code=si;
374 } else if(strcasecmp(field, "X_RESOLUTION")==0) {
375 h->x_resolution=f;
376 } else if(strcasecmp(field, "Y_RESOLUTION")==0) {
377 h->y_resolution=f;
378 } else if(strcasecmp(field, "Z_RESOLUTION")==0) {
379 h->z_resolution=f;
380 } else if(strcasecmp(field, "NUM_R_ELEMENTS")==0) {
381 h->num_r_elements=f;
382 } else if(strcasecmp(field, "NUM_ANGLES")==0) {
383 h->num_angles=f;
384 } else if(strcasecmp(field, "Z_ROTATION_ANGLE")==0) {
385 h->z_rotation_angle=f;
386 } else if(strcasecmp(field, "DECAY_CORR_FCTR")==0) {
387 h->decay_corr_fctr=f;
388 } else if(strcasecmp(field, "PROCESSING_CODE")==0) {
389 h->processing_code=ii;
390 } else if(strcasecmp(field, "GATE_DURATION")==0) {
391 h->gate_duration=ii;
392 } else if(strcasecmp(field, "R_WAVE_OFFSET")==0) {
393 h->r_wave_offset=ii;
394 } else if(strcasecmp(field, "NUM_ACCEPTED_BEATS")==0) {
395 h->num_accepted_beats=ii;
396 } else if(strcasecmp(field, "FILTER_CUTOFF_FREQUENCY")==0) {
398 } else if(strcasecmp(field, "FILTER_RESOLUTION")==0) {
400 } else if(strcasecmp(field, "FILTER_RAMP_SLOPE")==0) {
402 } else if(strcasecmp(field, "FILTER_ORDER")==0) {
403 h->filter_order=f;
404 } else if(strcasecmp(field, "FILTER_SCATTER_FRACTION")==0) {
406 } else if(strcasecmp(field, "FILTER_SCATTER_SLOPE")==0) {
408 } else if(strcasecmp(field, "ANNOTATION")==0) {
409 strlcpy(h->annotation, value, 40);
410 } else if(strcasecmp(field, "MT_1_1")==0) {
411 h->mt_1_1=f;
412 } else if(strcasecmp(field, "MT_1_2")==0) {
413 h->mt_1_2=f;
414 } else if(strcasecmp(field, "MT_1_3")==0) {
415 h->mt_1_3=f;
416 } else if(strcasecmp(field, "MT_2_1")==0) {
417 h->mt_2_1=f;
418 } else if(strcasecmp(field, "MT_2_2")==0) {
419 h->mt_2_2=f;
420 } else if(strcasecmp(field, "MT_2_3")==0) {
421 h->mt_2_3=f;
422 } else if(strcasecmp(field, "MT_3_1")==0) {
423 h->mt_3_1=f;
424 } else if(strcasecmp(field, "MT_3_2")==0) {
425 h->mt_3_2=f;
426 } else if(strcasecmp(field, "MT_3_3")==0) {
427 h->mt_3_3=f;
428 } else if(strcasecmp(field, "RFILTER_CUTOFF")==0) {
429 h->rfilter_cutoff=f;
430 } else if(strcasecmp(field, "RFILTER_RESOLUTION")==0) {
432 } else if(strcasecmp(field, "RFILTER_CODE")==0) {
433 h->rfilter_code=si;
434 } else if(strcasecmp(field, "RFILTER_ORDER")==0) {
435 h->rfilter_order=si;
436 } else if(strcasecmp(field, "ZFILTER_CUTOFF")==0) {
437 h->zfilter_cutoff=f;
438 } else if(strcasecmp(field, "ZFILTER_RESOLUTION")==0) {
440 } else if(strcasecmp(field, "ZFILTER_CODE")==0) {
441 h->zfilter_code=si;
442 } else if(strcasecmp(field, "ZFILTER_ORDER")==0) {
443 h->zfilter_order=si;
444 } else if(strcasecmp(field, "MT_1_4")==0) {
445 h->mt_1_4=f;
446 } else if(strcasecmp(field, "MT_2_4")==0) {
447 h->mt_2_4=f;
448 } else if(strcasecmp(field, "MT_3_4")==0) {
449 h->mt_3_4=f;
450 } else if(strcasecmp(field, "SCATTER_TYPE")==0) {
451 h->scatter_type=si;
452 } else if(strcasecmp(field, "RECON_TYPE")==0) {
453 h->recon_type=si;
454 } else if(strcasecmp(field, "RECON_VIEWS")==0) {
455 h->recon_views=si;
456 } else if(strncasecmp(field, "FILL_CTI", 8)==0) {
457 char *cptr;
458 cptr=strtok(value, " \t,;\n\r");
459 for(int i=0; i<87; i++) {
460 if(cptr==NULL) break;
461 h->fill_cti[i]=(short int)atoi(cptr);
462 cptr=strtok(NULL, " \t,;\n\r");
463 }
464 } else if(strncasecmp(field, "FILL_USER", 9)==0) {
465 char *cptr;
466 cptr=strtok(value, " \t,;\n\r");
467 for(int i=0; i<50; i++) {
468 if(cptr==NULL) break;
469 h->fill_user[i]=(short int)atoi(cptr);
470 cptr=strtok(NULL, " \t,;\n\r");
471 }
472 } else
473 return(1);
474
475 return(0);
476}
short int fill_cti[87]
float filter_scatter_fraction
short int filter_code
short int image_max
short int image_min
short int zfilter_order
short int fill_user[49]
short int rfilter_code
float filter_cutoff_frequency
short int zfilter_code
short int filter_order
short int y_dimension
short int z_dimension
short int recon_type
short int scatter_type
short int recon_views
short int num_dimensions
short int rfilter_order
short int x_dimension
short int data_type

Referenced by ecat7WriteSubheaderFromIFT().

◆ ecat7EmptyMatlist()

void ecat7EmptyMatlist ( ECAT7_MATRIXLIST * mlist)
extern

Free memory allocated for ECAT matrix list.

Parameters
mlisttarget matrix list that has allocated memory

Definition at line 26 of file ecat7ml.c.

26 {
27 if(mlist->matrixSpace>0) free((char*)(mlist->matdir));
28 mlist->matrixSpace=mlist->matrixNr=0;
29}

Referenced by ecat7PrintSubheader(), ecat7ReadHeaders(), ecat7ReadMatlist(), ecat7WriteHeaders(), imgReadEcat7(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7EnterMatrix()

int ecat7EnterMatrix ( FILE * fp,
int matrix_id,
int block_nr )
extern

Prepare matrix list for additional matrix data and return block number for matrix header. Directory records are written in big endian byte order. Set block_nr to the number of data blocks + (nr of header blocks - 1)

Parameters
fpfile pointer
matrix_idmatrix identifier coding
block_nrmatrix number [1..number of matrixes]
Returns
returns the block number for matrix header, -1 if invalid input, -2 if first directory block is not found, -3 if failed to read first block, -9 if other directory block is not found, -10 if failed to read other block, -11 if place for new directory block is not found, -12 if failed clear new block, -15 if place for new directory block is not found, -16 if failed to write into new block

Definition at line 147 of file ecat7ml.c.

147 {
148 unsigned int i=0, dirblk, little, busy=1, nxtblk=0, oldsize;
149 /*unsigned*/ int dirbuf[MatBLKSIZE/4];
150
151 if(ECAT7_TEST) printf("ecat7EnterMatrix(fp, %d, %d)\n", matrix_id, block_nr);
152 /* Check the input */
153 if(fp==NULL || matrix_id<1 || block_nr<1) return(-1);
154 /* Is this a little endian machine? */
155 little=little_endian();
156 /* Read first directory record block */
157 dirblk=MatFirstDirBlk;
158 fseek(fp, (dirblk-1)*MatBLKSIZE, SEEK_SET);
159 if(ftell(fp)!=(int)(dirblk-1)*MatBLKSIZE) return(-2);
160 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-3);
161 /* Byte order conversion for ints in little endian platforms */
162 if(little) swawbip(dirbuf, MatBLKSIZE);
163 /* Read through the existing directory records */
164 while(busy) {
165 /* Go through the directory entries in this record */
166 for(i=4, nxtblk=dirblk+1; i<MatBLKSIZE/4; i+=4) {
167 oldsize=dirbuf[i+2]-dirbuf[i+1]+1;
168 if(dirbuf[i]==0) { /* Check for end of matrix list */
169 busy=0; break;
170 } else if(dirbuf[i]==matrix_id) { /* Maybe this matrix already exists? */
171 /* yes it does; is old data smaller? */
172 if(oldsize<(unsigned int)block_nr) {
173 /* it was smaller, so do not use it, but mark it deleted */
174 dirbuf[i] = 0xFFFFFFFF; dirbuf[i+3]=-1;
175 if(little) swawbip(dirbuf, MatBLKSIZE);
176 long long pos=(dirblk-1)*(long long)MatBLKSIZE;
177 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(-6);
178 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-7);
179 if(little) swawbip(dirbuf, MatBLKSIZE);
180 nxtblk=dirbuf[i+2]+1;
181 } else { /* old matrix size is ok */
182 nxtblk=dirbuf[i+1]; dirbuf[0]++; dirbuf[3]--; busy=0;
183 break;
184 }
185 } else { /* this is not the same matrix */
186 /* But is deleted and of same or smaller size? */
187 if(dirbuf[i+3]==-1 && (unsigned int)block_nr<=oldsize) {
188 /* yes it was, so lets recycle it */
189 dirbuf[i]=matrix_id;
190 nxtblk=dirbuf[i+1]; dirbuf[0]++; dirbuf[3]--; busy=0;
191 break;
192 }
193 /* nothing to be done with this entry */
194 nxtblk=dirbuf[i+2]+1;
195 }
196 } /* next entry in this record */
197 if(!busy) break; /* stop reading existing records */
198 /* Read the next directory record */
199 if(dirbuf[1]!=MatFirstDirBlk) {
200 /* There are more records left to read */
201 dirblk=dirbuf[1];
202 long long pos=(dirblk-1)*(long long)MatBLKSIZE;
203 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(-9);
204 if(fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-10);
205 if(little) swawbip(dirbuf, MatBLKSIZE);
206 } else {
207 /* No more records to read, so lets write a new empty one */
208 dirbuf[1]=nxtblk; /* write a pointer to the new one */
209 if(little) swawbip(dirbuf, MatBLKSIZE);
210 long long pos=(dirblk-1)*(long long)MatBLKSIZE;
211 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(-11);
212 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-12);
213 /* and then initiate the contents of the next one, but do not write it */
214 dirbuf[0]=31; dirbuf[1]=MatFirstDirBlk; dirbuf[2]=dirblk;
215 dirbuf[3]=0; dirblk=nxtblk;
216 for(i=4; i<MatBLKSIZE/4; i++) dirbuf[i]=0;
217 }
218 } /* next directory record */
219 dirbuf[i]=matrix_id;
220 dirbuf[i+1]=nxtblk;
221 dirbuf[i+2]=nxtblk+block_nr;
222 dirbuf[i+3]=1; /* mark the entry as read/write */
223 dirbuf[0]--;
224 dirbuf[3]++;
225 if(little) swawbip(dirbuf, MatBLKSIZE);
226 long long pos=(dirblk-1)*(long long)MatBLKSIZE;
227 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(-15);
228 if(fwrite(dirbuf, sizeof(int), MatBLKSIZE/4, fp) != MatBLKSIZE/4) return(-16);
229 if(ECAT7_TEST) printf("returning %d from ecat7EnterMatrix()\n", nxtblk);
230 return(nxtblk);
231}

Referenced by ecat7CopyFile(), ecat7Write2DScanMatrix(), ecat7WriteImageMatrix(), ecat7WritePolarmapMatrix(), and ecat7WriteScanMatrix().

◆ ecat7filetype()

char * ecat7filetype ( short int file_type)
extern

Returns pointer to a string describing the ECAT7 file_type

Parameters
file_typefile type code
Returns
pointer to static string

Definition at line 447 of file ecat7p.c.

449 {
450 static char *info[] = {
451 "unknown", "2D sinogram", "image-16", "attenuation correction",
452 "2D normalization", "polar map", "volume 8", "volume 16",
453 "projection 8", "projection 16", "image 8", "3D sinogram 16",
454 "3D sinogram 8", "3D normalization", "3D sinogram fit",
455 0};
456 if(file_type>=0 && file_type<=14) return((char*)info[file_type]);
457 else return((char*)info[0]);
458}

Referenced by ecat7PrintMainheader(), and imgRead().

◆ ecat7GatherMatlist()

int ecat7GatherMatlist ( ECAT7_MATRIXLIST * ml,
short int do_planes,
short int do_frames,
short int do_gates,
short int do_beds )
extern

Matrix numbers in ECAT 7 matrix list are edited, when necessary, so that plane, frame, gate and/or bed numbers are continuous, starting from one (planes, frames and gates) or from zero (beds). List order is not changed.

Parameters
mlECAT 7 matrix list, where the matrix numbers will be edited
do_planesPlane numbers are gathered together (1) or not (0)
do_framesFrame numbers are gathered together (1) or not (0)
do_gatesGate numbers are gathered together (1) or not (0)
do_bedsBed numbers are gathered together (1) or not (0)
Returns
0 if successful, 1 if invalid input, 3 failed to allocate memory

Definition at line 535 of file ecat7ml.c.

536 {
537 int i, ncurr, n;
538 ECAT7_Matval* matval;
539
540 if(ml==NULL) return(1);
541 if(ml->matrixNr<1) return(0);
542
543 /* Allocate memory for matrix values */
544 matval = (ECAT7_Matval*)calloc(ml->matrixNr,sizeof(ECAT7_Matval));
545 if(matval == NULL) return(3);
546
547 /* And get the matrix values */
548 for(i=0; i<ml->matrixNr; i++) ecat7_id_to_val(ml->matdir[i].id, matval+i);
549
550 /* Planes */
551 if(do_planes!=0) {
552 ncurr=1;
553 while(ncurr <= ml->matrixNr) {
554 /* Find any matrix with this number? */
555 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].plane==ncurr) {n=1; break;}
556 /* If yes, then go on to the next matrix number */
557 if(n==1) {ncurr++; continue;}
558 /* If not, then subtract 1 from all matrix numbers that are larger */
559 for(i=0, n=0; i<ml->matrixNr; i++)
560 if(matval[i].plane>ncurr) {
561 /*printf(" plane %d -> plane %d\n", matval[i].plane, matval[i].plane-1);*/
562 matval[i].plane--; n++;
563 }
564 /* If no larger values were found any more, then quit */
565 if(n<1) break;
566 }
567 }
568
569 /* Frames */
570 if(do_frames!=0) {
571 ncurr=1;
572 while(ncurr <= ml->matrixNr) {
573 /* Find any matrix with this number? */
574 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].frame==ncurr) {n=1; break;}
575 /* If yes, then go on to the next matrix number */
576 if(n==1) {ncurr++; continue;}
577 /* If not, then subtract 1 from all matrix numbers that are larger */
578 for(i=0, n=0; i<ml->matrixNr; i++)
579 if(matval[i].frame>ncurr) {matval[i].frame--; n++;}
580 /* If no larger values were found any more, then quit */
581 if(n<1) break;
582 }
583 }
584
585 /* Gates */
586 if(do_gates!=0) {
587 ncurr=1;
588 while(ncurr <= ml->matrixNr) {
589 /* Find any matrix with this number? */
590 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].gate==ncurr) {n=1; break;}
591 /* If yes, then go on to the next matrix number */
592 if(n==1) {ncurr++; continue;}
593 /* If not, then subtract 1 from all matrix numbers that are larger */
594 for(i=0, n=0; i<ml->matrixNr; i++)
595 if(matval[i].gate>ncurr) {matval[i].gate--; n++;}
596 /* If no larger values were found any more, then quit */
597 if(n<1) break;
598 }
599 }
600
601 /* Beds */
602 if(do_beds!=0) {
603 ncurr=1;
604 while(ncurr <= ml->matrixNr) {
605 /* Find any matrix with this number? */
606 for(i=0, n=0; i<ml->matrixNr; i++) if(matval[i].bed==ncurr) {n=1; break;}
607 /* If yes, then go on to the next matrix number */
608 if(n==1) {ncurr++; continue;}
609 /* If not, then subtract 1 from all matrix numbers that are larger */
610 for(i=0, n=0; i<ml->matrixNr; i++)
611 if(matval[i].bed>ncurr) {matval[i].bed--; n++;}
612 /* If no larger values were found any more, then quit */
613 if(n<1) break;
614 }
615 }
616
617 /* Write matrix values (possibly changed) into matrix list */
618 for(i=0; i<ml->matrixNr; i++) ml->matdir[i].id=ecat7_val_to_id(
619 matval[i].frame, matval[i].plane,
620 matval[i].gate, matval[i].data,
621 matval[i].bed);
622 free(matval);
623 return(0);
624}
int ecat7_val_to_id(int frame, int plane, int gate, int data, int bed)
Definition ecat7ml.c:245

Referenced by ecatFixMatrixlist(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7GetMatrixBlockSize()

int ecat7GetMatrixBlockSize ( ECAT7_MATRIXLIST * mlist,
int * blk_nr )
extern

Calculate the size of one data matrix in ECAT7 file matrix list, and check that the size is same in all matrices.

Parameters
mlistEcat7 matrix list; note that this list is here sorted by planes
blk_nrnumber of blocks will be put here; NULL if not needed
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 418 of file ecat7ml.c.

418 {
419 int m, prev_blk, blk;
420
421 /* Check input */
422 if(mlist==NULL) return STATUS_FAULT;
423 if(blk_nr!=NULL) *blk_nr=0;
424
425 /* Calculate the size of first data matrix */
426 m=0; prev_blk=blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
427 for(m=1; m<mlist->matrixNr; m++) {
428 blk=mlist->matdir[m].endblk - mlist->matdir[m].strtblk;
429 if(blk!=prev_blk) return STATUS_VARMATSIZE;
430 else prev_blk=blk;
431 }
432 if(blk_nr!=NULL) *blk_nr=blk;
433 return STATUS_OK;
434}

Referenced by imgReadEcat7Header().

◆ ecat7GetNums()

int ecat7GetNums ( ECAT7_MATRIXLIST * ml,
ECAT7_mainheader * mh,
FILE * fp,
short int * num_planes,
short int * num_frames,
short int * num_gates,
short int * num_bed_pos )
extern

Read the maximum plane, frame, gate and bed number from matrixlist. In case of 3D formats, num_planes is checked from the first subheader.

Parameters
mlPointer to matrixlist
mhPointer to mainheader
fpFile pointer to ECAT7 file opened in binary mode
num_planesnum_planes will be put here; NULL if not needed to be read
num_framesnum_planes will be put here; NULL if not needed to be read
num_gatesnum_planes will be put here; NULL if not needed to be read
num_bed_posnum_planes will be put here; NULL if not needed to be read
Returns
0 if successful, 1 if invalid input, 2 if no matrixes, 3 failed to allocate memory, 5 if failed to read image/scan header information

Definition at line 452 of file ecat7ml.c.

453 {
454 int i, nmax, ret=0;
457 ECAT7_Matval* matval;
458
459 if(ml==NULL) return(1);
460 if(ml->matrixNr<1) return(2);
461
462 /* Allocate memory for matrix values */
463 matval = (ECAT7_Matval*)calloc(ml->matrixNr,sizeof(ECAT7_Matval));
464 if(matval == NULL) return(3);
465
466 /* And get the matrix values */
467 for(i=0; i<ml->matrixNr; i++) ecat7_id_to_val(ml->matdir[i].id, matval+i);
468
469 /* Planes */
470 if(num_planes!=NULL) {
471 nmax=matval[0].plane;
472 for(i=1; i<ml->matrixNr; i++) if(matval[i].plane>nmax) nmax=matval[i].plane;
473 *num_planes=nmax;
474 }
475 /* Frames */
476 if(num_frames!=NULL) {
477 nmax=matval[0].frame;
478 for(i=1; i<ml->matrixNr; i++) if(matval[i].frame>nmax) nmax=matval[i].frame;
479 *num_frames=nmax;
480 }
481 /* Gates */
482 if(num_gates!=NULL) {
483 nmax=matval[0].gate;
484 for(i=1; i<ml->matrixNr; i++) if(matval[i].gate>nmax) nmax=matval[i].gate;
485 *num_gates=nmax;
486 }
487 /* Beds */
488 if(num_bed_pos!=NULL) {
489 nmax=matval[0].bed;
490 for(i=1; i<ml->matrixNr; i++) if(matval[i].bed>nmax) nmax=matval[i].bed;
491 *num_bed_pos=nmax;
492 }
493
494 /* Check the num_planes from the first subheader in 3D formats */
495 if(num_planes!=NULL && *num_planes<=1) switch(mh->file_type) {
496 case ECAT7_VOLUME8:
497 case ECAT7_VOLUME16:
498 ret=ecat7ReadImageheader(fp, ml->matdir[0].strtblk, &ih);
499 if(ret!=0) {
500 free(matval);
501 return(5);
502 }
503 if(ih.num_dimensions>2 && ih.z_dimension>1) *num_planes=ih.z_dimension;
504 break;
505 case ECAT7_3DSCAN:
506 case ECAT7_3DSCAN8:
507 case ECAT7_3DSCANFIT:
508 ret=ecat7ReadScanheader(fp, ml->matdir[0].strtblk, &sh);
509 if(ret!=0) {
510 free(matval);
511 return(5);
512 }
513 for(i=0, *num_planes=0; i<64; i++) *num_planes+=sh.num_z_elements[i];
514 break;
515 }
516 free(matval);
517 return(0);
518}
int ecat7ReadScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition ecat7r.c:536
int ecat7ReadImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition ecat7r.c:162
#define ECAT7_VOLUME8
#define ECAT7_3DSCAN
#define ECAT7_3DSCAN8
#define ECAT7_3DSCANFIT
#define ECAT7_VOLUME16

Referenced by ecatFixMatrixlist().

◆ ecat7GetPlaneAndFrameNr()

int ecat7GetPlaneAndFrameNr ( ECAT7_MATRIXLIST * mlist,
ECAT7_mainheader * h,
int * plane_nr,
int * frame_nr )
extern

Calculate the number of planes and frames/gates from ECAT7 matrix list. Check that all planes have equal nr of frames/gates, that frames/gates are sequentally numbered.

Parameters
mlistEcat7 matrix list; note that this list is here sorted by planes
hEcat7 main header structure
plane_nrNumber of planes will be put here; NULL if not needed [1..number of planes, or NULL]
frame_nrNumber of frames/gates will be put here; NULL if not needed [1..number of frames, or NULL]
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error. Note that if this is 3D image volume or sinogram, then the returned plane_nr will be one, and the actual Z dim must be read from subheader.

Definition at line 372 of file ecat7ml.c.

372 {
373 ECAT7_Matval matval;
374 int m, plane, frame, prev_plane, prev_frame, fnr, pnr;
375
376 /* Check input */
377 if(mlist==NULL) return STATUS_FAULT;
378 if(plane_nr!=NULL) *plane_nr=0;
379 if(frame_nr!=NULL) *frame_nr=0;
380
381 /* Sort matrices by plane so that following computation works */
383
384 prev_plane=plane=-1; prev_frame=frame=-1;
385 fnr=pnr=0;
386 for(m=0; m<mlist->matrixNr; m++) {
387 ecat7_id_to_val(mlist->matdir[m].id, &matval);
388 plane=matval.plane;
389 if(h->num_frames>=h->num_gates)
390 frame=matval.frame;
391 else
392 frame=matval.gate;
393 if(plane!=prev_plane) {
394 fnr=1; pnr++;
395 } else {
396 fnr++;
397 if(prev_frame>0 && frame!=prev_frame+1) return STATUS_MISSINGMATRIX;
398 }
399 prev_plane=plane; prev_frame=frame;
400 } /* next matrix */
401 if(fnr*pnr != mlist->matrixNr) return STATUS_MISSINGMATRIX;
402 if(plane_nr!=NULL) *plane_nr=pnr;
403 if(frame_nr!=NULL) *frame_nr=fnr;
404 return STATUS_OK;
405}
void ecat7SortMatlistByPlane(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:277

Referenced by imgReadEcat7Header().

◆ ecat7ImageheaderToIFT()

int ecat7ImageheaderToIFT ( ECAT7_imageheader * h,
IFT * ift,
int verbose )
extern

Copy ECAT 7 image header into IFT structure.

Returns
Returns STATUS_OK when successful.
Parameters
hPointer to source ECAT 7 image header
iftPointer to initiated IFT structure
verboseVerbose level

Definition at line 251 of file ecat7ift.c.

258 {
259 int i;
260 char tmp[1024], tmp2[32];
261
262 if(verbose>0) printf("%s(h, ift)\n", __func__);
263 if(h==NULL || ift==NULL) return STATUS_FAULT;
264 if(h->data_type<=0) return STATUS_UNKNOWNFORMAT;
265
266 sprintf(tmp, "%d", h->data_type);
267 if(iftPut(ift, "data_type", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
268 sprintf(tmp, "%d", h->num_dimensions);
269 if(iftPut(ift, "num_dimensions", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
270 sprintf(tmp, "%d", h->x_dimension);
271 if(iftPut(ift, "x_dimension", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
272 sprintf(tmp, "%d", h->y_dimension);
273 if(iftPut(ift, "y_dimension", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
274 sprintf(tmp, "%d", h->z_dimension);
275 if(iftPut(ift, "z_dimension", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
276 sprintf(tmp, "%g", h->x_offset);
277 if(iftPut(ift, "x_offset", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
278 sprintf(tmp, "%g", h->y_offset);
279 if(iftPut(ift, "y_offset", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
280 sprintf(tmp, "%g", h->z_offset);
281 if(iftPut(ift, "z_offset", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
282 sprintf(tmp, "%g", h->recon_zoom);
283 if(iftPut(ift, "recon_zoom", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
284 sprintf(tmp, "%E", h->scale_factor);
285 if(iftPut(ift, "scale_factor", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
286 sprintf(tmp, "%d", h->image_min);
287 if(iftPut(ift, "image_min", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
288 sprintf(tmp, "%d", h->image_max);
289 if(iftPut(ift, "image_max", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
290 sprintf(tmp, "%g", h->x_pixel_size);
291 if(iftPut(ift, "x_pixel_size", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
292 sprintf(tmp, "%g", h->y_pixel_size);
293 if(iftPut(ift, "y_pixel_size", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
294 sprintf(tmp, "%g", h->z_pixel_size);
295 if(iftPut(ift, "z_pixel_size", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
296 sprintf(tmp, "%d", h->frame_duration);
297 if(iftPut(ift, "frame_duration", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
298 sprintf(tmp, "%d", h->frame_start_time);
299 if(iftPut(ift, "frame_start_time", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
300 sprintf(tmp, "%d", h->filter_code);
301 if(iftPut(ift, "filter_code", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
302 sprintf(tmp, "%g", h->x_resolution);
303 if(iftPut(ift, "x_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
304 sprintf(tmp, "%g", h->y_resolution);
305 if(iftPut(ift, "y_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
306 sprintf(tmp, "%g", h->z_resolution);
307 if(iftPut(ift, "z_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
308 sprintf(tmp, "%g", h->num_r_elements);
309 if(iftPut(ift, "num_r_elements", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
310 sprintf(tmp, "%g", h->num_angles);
311 if(iftPut(ift, "num_angles", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
312 sprintf(tmp, "%g", h->z_rotation_angle);
313 if(iftPut(ift, "z_rotation_angle", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
314 sprintf(tmp, "%g", h->decay_corr_fctr);
315 if(iftPut(ift, "decay_corr_fctr", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
316 sprintf(tmp, "%d", h->processing_code);
317 if(iftPut(ift, "processing_code", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
318 sprintf(tmp, "%d", h->gate_duration);
319 if(iftPut(ift, "gate_duration", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
320 sprintf(tmp, "%d", h->r_wave_offset);
321 if(iftPut(ift, "r_wave_offset", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
322 sprintf(tmp, "%d", h->num_accepted_beats);
323 if(iftPut(ift, "num_accepted_beats", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
324 sprintf(tmp, "%E", h->filter_cutoff_frequency);
325 if(iftPut(ift, "filter_cutoff_frequency", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
326 sprintf(tmp, "%E", h->filter_resolution);
327 if(iftPut(ift, "filter_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
328 sprintf(tmp, "%E", h->filter_ramp_slope);
329 if(iftPut(ift, "filter_ramp_slope", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
330 sprintf(tmp, "%d", h->filter_order);
331 if(iftPut(ift, "filter_order", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
332 sprintf(tmp, "%E", h->filter_scatter_fraction);
333 if(iftPut(ift, "filter_scatter_fraction", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
334 sprintf(tmp, "%E", h->filter_scatter_slope);
335 if(iftPut(ift, "filter_scatter_slope", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
336 if(iftPut(ift, "annotation", h->annotation, NULL, 0)!=0) return STATUS_UNSUPPORTED;
337 sprintf(tmp, "%g", h->mt_1_1);
338 if(iftPut(ift, "mt_1_1", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
339 sprintf(tmp, "%g", h->mt_1_2);
340 if(iftPut(ift, "mt_1_2", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
341 sprintf(tmp, "%g", h->mt_1_3);
342 if(iftPut(ift, "mt_1_3", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
343 sprintf(tmp, "%g", h->mt_2_1);
344 if(iftPut(ift, "mt_2_1", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
345 sprintf(tmp, "%g", h->mt_2_2);
346 if(iftPut(ift, "mt_2_2", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
347 sprintf(tmp, "%g", h->mt_2_3);
348 if(iftPut(ift, "mt_2_3", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
349 sprintf(tmp, "%g", h->mt_3_1);
350 if(iftPut(ift, "mt_3_1", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
351 sprintf(tmp, "%g", h->mt_3_2);
352 if(iftPut(ift, "mt_3_2", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
353 sprintf(tmp, "%g", h->mt_3_3);
354 if(iftPut(ift, "mt_3_3", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
355 sprintf(tmp, "%g", h->rfilter_cutoff);
356 if(iftPut(ift, "rfilter_cutoff", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
357 sprintf(tmp, "%g", h->rfilter_resolution);
358 if(iftPut(ift, "rfilter_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
359 sprintf(tmp, "%d", h->rfilter_code);
360 if(iftPut(ift, "rfilter_code", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
361 sprintf(tmp, "%d", h->rfilter_order);
362 if(iftPut(ift, "rfilter_order", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
363 sprintf(tmp, "%g", h->zfilter_cutoff);
364 if(iftPut(ift, "zfilter_cutoff", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
365 sprintf(tmp, "%g", h->zfilter_resolution);
366 if(iftPut(ift, "zfilter_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
367 sprintf(tmp, "%d", h->zfilter_code);
368 if(iftPut(ift, "zfilter_code", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
369 sprintf(tmp, "%d", h->zfilter_order);
370 if(iftPut(ift, "zfilter_order", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
371 sprintf(tmp, "%g", h->mt_1_4);
372 if(iftPut(ift, "mt_1_4", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
373 sprintf(tmp, "%g", h->mt_2_4);
374 if(iftPut(ift, "mt_2_4", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
375 sprintf(tmp, "%g", h->mt_3_4);
376 if(iftPut(ift, "mt_3_4", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
377 sprintf(tmp, "%d", h->scatter_type);
378 if(iftPut(ift, "scatter_type", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
379 sprintf(tmp, "%d", h->recon_type);
380 if(iftPut(ift, "recon_type", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
381 sprintf(tmp, "%d", h->recon_views);
382 if(iftPut(ift, "recon_views", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
383
384 sprintf(tmp, "%d", h->fill_cti[0]);
385 for(i=1; i<87; i++) {sprintf(tmp2, " %d", h->fill_cti[i]); strcat(tmp, tmp2);}
386 if(iftPut(ift, "fill_cti", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
387
388 sprintf(tmp, "%d", h->fill_user[0]);
389 for(i=1; i<49; i++) {sprintf(tmp2, " %d", h->fill_user[i]); strcat(tmp, tmp2);}
390 if(iftPut(ift, "fill_user", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
391
392/*
393 if(iftPut(ift, "", h->, NULL)!=0) return STATUS_UNSUPPORTED;
394
395 sprintf(tmp, "%g", h->);
396 if(iftPut(ift, "", tmp, NULL)!=0) return STATUS_UNSUPPORTED;
397
398 sprintf(tmp, "%d", h->);
399 if(iftPut(ift, "", tmp, NULL)!=0) return STATUS_UNSUPPORTED;
400 */
401 return STATUS_OK;
402}
int iftPut(IFT *ift, char *key, char *value, char *cmt_type, int verbose)
Definition ift.c:82

Referenced by ecat7ReadSubheaderToIFT().

◆ ecat7InitMatlist()

void ecat7InitMatlist ( ECAT7_MATRIXLIST * mlist)
extern

Initiate ECAT matrix list. Call this once before first use.

Parameters
mlisttarget matrix list

Definition at line 15 of file ecat7ml.c.

15 {
16 mlist->matrixSpace=mlist->matrixNr=0; mlist->matdir=NULL;
17}

Referenced by ecat7PrintSubheader(), ecat7ReadHeaders(), ecat7WriteHeaders(), ecatFixMatrixlist(), imgReadEcat7(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7MainheaderFromIFT()

int ecat7MainheaderFromIFT ( ECAT7_mainheader * h,
IFT * ift,
int verbose )
extern

Copy ECAT 7 main header from IFT structure to header structure.

Returns
Returns STATUS_OK when successful.
Parameters
hPointer to target ECAT 7 main header
iftPointer to source IFT structure
verboseVerbose level

Definition at line 221 of file ecat7ift.c.

228 {
229 int ii, ret;
230
231 if(verbose>0) printf("ecat7MainheaderFromIFT(mh, ift)\n");
232 if(h==NULL || ift==NULL) return STATUS_FAULT;
233 if(verbose>5) iftWrite(ift, "stdout", 0);
234
235 for(ii=ret=0; ii<ift->keyNr; ii++) {
236 if(verbose>2) printf(" key := %s\n value := %s\n", ift->item[ii].key, ift->item[ii].value);
237 ret=ecat7EditMHeader(h, ift->item[ii].key, ift->item[ii].value, verbose-1);
238 if(ret!=0) {
239 if(verbose>0) fprintf(stderr, "Error with key '%s'\n", ift->item[ii].key);
240 break;
241 }
242 }
243 if(ret!=0) return STATUS_FAULT;
244 return STATUS_OK;
245}
int ecat7EditMHeader(ECAT7_mainheader *h, char *field, char *value, int verbose)
Definition ecat7h.c:16
int iftWrite(IFT *ift, char *filename, int verbose)
Definition iftfile.c:282
int keyNr
Definition libtpcmisc.h:270
IFT_KEY_AND_VALUE * item
Definition libtpcmisc.h:279

Referenced by ecat7WriteHeaders().

◆ ecat7MHeaderToIFT()

int ecat7MHeaderToIFT ( ECAT7_mainheader * h,
IFT * ift,
int verbose )
extern

Copy ECAT 7 mainheader into IFT struct.

Returns
Returns STATUS_OK when succesful.
Parameters
hPointer to source ECAT 7 main header
iftPointer to initiated IFT struct
verboseVerbose level

Definition at line 85 of file ecat7ift.c.

92 {
93 int i;
94 char tmp[1024], tmp2[32];
95 time_t t;
96
97 if(verbose>0) printf("ecat7MHeaderToIFT(mh, ift)\n");
98 if(h==NULL || ift==NULL) return STATUS_FAULT;
99 if(strncmp(h->magic_number, ECAT7V_MAGICNR, 7)!=0) return STATUS_UNKNOWNFORMAT;
100
101 if(iftPut(ift, "magic_number", h->magic_number, NULL, 0)!=0) return STATUS_UNSUPPORTED;
102 if(iftPut(ift, "original_file_name", h->original_file_name, NULL, 0)!=0) return STATUS_UNSUPPORTED;
103 sprintf(tmp, "%d", h->sw_version);
104 if(iftPut(ift, "sw_version", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
105 sprintf(tmp, "%d", h->system_type);
106 if(iftPut(ift, "system_type", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
107 sprintf(tmp, "%d", h->file_type);
108 if(iftPut(ift, "file_type", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
109 if(iftPut(ift, "serial_number", h->serial_number, NULL, 0)!=0) return STATUS_UNSUPPORTED;
110 t=h->scan_start_time;
111 if(!ctime_r_int(&t, tmp)) strcpy(tmp, "1970-01-01 00:00:00");
112 if(iftPut(ift, "scan_start_time", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
113 if(iftPut(ift, "isotope_name", h->isotope_name, NULL, 0)!=0) return STATUS_UNSUPPORTED;
114 sprintf(tmp, "%g", h->isotope_halflife);
115 if(iftPut(ift, "isotope_halflife", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
116 if(iftPut(ift, "radiopharmaceutical", h->radiopharmaceutical, NULL, 0)!=0) return STATUS_UNSUPPORTED;
117 sprintf(tmp, "%g", h->gantry_tilt);
118 if(iftPut(ift, "gantry_tilt", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
119 sprintf(tmp, "%g", h->gantry_rotation);
120 if(iftPut(ift, "gantry_rotation", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
121 sprintf(tmp, "%g", h->bed_elevation);
122 if(iftPut(ift, "bed_elevation", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
123 sprintf(tmp, "%g", h->intrinsic_tilt);
124 if(iftPut(ift, "intrinsic_tilt", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
125 sprintf(tmp, "%d", h->wobble_speed);
126 if(iftPut(ift, "wobble_speed", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
127 sprintf(tmp, "%d", h->transm_source_type);
128 if(iftPut(ift, "transm_source_type", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
129 sprintf(tmp, "%g", h->distance_scanned);
130 if(iftPut(ift, "distance_scanned", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
131 sprintf(tmp, "%g", h->transaxial_fov);
132 if(iftPut(ift, "transaxial_fov", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
133 sprintf(tmp, "%d", h->angular_compression);
134 if(iftPut(ift, "angular_compression", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
135 sprintf(tmp, "%d", h->coin_samp_mode);
136 if(iftPut(ift, "coin_samp_mode", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
137 sprintf(tmp, "%d", h->axial_samp_mode);
138 if(iftPut(ift, "axial_samp_mode", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
139 sprintf(tmp, "%E", h->ecat_calibration_factor);
140 if(iftPut(ift, "ecat_calibration_factor", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
141 sprintf(tmp, "%d", h->calibration_units);
142 if(iftPut(ift, "calibration_units", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
143 sprintf(tmp, "%d", h->calibration_units_label);
144 if(iftPut(ift, "calibration_units_label", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
145 sprintf(tmp, "%d", h->compression_code);
146 if(iftPut(ift, "compression_code", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
147 if(iftPut(ift, "study_type", h->study_type, NULL, 0)!=0) return STATUS_UNSUPPORTED;
148 if(iftPut(ift, "patient_id", h->patient_id, NULL, 0)!=0) return STATUS_UNSUPPORTED;
149 if(iftPut(ift, "patient_name", h->patient_name, NULL, 0)!=0) return STATUS_UNSUPPORTED;
150 sprintf(tmp, "%c", h->patient_sex);
151 if(iftPut(ift, "patient_sex", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
152 sprintf(tmp, "%c", h->patient_dexterity);
153 if(iftPut(ift, "patient_dexterity", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
154 sprintf(tmp, "%g", h->patient_age);
155 if(iftPut(ift, "patient_age", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
156 sprintf(tmp, "%g", h->patient_height);
157 if(iftPut(ift, "patient_height", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
158 sprintf(tmp, "%g", h->patient_weight);
159 if(iftPut(ift, "patient_weight", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
161 if(!ctime_r_int(&t, tmp)) strcpy(tmp, "1970-01-01 00:00:00");
162 if(iftPut(ift, "patient_birth_date", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
163 if(iftPut(ift, "physician_name", h->physician_name, NULL, 0)!=0) return STATUS_UNSUPPORTED;
164 if(iftPut(ift, "operator_name", h->operator_name, NULL, 0)!=0) return STATUS_UNSUPPORTED;
165 if(iftPut(ift, "study_description", h->study_description, NULL, 0)!=0) return STATUS_UNSUPPORTED;
166 sprintf(tmp, "%d", h->acquisition_type);
167 if(iftPut(ift, "acquisition_type", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
168 sprintf(tmp, "%d", h->patient_orientation);
169 if(iftPut(ift, "patient_orientation", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
170 if(iftPut(ift, "facility_name", h->facility_name, NULL, 0)!=0) return STATUS_UNSUPPORTED;
171 sprintf(tmp, "%d", h->num_planes);
172 if(iftPut(ift, "num_planes", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
173 sprintf(tmp, "%d", h->num_frames);
174 if(iftPut(ift, "num_frames", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
175 sprintf(tmp, "%d", h->num_gates);
176 if(iftPut(ift, "num_gates", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
177 sprintf(tmp, "%d", h->num_bed_pos);
178 if(iftPut(ift, "num_bed_pos", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
179 sprintf(tmp, "%g", h->init_bed_position);
180 if(iftPut(ift, "init_bed_position", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
181 sprintf(tmp, "%g", h->bed_position[0]);
182 for(i=1; i<15; i++) {sprintf(tmp2, " %g", h->bed_position[i]); strcat(tmp, tmp2);}
183 if(iftPut(ift, "bed_position", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
184 sprintf(tmp, "%g", h->plane_separation);
185 if(iftPut(ift, "plane_separation", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
186 sprintf(tmp, "%d", h->lwr_sctr_thres);
187 if(iftPut(ift, "lwr_sctr_thres", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
188 sprintf(tmp, "%d", h->lwr_true_thres);
189 if(iftPut(ift, "lwr_true_thres", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
190 sprintf(tmp, "%d", h->upr_true_thres);
191 if(iftPut(ift, "upr_true_thres", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
192 if(iftPut(ift, "user_process_code", h->user_process_code, NULL, 0)!=0) return STATUS_UNSUPPORTED;
193 sprintf(tmp, "%d", h->acquisition_mode);
194 if(iftPut(ift, "acquisition_mode", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
195 sprintf(tmp, "%g", h->bin_size);
196 if(iftPut(ift, "bin_size", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
197 sprintf(tmp, "%g", h->branching_fraction);
198 if(iftPut(ift, "branching_fraction", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
199 t=h->dose_start_time;
200 if(!ctime_r_int(&t, tmp)) strcpy(tmp, "1970-01-01 00:00:00");
201 if(iftPut(ift, "dose_start_time", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
202 sprintf(tmp, "%g", h->dosage);
203 if(iftPut(ift, "dosage", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
204 sprintf(tmp, "%E", h->well_counter_corr_factor);
205 if(iftPut(ift, "well_counter_corr_factor", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
206 if(iftPut(ift, "data_units", h->data_units, NULL, 0)!=0) return STATUS_UNSUPPORTED;
207 sprintf(tmp, "%d", h->septa_state);
208 if(iftPut(ift, "septa_state", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
209
210 sprintf(tmp, "%d", h->fill_cti[0]);
211 for(i=1; i<6; i++) {sprintf(tmp2, " %d", h->fill_cti[i]); strcat(tmp, tmp2);}
212 if(iftPut(ift, "fill_cti", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
213
214 return STATUS_OK;
215}
char * ctime_r_int(const time_t *t, char *buf)
Convert calendard time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss,...
Definition datetime.c:110

Referenced by ecat7ReadHeaders().

◆ ecat7Print2DNormheader()

void ecat7Print2DNormheader ( ECAT7_2Dnormheader * h,
FILE * fp )
extern

Print ECAT 7.x 2D normalization header contents to specified file pointer

Parameters
hEcat7 2D normalization header
fptarget file pointer

Definition at line 415 of file ecat7p.c.

417 {
418 if(ECAT7_TEST) fprintf(stdout, "ecat7Print2DNormheader()\n");
419 fprintf(fp, "data_type := %d (%s)\n", h->data_type,
421 fprintf(fp, "num_dimensions := %d\n", h->num_dimensions);
422 fprintf(fp, "num_r_elements := %d\n", h->num_r_elements);
423 fprintf(fp, "num_angles := %d\n", h->num_angles);
424 fprintf(fp, "num_z_elements := %d\n", h->num_z_elements);
425 fprintf(fp, "ring_difference := %d\n", h->ring_difference);
426 fprintf(fp, "scale_factor := %E\n", h->scale_factor);
427 fprintf(fp, "norm_min := %g\n", h->norm_min);
428 fprintf(fp, "norm_max := %g\n", h->norm_max);
429 fprintf(fp, "fov_source_width := %g\n", h->fov_source_width);
430 fprintf(fp, "norm_quality_factor := %g\n", h->norm_quality_factor);
431 fprintf(fp, "norm_quality_factor_code := %d\n", h->norm_quality_factor_code);
432 fprintf(fp, "storage_order := %d\n", h->storage_order);
433 fprintf(fp, "span := %d\n", h->span);
434 fprintf(fp, "z_elements :=");
435 for(int i=0; i<64; i++) fprintf(fp, " %d", h->z_elements[i]);
436 fprintf(fp, "\n");
437}
char * ecat7datatype(short int data_type)
Definition ecat7p.c:489
short int z_elements[64]
short int num_dimensions
short int ring_difference
short int storage_order
short int num_z_elements
short int norm_quality_factor_code
short int num_r_elements

Referenced by ecat7PrintSubheader().

◆ ecat7Print2DScanheader()

void ecat7Print2DScanheader ( ECAT7_2Dscanheader * h,
FILE * fp )
extern

Print ECAT 7.x 2D sinogram header contents to specified file pointer

Parameters
hEcat7 2D scan header
fptarget file pointer

Definition at line 364 of file ecat7p.c.

366 {
367 if(ECAT7_TEST) fprintf(stdout, "ecat7Print2DScanheader()\n");
368 fprintf(fp, "data_type := %d (%s)\n", h->data_type,
370 fprintf(fp, "num_dimensions := %d\n", h->num_dimensions);
371 fprintf(fp, "num_r_elements := %d\n", h->num_r_elements);
372 fprintf(fp, "num_angles := %d\n", h->num_angles);
373 fprintf(fp, "corrections_applied := %d\n", h->corrections_applied);
374 fprintf(fp, "num_z_elements := %d\n", h->num_z_elements);
375 fprintf(fp, "ring_difference := %d\n", h->ring_difference);
376 fprintf(fp, "x_resolution := %g\n", h->x_resolution);
377 fprintf(fp, "y_resolution := %g\n", h->y_resolution);
378 fprintf(fp, "z_resolution := %g\n", h->z_resolution);
379 fprintf(fp, "w_resolution := %g\n", h->w_resolution);
380 fprintf(fp, "gate_duration := %d\n", h->gate_duration);
381 fprintf(fp, "r_wave_offset := %d\n", h->r_wave_offset);
382 fprintf(fp, "num_accepted_beats := %d\n", h->num_accepted_beats);
383 fprintf(fp, "scale_factor := %E\n", h->scale_factor);
384 fprintf(fp, "scan_min := %d\n", h->scan_min);
385 fprintf(fp, "scan_max := %d\n", h->scan_max);
386 fprintf(fp, "prompts := %d\n", h->prompts);
387 fprintf(fp, "delayed := %d\n", h->delayed);
388 fprintf(fp, "multiples := %d\n", h->multiples);
389 fprintf(fp, "net_trues := %d\n", h->net_trues);
390 fprintf(fp, "cor_singles :=");
391 for(int i=0; i<16; i++) fprintf(fp, " %g", h->cor_singles[i]);
392 fprintf(fp, "\n");
393 fprintf(fp, "uncor_singles :=");
394 for(int i=0; i<16; i++) fprintf(fp, " %g", h->uncor_singles[i]);
395 fprintf(fp, "\n");
396 fprintf(fp, "tot_avg_cor := %g\n", h->tot_avg_cor);
397 fprintf(fp, "tot_avg_uncor := %g\n", h->tot_avg_uncor);
398 fprintf(fp, "total_coin_rate := %d\n", h->total_coin_rate);
399 fprintf(fp, "frame_start_time := %d\n", h->frame_start_time);
400 fprintf(fp, "frame_duration := %d\n", h->frame_duration);
401 fprintf(fp, "deadtime_correction_factor := %E\n", h->deadtime_correction_factor);
402 fprintf(fp, "physical_planes :=");
403 for(int i=0; i<8; i++) fprintf(fp, " %d", h->physical_planes[i]);
404 fprintf(fp, "\n");
405}
short int corrections_applied
float deadtime_correction_factor
short int num_z_elements
short int num_r_elements
short int ring_difference
short int physical_planes[8]
float cor_singles[16]
float uncor_singles[16]
short int num_dimensions

Referenced by ecat7PrintSubheader(), and ecat7Read2DScanMatrix().

◆ ecat7PrintAttenheader()

void ecat7PrintAttenheader ( ECAT7_attenheader * h,
FILE * fp )
extern

Print ECAT 7.x attenuation header contents to specified file pointer

Parameters
hEcat7 attenuation header
fptarget file pointer

Definition at line 230 of file ecat7p.c.

232 {
233 if(ECAT7_TEST) fprintf(stdout, "ecat7PrintAttenheader()\n");
234 fprintf(fp, "data_type := %d (%s)\n", h->data_type,
236 fprintf(fp, "num_dimensions := %d\n", h->num_dimensions);
237 fprintf(fp, "attenuation_type := %d\n", h->attenuation_type);
238 fprintf(fp, "num_r_elements := %d\n", h->num_r_elements);
239 fprintf(fp, "num_angles := %d\n", h->num_angles);
240 fprintf(fp, "num_z_elements := %d\n", h->num_z_elements);
241 fprintf(fp, "ring_difference := %d\n", h->ring_difference);
242 fprintf(fp, "x_resolution := %g\n", h->x_resolution);
243 fprintf(fp, "y_resolution := %g\n", h->y_resolution);
244 fprintf(fp, "z_resolution := %g\n", h->z_resolution);
245 fprintf(fp, "w_resolution := %g\n", h->w_resolution);
246 fprintf(fp, "scale_factor := %E\n", h->scale_factor);
247 fprintf(fp, "x_offset := %g\n", h->x_offset);
248 fprintf(fp, "y_offset := %g\n", h->y_offset);
249 fprintf(fp, "x_radius := %g\n", h->x_radius);
250 fprintf(fp, "y_radius := %g\n", h->y_radius);
251 fprintf(fp, "tilt_angle := %g\n", h->tilt_angle);
252 fprintf(fp, "attenuation_coeff := %E\n", h->attenuation_coeff);
253 fprintf(fp, "attenuation_min := %E\n", h->attenuation_min);
254 fprintf(fp, "attenuation_max := %E\n", h->attenuation_max);
255 fprintf(fp, "skull_thickness := %g\n", h->skull_thickness);
256 fprintf(fp, "num_additional_atten_coeff := %d\n", h->num_additional_atten_coeff);
257 fprintf(fp, "additional_atten_coeff :=");
258 for(int i=0; i<8; i++) fprintf(fp, " %E", h->additional_atten_coeff[i]);
259 fprintf(fp, "\n");
260 fprintf(fp, "edge_finding_threshold := %g\n", h->edge_finding_threshold);
261 fprintf(fp, "storage_order := %d\n", h->storage_order);
262 fprintf(fp, "span := %d\n", h->span);
263 fprintf(fp, "z_elements :=");
264 for(int i=0; i<64; i++) fprintf(fp, " %d", h->z_elements[i]);
265 fprintf(fp, "\n");
266}
short int num_r_elements
short int z_elements[64]
short int attenuation_type
short int num_additional_atten_coeff
short int num_dimensions
float edge_finding_threshold
short int num_z_elements
short int data_type
short int num_angles
short int storage_order
short int ring_difference
float additional_atten_coeff[8]

Referenced by ecat7PrintSubheader().

◆ ecat7PrintImageheader()

void ecat7PrintImageheader ( ECAT7_imageheader * h,
FILE * fp )
extern

Print ECAT 7.x image header contents to specified file pointer.

Parameters
hEcat7 image header
fptarget file pointer

Definition at line 102 of file ecat7p.c.

104 {
105 if(ECAT7_TEST) fprintf(stdout, "ecat7PrintImageheader()\n");
106 fprintf(fp, "data_type := %d (%s)\n", h->data_type, ecat7datatype(h->data_type) );
107 fprintf(fp, "num_dimensions := %d\n", h->num_dimensions);
108 fprintf(fp, "x_dimension := %d\n", h->x_dimension);
109 fprintf(fp, "y_dimension := %d\n", h->y_dimension);
110 fprintf(fp, "z_dimension := %d\n", h->z_dimension);
111 fprintf(fp, "x_offset := %g\n", h->x_offset);
112 fprintf(fp, "y_offset := %g\n", h->y_offset);
113 fprintf(fp, "z_offset := %g\n", h->z_offset);
114 fprintf(fp, "recon_zoom := %g\n", h->recon_zoom);
115 fprintf(fp, "scale_factor := %E\n", h->scale_factor);
116 fprintf(fp, "image_min := %d\n", h->image_min);
117 fprintf(fp, "image_max := %d\n", h->image_max);
118 fprintf(fp, "x_pixel_size := %g\n", h->x_pixel_size);
119 fprintf(fp, "y_pixel_size := %g\n", h->y_pixel_size);
120 fprintf(fp, "z_pixel_size := %g\n", h->z_pixel_size);
121 fprintf(fp, "frame_duration := %d\n", h->frame_duration);
122 fprintf(fp, "frame_start_time := %d\n", h->frame_start_time);
123 fprintf(fp, "filter_code := %d\n", h->filter_code);
124 fprintf(fp, "x_resolution := %g\n", h->x_resolution);
125 fprintf(fp, "y_resolution := %g\n", h->y_resolution);
126 fprintf(fp, "z_resolution := %g\n", h->z_resolution);
127 fprintf(fp, "num_r_elements := %g\n", h->num_r_elements);
128 fprintf(fp, "num_angles := %g\n", h->num_angles);
129 fprintf(fp, "z_rotation_angle := %g\n", h->z_rotation_angle);
130 fprintf(fp, "decay_corr_fctr := %g\n", h->decay_corr_fctr);
131 fprintf(fp, "processing_code := %d\n", h->processing_code);
132 fprintf(fp, "gate_duration := %d\n", h->gate_duration);
133 fprintf(fp, "r_wave_offset := %d\n", h->r_wave_offset);
134 fprintf(fp, "num_accepted_beats := %d\n", h->num_accepted_beats);
135 fprintf(fp, "filter_cutoff_frequency := %E\n", h->filter_cutoff_frequency);
136 fprintf(fp, "filter_resolution := %E\n", h->filter_resolution);
137 fprintf(fp, "filter_ramp_slope := %E\n", h->filter_ramp_slope);
138 fprintf(fp, "filter_order := %d\n", h->filter_order);
139 fprintf(fp, "filter_scatter_fraction := %E\n", h->filter_scatter_fraction);
140 fprintf(fp, "filter_scatter_slope := %E\n", h->filter_scatter_slope);
141 fprintf(fp, "annotation := %.40s\n", h->annotation);
142 fprintf(fp, "mt_1_1 := %g\n", h->mt_1_1);
143 fprintf(fp, "mt_1_2 := %g\n", h->mt_1_2);
144 fprintf(fp, "mt_1_3 := %g\n", h->mt_1_3);
145 fprintf(fp, "mt_2_1 := %g\n", h->mt_2_1);
146 fprintf(fp, "mt_2_2 := %g\n", h->mt_2_2);
147 fprintf(fp, "mt_2_3 := %g\n", h->mt_2_3);
148 fprintf(fp, "mt_3_1 := %g\n", h->mt_3_1);
149 fprintf(fp, "mt_3_2 := %g\n", h->mt_3_2);
150 fprintf(fp, "mt_3_3 := %g\n", h->mt_3_3);
151 fprintf(fp, "rfilter_cutoff := %g\n", h->rfilter_cutoff);
152 fprintf(fp, "rfilter_resolution := %g\n", h->rfilter_resolution);
153 fprintf(fp, "rfilter_code := %d\n", h->rfilter_code);
154 fprintf(fp, "rfilter_order := %d\n", h->rfilter_order);
155 fprintf(fp, "zfilter_cutoff := %g\n", h->zfilter_cutoff);
156 fprintf(fp, "zfilter_resolution := %g\n", h->zfilter_resolution);
157 fprintf(fp, "zfilter_code := %d\n", h->zfilter_code);
158 fprintf(fp, "zfilter_order := %d\n", h->zfilter_order);
159 fprintf(fp, "mt_1_4 := %g\n", h->mt_1_4);
160 fprintf(fp, "mt_2_4 := %g\n", h->mt_2_4);
161 fprintf(fp, "mt_3_4 := %g\n", h->mt_3_4);
162 fprintf(fp, "scatter_type := %d\n", h->scatter_type);
163 fprintf(fp, "recon_type := %d\n", h->recon_type);
164 fprintf(fp, "recon_views := %d\n", h->recon_views);
165 fprintf(fp, "fill_cti :=");
166 for(int i=0; i<87; i++) fprintf(fp, " %d", h->fill_cti[i]);
167 fprintf(fp, "\n");
168 fprintf(fp, "fill_user :=");
169 for(int i=0; i<49; i++) fprintf(fp, " %d", h->fill_user[i]);
170 fprintf(fp, "\n");
171}

Referenced by ecat7PrintSubheader(), and ecat7ReadImageMatrix().

◆ ecat7PrintMainheader()

void ecat7PrintMainheader ( ECAT7_mainheader * h,
FILE * fp )
extern

Print ECAT 7.x main header contents to specified file pointer

Parameters
hEcat7 main header
fptarget file pointer

Definition at line 16 of file ecat7p.c.

18 {
19 char tmp[64];
20 time_t t;
21
22 if(ECAT7_TEST) fprintf(stdout, "ecat7PrintMainheader()\n");
23 fprintf(fp, "magic_number := %.14s\n", h->magic_number);
24 fprintf(fp, "original_file_name := %.32s\n", h->original_file_name);
25 fprintf(fp, "sw_version := %d\n", h->sw_version);
26 fprintf(fp, "system_type := %d\n", h->system_type);
27 fprintf(fp, "file_type := %d (%s)\n", h->file_type, ecat7filetype(h->file_type) );
28 fprintf(fp, "serial_number := %.10s\n", h->serial_number);
29 t=(time_t)h->scan_start_time;
30 if(!ctime_r_int(&t, tmp)) strcpy(tmp, "1900-01-01 00:00:00");
31 fprintf(fp, "scan_start_time := %s\n", tmp);
32 fprintf(fp, "isotope_name := %.8s\n", h->isotope_name);
33 fprintf(fp, "isotope_halflife := %E sec\n", h->isotope_halflife);
34 fprintf(fp, "radiopharmaceutical := %.32s\n", h->radiopharmaceutical);
35 fprintf(fp, "gantry_tilt := %g\n", h->gantry_tilt);
36 fprintf(fp, "gantry_rotation := %g\n", h->gantry_rotation);
37 fprintf(fp, "bed_elevation := %g\n", h->bed_elevation);
38 fprintf(fp, "intrinsic_tilt := %g\n", h->intrinsic_tilt);
39 fprintf(fp, "wobble_speed := %d\n", h->wobble_speed);
40 fprintf(fp, "transm_source_type := %d\n", h->transm_source_type);
41 fprintf(fp, "distance_scanned := %g\n", h->distance_scanned);
42 fprintf(fp, "transaxial_fov := %g\n", h->transaxial_fov);
43 fprintf(fp, "angular_compression := %d\n", h->angular_compression);
44 fprintf(fp, "coin_samp_mode := %d\n", h->coin_samp_mode);
45 fprintf(fp, "axial_samp_mode := %d\n", h->axial_samp_mode);
46 fprintf(fp, "ecat_calibration_factor := %E\n", h->ecat_calibration_factor);
47 fprintf(fp, "calibration_units := %d\n", h->calibration_units);
48 fprintf(fp, "calibration_units_label := %d\n", h->calibration_units_label);
49 fprintf(fp, "compression_code := %d\n", h->compression_code);
50 fprintf(fp, "study_type := %.12s\n", h->study_type);
51 fprintf(fp, "patient_id := %.16s\n", h->patient_id);
52 fprintf(fp, "patient_name := %.32s\n", h->patient_name);
53 fprintf(fp, "patient_sex := %c\n", (h->patient_sex!=0)?h->patient_sex:(char)32);
54 fprintf(fp, "patient_dexterity := %c\n", (h->patient_dexterity!=0)?h->patient_dexterity:(char)32 );
55 fprintf(fp, "patient_age := %g\n", h->patient_age);
56 fprintf(fp, "patient_height := %g\n", h->patient_height);
57 fprintf(fp, "patient_weight := %g\n", h->patient_weight);
58 fprintf(fp, "patient_birth_date := %d\n", h->patient_birth_date);
59 fprintf(fp, "physician_name := %.32s\n", h->physician_name);
60 fprintf(fp, "operator_name := %.32s\n", h->operator_name);
61 fprintf(fp, "study_description := %.32s\n", h->study_description);
62 fprintf(fp, "acquisition_type := %d (%s)\n", h->acquisition_type,
64 fprintf(fp, "patient_orientation := %d\n", h->patient_orientation);
65 fprintf(fp, "facility_name := %.20s\n", h->facility_name);
66 fprintf(fp, "num_planes := %d\n", h->num_planes);
67 fprintf(fp, "num_frames := %d\n", h->num_frames);
68 fprintf(fp, "num_gates := %d\n", h->num_gates);
69 fprintf(fp, "num_bed_pos := %d\n", h->num_bed_pos);
70 fprintf(fp, "init_bed_position := %g\n", h->init_bed_position);
71 fprintf(fp, "bed_position :=");
72 for(int i=0; i<15; i++) fprintf(fp, " %g", h->bed_position[i]);
73 fprintf(fp, "\n");
74 fprintf(fp, "plane_separation := %g cm\n", h->plane_separation);
75 fprintf(fp, "lwr_sctr_thres := %d\n", h->lwr_sctr_thres);
76 fprintf(fp, "lwr_true_thres := %d\n", h->lwr_true_thres);
77 fprintf(fp, "upr_true_thres := %d\n", h->upr_true_thres);
78 fprintf(fp, "user_process_code := %.10s\n", h->user_process_code);
79 fprintf(fp, "acquisition_mode := %d\n", h->acquisition_mode);
80 fprintf(fp, "bin_size := %g cm\n", h->bin_size);
81 fprintf(fp, "branching_fraction := %g\n", h->branching_fraction);
82 t=(time_t)h->dose_start_time;
83 if(!ctime_r_int(&t, tmp)) strcpy(tmp, "1900-01-01 00:00:00");
84 fprintf(fp, "dose_start_time := %s\n", tmp);
85 fprintf(fp, "dosage := %g\n", h->dosage);
86 fprintf(fp, "well_counter_corr_factor := %E\n", h->well_counter_corr_factor);
87 fprintf(fp, "data_units := %.32s\n", h->data_units);
88 fprintf(fp, "septa_state := %d\n", h->septa_state);
89 fprintf(fp, "fill_cti :=");
90 for(int i=0; i<6; i++) fprintf(fp, " %d", h->fill_cti[i]);
91 fprintf(fp, "\n");
92}
char * ecat7acquisitiontype(short int acquisition_type)
Definition ecat7p.c:468
char * ecat7filetype(short int file_type)
Definition ecat7p.c:447

◆ ecat7PrintMatlist()

void ecat7PrintMatlist ( ECAT7_MATRIXLIST * ml)
extern

Print ECAT matrix list on stdout.

Parameters
mlmatrix list for Ecat7 file

Definition at line 112 of file ecat7ml.c.

112 {
113 int i;
114 ECAT7_Matval matval;
115
116 printf("nr matrix pl fr gate bed startblk blknr status\n");
117 for(i=0; i<ml->matrixNr; i++) {
118 ecat7_id_to_val(ml->matdir[i].id, &matval);
119 printf("%4d %8d %3d %3d %3d %3d %8d %5d ", i+1, ml->matdir[i].id,
120 matval.plane, matval.frame, matval.gate, matval.bed,
121 ml->matdir[i].strtblk, 1+ml->matdir[i].endblk-ml->matdir[i].strtblk);
122 if(ml->matdir[i].status==1) printf("read/write\n");
123 else if(ml->matdir[i].status==0) printf("not ready\n");
124 else if(ml->matdir[i].status==-1) printf("deleted\n");
125 else printf("%d\n", ml->matdir[i].status);
126 }
127 return;
128}

Referenced by ecat7PrintSubheader(), ecatFixMatrixlist(), and imgReadEcat7().

◆ ecat7PrintNormheader()

void ecat7PrintNormheader ( ECAT7_normheader * h,
FILE * fp )
extern

Prints ECAT 7.x normalization header contents to specified file pointer

Parameters
hEcat7 normalization header
fptager file pointer

Definition at line 327 of file ecat7p.c.

329 {
330 if(ECAT7_TEST) fprintf(stdout, "ecat7PrintNormheader()\n");
331 fprintf(fp, "data_type := %d (%s)\n", h->data_type,
333 fprintf(fp, "num_r_elements := %d\n", h->num_r_elements);
334 fprintf(fp, "num_transaxial_crystals := %d\n", h->num_transaxial_crystals);
335 fprintf(fp, "num_crystal_rings := %d\n", h->num_crystal_rings);
336 fprintf(fp, "crystals_per_ring := %d\n", h->crystals_per_ring);
337 fprintf(fp, "num_geo_corr_planes := %d\n", h->num_geo_corr_planes);
338 fprintf(fp, "uld := %d\n", h->uld);
339 fprintf(fp, "lld := %d\n", h->lld);
340 fprintf(fp, "scatter_energy := %d\n", h->scatter_energy);
341 fprintf(fp, "norm_quality_factor := %g\n", h->norm_quality_factor);
342 fprintf(fp, "norm_quality_factor_code := %d\n", h->norm_quality_factor_code);
343 fprintf(fp, "ring_dtcor1 :=");
344 for(int i=0; i<32; i++) fprintf(fp, " %E", h->ring_dtcor1[i]);
345 fprintf(fp, "\n");
346 fprintf(fp, "ring_dtcor2 :=");
347 for(int i=0; i<32; i++) fprintf(fp, " %E", h->ring_dtcor2[i]);
348 fprintf(fp, "\n");
349 fprintf(fp, "crystal_dtcor :=");
350 for(int i=0; i<8; i++) fprintf(fp, " %E", h->crystal_dtcor[i]);
351 fprintf(fp, "\n");
352 fprintf(fp, "span := %d\n", h->span);
353 fprintf(fp, "max_ring_diff := %d\n", h->max_ring_diff);
354}
short int num_r_elements
short int data_type
short int num_transaxial_crystals
short int num_geo_corr_planes
short int crystals_per_ring
short int max_ring_diff
float norm_quality_factor
float ring_dtcor1[32]
short int num_crystal_rings
short int norm_quality_factor_code
float ring_dtcor2[32]
float crystal_dtcor[8]
short int scatter_energy

Referenced by ecat7PrintSubheader().

◆ ecat7PrintPolmapheader()

void ecat7PrintPolmapheader ( ECAT7_polmapheader * h,
FILE * fp )
extern

Print ECAT 7.x polar map header contents to specified file pointer

Parameters
hEcat7 polar map header
fptarget file pointer

Definition at line 276 of file ecat7p.c.

278 {
279 int i;
280
281 if(ECAT7_TEST) fprintf(stdout, "ecat7PrintPolmapheader()\n");
282 fprintf(fp, "data_type := %d (%s)\n", h->data_type,
284 fprintf(fp, "polar_map_type := %d\n", h->polar_map_type);
285 fprintf(fp, "num_rings := %d\n", h->num_rings);
286 fprintf(fp, "sectors_per_ring :=");
287 for(i=0; i<32; i++) fprintf(fp, " %d", h->sectors_per_ring[i]);
288 fprintf(fp, "\n");
289 fprintf(fp, "ring_position :=");
290 for(i=0; i<32; i++) fprintf(fp, " %g", h->ring_position[i]);
291 fprintf(fp, "\n");
292 fprintf(fp, "ring_angle :=");
293 for(i=0; i<32; i++) fprintf(fp, " %d", h->ring_angle[i]);
294 fprintf(fp, "\n");
295 fprintf(fp, "start_angle := %d\n", h->start_angle);
296 fprintf(fp, "long_axis_left :=");
297 for(i=0; i<3; i++) fprintf(fp, " %d", h->long_axis_left[i]);
298 fprintf(fp, "\n");
299 fprintf(fp, "long_axis_right :=");
300 for(i=0; i<3; i++) fprintf(fp, " %d", h->long_axis_right[i]);
301 fprintf(fp, "\n");
302 fprintf(fp, "position_data := %d\n", h->position_data);
303 fprintf(fp, "image_min := %d\n", h->image_min);
304 fprintf(fp, "image_max := %d\n", h->image_max);
305 fprintf(fp, "scale_factor := %E\n", h->scale_factor);
306 fprintf(fp, "pixel_size := %g\n", h->pixel_size);
307 fprintf(fp, "frame_duration := %d\n", h->frame_duration);
308 fprintf(fp, "frame_start_time := %d\n", h->frame_start_time);
309 fprintf(fp, "processing_code := %d\n", h->processing_code);
310 fprintf(fp, "quant_units := %d\n", h->quant_units);
311 fprintf(fp, "annotation := %.40s\n", h->annotation);
312 fprintf(fp, "gate_duration := %d\n", h->gate_duration);
313 fprintf(fp, "r_wave_offset := %d\n", h->r_wave_offset);
314 fprintf(fp, "num_accepted_beats := %d\n", h->num_accepted_beats);
315 fprintf(fp, "polar_map_protocol := %.20s\n", h->polar_map_protocol);
316 fprintf(fp, "database_name := %.30s\n", h->database_name);
317}
short int ring_angle[32]
short int long_axis_left[3]
short int processing_code
short int sectors_per_ring[32]
char polar_map_protocol[20]
short int start_angle
short int polar_map_type
short int position_data
float ring_position[32]
short int quant_units
short int long_axis_right[3]

Referenced by ecat7PrintSubheader(), and ecat7ReadPolarmapMatrix().

◆ ecat7PrintScanheader()

void ecat7PrintScanheader ( ECAT7_scanheader * h,
FILE * fp )
extern

Print ECAT 7.x 3D sinogram header contents to specified file pointer

Parameters
hEcat7 scan header
fptarget file pointer

Definition at line 181 of file ecat7p.c.

183 {
184 if(ECAT7_TEST) fprintf(stdout, "ecat7PrintScanheader()\n");
185 fprintf(fp, "data_type := %d (%s)\n", h->data_type,
187 fprintf(fp, "num_dimensions := %d\n", h->num_dimensions);
188 fprintf(fp, "num_r_elements := %d\n", h->num_r_elements);
189 fprintf(fp, "num_angles := %d\n", h->num_angles);
190 fprintf(fp, "corrections_applied := %d\n", h->corrections_applied);
191 fprintf(fp, "num_z_elements :=");
192 for(int i=0; i<64; i++) fprintf(fp, " %d", h->num_z_elements[i]);
193 fprintf(fp, "\n");
194 fprintf(fp, "ring_difference := %d\n", h->ring_difference);
195 fprintf(fp, "storage_order := %d\n", h->storage_order);
196 fprintf(fp, "axial_compression := %d (span)\n", h->axial_compression);
197 fprintf(fp, "x_resolution := %g cm\n", h->x_resolution);
198 fprintf(fp, "v_resolution := %g rad\n", h->v_resolution);
199 fprintf(fp, "z_resolution := %g cm\n", h->z_resolution);
200 fprintf(fp, "w_resolution := %g\n", h->w_resolution);
201 fprintf(fp, "gate_duration := %d\n", h->gate_duration);
202 fprintf(fp, "r_wave_offset := %d\n", h->r_wave_offset);
203 fprintf(fp, "num_accepted_beats := %d\n", h->num_accepted_beats);
204 fprintf(fp, "scale_factor := %E\n", h->scale_factor);
205 fprintf(fp, "scan_min := %d\n", h->scan_min);
206 fprintf(fp, "scan_max := %d\n", h->scan_max);
207 fprintf(fp, "prompts := %d\n", h->prompts);
208 fprintf(fp, "delayed := %d\n", h->delayed);
209 fprintf(fp, "multiples := %d\n", h->multiples);
210 fprintf(fp, "net_trues := %d\n", h->net_trues);
211 fprintf(fp, "tot_avg_cor := %g\n", h->tot_avg_cor);
212 fprintf(fp, "tot_avg_uncor := %g\n", h->tot_avg_uncor);
213 fprintf(fp, "total_coin_rate := %d\n", h->total_coin_rate);
214 fprintf(fp, "frame_start_time := %d\n", h->frame_start_time);
215 fprintf(fp, "frame_duration := %d\n", h->frame_duration);
216 fprintf(fp, "deadtime_correction_factor := %g\n", h->deadtime_correction_factor);
217 fprintf(fp, "uncor_singles :=");
218 for(int i=0; i<128; i++) fprintf(fp, " %g", h->uncor_singles[i]);
219 fprintf(fp, "\n");
220}
float uncor_singles[128]

Referenced by ecat7PrintSubheader(), and ecat7ReadScanMatrix().

◆ ecat7PrintSubheader()

int ecat7PrintSubheader ( ECAT7_mainheader mh,
FILE * fp,
int plane,
int frame,
FILE * ofp )
extern

Print ECAT7 subheader contents into specified file pointer.

Returns
Returns 0 when successful.
Parameters
mhECAT7 mainheader (not printed but needed here)
fpFile pointer to ECAT7 file
planeECAT7 plane
frameECAT7 frame
ofpOutput is written to this file pointer; it can be stdout

Definition at line 506 of file ecat7p.c.

517 {
518 int mi, ret, nr=0;
519 ECAT7_imageheader image_header;
520 ECAT7_scanheader scan_header;
521 ECAT7_2Dscanheader scan2D_header;
522 ECAT7_2Dnormheader norm2D_header;
523 ECAT7_normheader norm_header;
524 ECAT7_attenheader atten_header;
525 ECAT7_polmapheader polmap_header;
526 static ECAT7_MATRIXLIST mlist;
527 ECAT7_Matval matval;
528
529
530 /*
531 * Read matrix list
532 */
533 ecat7InitMatlist(&mlist);
534 ret=ecat7ReadMatlist(fp, &mlist, ECAT7_TEST);
535 if(ret) {
536 fprintf(stderr, "Error (%d): cannot read matrix list.\n", ret);
537 return(2);
538 }
539 if(mlist.matrixNr<=0) {
540 fprintf(stderr, "Error: matrix list is empty.\n");
541 return(2);
542 }
543 if(ECAT7_TEST>1) ecat7PrintMatlist(&mlist);
544
545 /*
546 * Read and print subheaders one at a time
547 */
548 for(mi=nr=0; mi<mlist.matrixNr; mi++) {
549 /* Get frame nr */
550 ecat7_id_to_val(mlist.matdir[mi].id, &matval);
551 /* Check if this is supposed to be listed or not */
552 if(frame>=0 && frame!=matval.frame) continue;
553 if(plane>=0 && plane!=matval.plane) continue;
554 fprintf(fp, "Matrix: plane %d frame %d gate %d bed %d\n",
555 matval.plane, matval.frame, matval.gate, matval.bed);
556 /* Read and print subheader */
557 ret=0;
558 switch(mh.file_type) {
559 case ECAT7_ATTEN:
560 ret=ecat7ReadAttenheader(fp, mlist.matdir[mi].strtblk, &atten_header);
561 if(ret==0) ecat7PrintAttenheader(&atten_header, ofp);
562 break;
563 case ECAT7_3DNORM:
564 ret=ecat7ReadNormheader(fp, mlist.matdir[mi].strtblk, &norm_header);
565 if(ret==0) ecat7PrintNormheader(&norm_header, ofp);
566 break;
567 case ECAT7_IMAGE8:
568 case ECAT7_IMAGE16:
569 case ECAT7_VOLUME8:
570 case ECAT7_VOLUME16:
571 ret=ecat7ReadImageheader(fp, mlist.matdir[mi].strtblk, &image_header);
572 if(ret==0) ecat7PrintImageheader(&image_header, ofp);
573 break;
574 case ECAT7_3DSCAN:
575 case ECAT7_3DSCAN8:
576 case ECAT7_3DSCANFIT:
577 ret=ecat7ReadScanheader(fp, mlist.matdir[mi].strtblk, &scan_header);
578 if(ret==0) ecat7PrintScanheader(&scan_header, ofp);
579 break;
580 case ECAT7_POLARMAP:
581 ret=ecat7ReadPolmapheader(fp, mlist.matdir[mi].strtblk, &polmap_header);
582 if(ret==0) ecat7PrintPolmapheader(&polmap_header, ofp);
583 break;
584 case ECAT7_2DSCAN:
585 ret=ecat7Read2DScanheader(fp, mlist.matdir[mi].strtblk, &scan2D_header);
586 if(ret==0) ecat7Print2DScanheader(&scan2D_header, ofp);
587 break;
588 case ECAT7_2DNORM:
589 ret=ecat7Read2DNormheader(fp, mlist.matdir[mi].strtblk, &norm2D_header);
590 if(ret==0) ecat7Print2DNormheader(&norm2D_header, ofp);
591 break;
592 default:
593 fprintf(stderr, "Error: matrix filetype %d is not yet supported.\n",
594 mh.file_type);
595 ecat7EmptyMatlist(&mlist);
596 return(8);
597 }
598 if(ret) {
599 fprintf(stderr, "Error %d in reading subheader.\n", ret);
600 ecat7EmptyMatlist(&mlist); return(5);
601 }
602 nr++; // counter
603 } /* next matrix */
604 ecat7EmptyMatlist(&mlist);
605
606 if(nr==0 && (plane>=0 || frame>=0)) {
607 fprintf(stderr, "Error: specified matrices not found.\n");
608 return(11);
609 }
610
611 return(0);
612}
void ecat7InitMatlist(ECAT7_MATRIXLIST *mlist)
Definition ecat7ml.c:15
int ecat7ReadMatlist(FILE *fp, ECAT7_MATRIXLIST *ml, int verbose)
Definition ecat7ml.c:41
void ecat7EmptyMatlist(ECAT7_MATRIXLIST *mlist)
Definition ecat7ml.c:26
void ecat7PrintMatlist(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:112
void ecat7PrintNormheader(ECAT7_normheader *h, FILE *fp)
Definition ecat7p.c:327
void ecat7PrintImageheader(ECAT7_imageheader *h, FILE *fp)
Definition ecat7p.c:102
void ecat7PrintPolmapheader(ECAT7_polmapheader *h, FILE *fp)
Definition ecat7p.c:276
void ecat7PrintAttenheader(ECAT7_attenheader *h, FILE *fp)
Definition ecat7p.c:230
void ecat7Print2DScanheader(ECAT7_2Dscanheader *h, FILE *fp)
Definition ecat7p.c:364
void ecat7PrintScanheader(ECAT7_scanheader *h, FILE *fp)
Definition ecat7p.c:181
void ecat7Print2DNormheader(ECAT7_2Dnormheader *h, FILE *fp)
Definition ecat7p.c:415
int ecat7ReadPolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h)
Definition ecat7r.c:397
int ecat7ReadNormheader(FILE *fp, int blk, ECAT7_normheader *h)
Definition ecat7r.c:472
int ecat7ReadAttenheader(FILE *fp, int blk, ECAT7_attenheader *h)
Definition ecat7r.c:311
int ecat7Read2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h)
Definition ecat7r.c:631
int ecat7Read2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h)
Definition ecat7r.c:725
#define ECAT7_ATTEN
#define ECAT7_IMAGE16
#define ECAT7_3DNORM
#define ECAT7_IMAGE8
#define ECAT7_2DNORM
#define ECAT7_POLARMAP
#define ECAT7_2DSCAN

◆ ecat7pxlbytes()

int ecat7pxlbytes ( short int data_type)
extern

Returns the nr of bytes required for storage of one pixel of specified data_type

Parameters
data_typedefined value for data type
Returns
number of bytes (1,2 or 4) or 0 if type not recognized

Definition at line 1274 of file ecat7r.c.

1274 {
1275 int byteNr=0;
1276 switch(data_type) {
1277 case ECAT7_BYTE: byteNr=1; break;
1278 case ECAT7_VAXI2:
1279 case ECAT7_SUNI2: byteNr=2; break;
1280 case ECAT7_VAXI4:
1281 case ECAT7_VAXR4:
1282 case ECAT7_IEEER4:
1283 case ECAT7_SUNI4: byteNr=4; break;
1284 }
1285 return(byteNr);
1286}
#define ECAT7_IEEER4
#define ECAT7_VAXI4
#define ECAT7_SUNI4
#define ECAT7_BYTE
#define ECAT7_VAXI2
#define ECAT7_VAXR4
#define ECAT7_SUNI2

Referenced by ecat7ReadScanMatrix(), ecat7Write2DScanMatrix(), ecat7WriteImageMatrix(), ecat7WritePolarmapMatrix(), and ecat7WriteScanMatrix().

◆ ecat7Read2DNormheader()

int ecat7Read2DNormheader ( FILE * fp,
int blk,
ECAT7_2Dnormheader * h )
extern

Read ECAT 7.x 2D normalization header

Parameters
fpinput file pointer
blkblock number [1..number of blocks]
hEcat7 normalization header
Returns
0 if ok, 1 == invalid parameters, 2 == first header block not found, 3 == header block not read properly

Definition at line 725 of file ecat7r.c.

725 {
726 unsigned char buf[MatBLKSIZE];
727 int little; /* 1 if current platform is little endian (i386), else 0 */
728
729 if(ECAT7_TEST) printf("ecat7Read2Dnormheader()\n");
730 if(fp==NULL || h==NULL) return(1);
731 little=little_endian();
732
733 /* Seek the subheader block */
734 long long pos=(blk-1)*(long long)MatBLKSIZE;
735 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
736 /* Read the header block */
737 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
738 /* Copy the header fields and swap if necessary */
739 if(little) swabip(buf+0, 2);
740 memcpy(&h->data_type, buf+0, 2);
741 if(little) swabip(buf+2, 2);
742 memcpy(&h->num_dimensions, buf+2, 2);
743 if(little) swabip(buf+4, 2);
744 memcpy(&h->num_r_elements, buf+4, 2);
745 if(little) swabip(buf+6, 2);
746 memcpy(&h->num_angles, buf+6, 2);
747 if(little) swabip(buf+8, 2);
748 memcpy(&h->num_z_elements, buf+8, 2);
749 if(little) swabip(buf+10, 2);
750 memcpy(&h->ring_difference, buf+10, 2);
751 if(little) swawbip(buf+12, 4);
752 memcpy(&h->scale_factor, buf+12, 4);
753 if(little) swawbip(buf+16, 4);
754 memcpy(&h->norm_min, buf+16, 4);
755 if(little) swawbip(buf+20, 4);
756 memcpy(&h->norm_max, buf+20, 4);
757 if(little) swawbip(buf+24, 4);
758 memcpy(&h->fov_source_width, buf+24, 4);
759 if(little) swawbip(buf+28, 4);
760 memcpy(&h->norm_quality_factor, buf+28, 4);
761 if(little) swabip(buf+32, 2);
762 memcpy(&h->norm_quality_factor_code, buf+32, 2);
763 if(little) swabip(buf+34, 2);
764 memcpy(&h->storage_order, buf+34, 2);
765 if(little) swabip(buf+36, 2);
766 memcpy(&h->span, buf+36, 2);
767 if(little) swabip(buf+38, 64*2);
768 memcpy(h->fill_cti, buf+38, 64*2);
769 if(little) swabip(buf+166, 123*2);
770 memcpy(h->fill_cti, buf+166, 123*2);
771 if(little) swabip(buf+412, 50*2);
772 memcpy(h->fill_user, buf+412, 50*2);
773 return(0);
774}
short int fill_user[50]
short int fill_cti[123]

Referenced by ecat7PrintSubheader(), ecat7ReadSubheaderToIFT(), and ecat7WriteSubheaderFromIFT().

◆ ecat7Read2DScanheader()

int ecat7Read2DScanheader ( FILE * fp,
int blk,
ECAT7_2Dscanheader * h )
extern

Read ECAT 7.x 2D scan header

Parameters
fpinput file pointer
blkblock number [1..number of blocks]
hEcat7 2D scan header
Returns
0 if ok, 1 == invalid parameters, 2 == first header block not found, 3 == header block not read properly

Definition at line 631 of file ecat7r.c.

631 {
632 unsigned char buf[MatBLKSIZE];
633 int little; /* 1 if current platform is little endian (i386), else 0 */
634
635 if(ECAT7_TEST) printf("ecat7Read2DScanheader()\n");
636 if(fp==NULL || h==NULL) return(1);
637 little=little_endian();
638
639 /* Seek the subheader block */
640 long long pos=(blk-1)*(long long)MatBLKSIZE;
641 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
642 /* Read the header block */
643 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
644 /* Copy the header fields and swap if necessary */
645 if(little) swabip(buf+0, 2);
646 memcpy(&h->data_type, buf+0, 2);
647 if(little) swabip(buf+2, 2);
648 memcpy(&h->num_dimensions, buf+2, 2);
649 if(little) swabip(buf+4, 2);
650 memcpy(&h->num_r_elements, buf+4, 2);
651 if(little) swabip(buf+6, 2);
652 memcpy(&h->num_angles, buf+6, 2);
653 if(little) swabip(buf+8, 2);
654 memcpy(&h->corrections_applied, buf+8, 2);
655 if(little) swabip(buf+10, 2);
656 memcpy(&h->num_z_elements, buf+10, 2);
657 if(little) swabip(buf+12, 2);
658 memcpy(&h->ring_difference, buf+12, 2);
659 if(little) swawbip(buf+14, 4);
660 memcpy(&h->x_resolution, buf+14, 4);
661 if(little) swawbip(buf+18, 4);
662 memcpy(&h->y_resolution, buf+18, 4);
663 if(little) swawbip(buf+22, 4);
664 memcpy(&h->z_resolution, buf+22, 4);
665 if(little) swawbip(buf+26, 4);
666 memcpy(&h->w_resolution, buf+26, 4);
667 if(little) swabip(buf+30, 6*2);
668 memcpy(h->fill_gate, buf+30, 6*2);
669 if(little) swawbip(buf+42, 4);
670 memcpy(&h->gate_duration, buf+42, 4);
671 if(little) swawbip(buf+46, 4);
672 memcpy(&h->r_wave_offset, buf+46, 4);
673 if(little) swawbip(buf+50, 4);
674 memcpy(&h->num_accepted_beats, buf+50, 4);
675 if(little) swawbip(buf+54, 4);
676 memcpy(&h->scale_factor, buf+54, 4);
677 if(little) swabip(buf+58, 2);
678 memcpy(&h->scan_min, buf+58, 2);
679 if(little) swabip(buf+60, 2);
680 memcpy(&h->scan_max, buf+60, 2);
681 if(little) swawbip(buf+62, 4);
682 memcpy(&h->prompts, buf+62, 4);
683 if(little) swawbip(buf+66, 4);
684 memcpy(&h->delayed, buf+66, 4);
685 if(little) swawbip(buf+70, 4);
686 memcpy(&h->multiples, buf+70, 4);
687 if(little) swawbip(buf+74, 4);
688 memcpy(&h->net_trues, buf+74, 4);
689 if(little) swawbip(buf+78, 16*4);
690 memcpy(h->cor_singles, buf+78, 16*4);
691 if(little) swawbip(buf+142, 16*4);
692 memcpy(h->uncor_singles, buf+142, 16*4);
693 if(little) swawbip(buf+206, 4);
694 memcpy(&h->tot_avg_cor, buf+206, 4);
695 if(little) swawbip(buf+210, 4);
696 memcpy(&h->tot_avg_uncor, buf+210, 4);
697 if(little) swawbip(buf+214, 4);
698 memcpy(&h->total_coin_rate, buf+214, 4);
699 if(little) swawbip(buf+218, 4);
700 memcpy(&h->frame_start_time, buf+218, 4);
701 if(little) swawbip(buf+222, 4);
702 memcpy(&h->frame_duration, buf+222, 4);
703 if(little) swawbip(buf+226, 4);
704 memcpy(&h->deadtime_correction_factor, buf+226,4);
705 if(little) swabip(buf+230, 8*2);
706 memcpy(h->physical_planes, buf+230, 8*2);
707 if(little) swabip(buf+246, 83*2);
708 memcpy(h->fill_cti, buf+246, 83*2);
709 if(little) swabip(buf+412, 50*2);
710 memcpy(h->fill_user, buf+412, 50*2);
711 return(0);
712}
short int fill_user[50]
short int fill_gate[6]
short int fill_cti[83]

Referenced by ecat7PrintSubheader(), ecat7Read2DScanMatrix(), ecat7ReadSubheaderToIFT(), ecat7WriteSubheaderFromIFT(), imgReadEcat7(), and imgReadEcat7Header().

◆ ecat7Read2DScanMatrix()

int ecat7Read2DScanMatrix ( FILE * fp,
int first_block,
int last_block,
ECAT7_2Dscanheader * h,
float ** fdata )
extern

Read ECAT7 2D sinogram matrix header and data Memory for fdata[] is allocated here, remember to free memory after usage. Note: data is not calibrated with factor in main header. Note: data is not multiplied with deadtime_correction_factor.

Parameters
fpECAT file pointer
first_blockSubheader record number
last_blockLast data block number
hPtr to subheader data which is filled
fdataPtr to the address of the matrix data
Returns
0 if ok, 1 invalid input, 5 failed to read scan header, 6 invalid image (x,y,z) dimensions, 8 failed to allocate memory for meta-data, 9 failed to read matrix data, 11 failed to allocate memory for voxel data

Definition at line 959 of file ecat7r.c.

960 {
961 int ret;
962 long long i, blockNr, pxlNr;
963 char *mdata, *mptr;
964 float *_fdata, *fptr;
965 short int *sptr;
966 int *iptr;
967
968
969 if(ECAT7_TEST) printf("ecat7Read2DScanMatrix(fp, %d, %d, hdr, fdata)\n",
970 first_block, last_block);
971 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
972 sprintf(ecat7errmsg, "invalid function parameter.\n");
973 return(1);
974 }
975 *fdata=(float*)NULL;
976
977 /* Read subheader */
978 ret=ecat7Read2DScanheader(fp, first_block, h);
979 if(ret) {
980 sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
981 return(5);
982 }
983 if(ECAT7_TEST>4) ecat7Print2DScanheader(h, stdout);
984 pxlNr=h->num_r_elements*h->num_angles;
985 if(h->num_dimensions>2) pxlNr*=h->num_z_elements;
986 if(pxlNr<=0) {
987 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
988 return(6);
989 }
990
991 /* Read matrix data */
992 blockNr=last_block-first_block; if(blockNr<1) return(0);
993 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
994 if(mdata==NULL) {
995 sprintf(ecat7errmsg, "cannot allocate memory.\n");
996 return(8);
997 }
998 mptr=mdata;
999 ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
1000 if(ret || mdata==NULL) {
1001 sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
1002 free(mdata); return(9);
1003 }
1004
1005 /* Allocate memory for float data */
1006 _fdata=(float*)malloc(pxlNr*sizeof(float));
1007 if(_fdata==NULL) {
1008 sprintf(ecat7errmsg, "cannot allocate memory.\n");
1009 free(mdata); return(11);
1010 }
1011
1012 /* Convert matrix data to floats */
1013 fptr=_fdata; mptr=mdata;
1014 if(h->data_type==ECAT7_BYTE) {
1015 for(i=0; i<pxlNr; i++, mptr++, fptr++)
1016 *fptr=h->scale_factor*(float)(*mptr);
1017 } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
1018 for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
1019 sptr=(short int*)mptr;
1020 *fptr=h->scale_factor*(float)(*sptr);
1021 }
1022 } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
1023 for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
1024 iptr=(int*)mptr;
1025 *fptr=h->scale_factor*(float)(*iptr);
1026 }
1027 } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
1028 memcpy(fptr, mptr, pxlNr*4);
1029 for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
1030 }
1031 free(mdata);
1032 *fdata=_fdata;
1033
1034 return(0);
1035}
char ecat7errmsg[128]
Definition ecat7h.c:7
int ecat7ReadMatrixdata(FILE *fp, int start_block, int block_nr, char *data, int dtype)
Definition ecat7r.c:791

Referenced by imgReadEcat7(), and imgReadEcat7Frame().

◆ ecat7ReadAttenheader()

int ecat7ReadAttenheader ( FILE * fp,
int blk,
ECAT7_attenheader * h )
extern

Read ECAT 7.x attenuation header

Parameters
fpinput file pointer
blkblock number [1..number of blocks]
hEcat7 attenuation header
Returns
0 if ok, 1 == invalid parameters, 2 == first header block not found, 3 == header block not read properly

Definition at line 311 of file ecat7r.c.

311 {
312 unsigned char buf[MatBLKSIZE];
313 int little; /* 1 if current platform is little endian (i386), else 0 */
314
315 if(ECAT7_TEST) printf("ecat7ReadAttenheader()\n");
316 if(fp==NULL || h==NULL) return(1);
317 little=little_endian();
318
319 /* Seek the subheader block */
320 long long pos=(blk-1)*(long long)MatBLKSIZE;
321 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
322 /* Read the header block */
323 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
324 /* Copy the header fields and swap if necessary */
325 if(little) swabip(buf+0, 2);
326 memcpy(&h->data_type, buf+0, 2);
327 if(little) swabip(buf+2, 2);
328 memcpy(&h->num_dimensions, buf+2, 2);
329 if(little) swabip(buf+4, 2);
330 memcpy(&h->attenuation_type, buf+4, 2);
331 if(little) swabip(buf+6, 2);
332 memcpy(&h->num_r_elements, buf+6, 2);
333 if(little) swabip(buf+8, 2);
334 memcpy(&h->num_angles, buf+8, 2);
335 if(little) swabip(buf+10, 2);
336 memcpy(&h->num_z_elements, buf+10, 2);
337 if(little) swabip(buf+12, 2);
338 memcpy(&h->ring_difference, buf+12, 2);
339 if(little) swawbip(buf+14, 4);
340 memcpy(&h->x_resolution, buf+14, 4);
341 if(little) swawbip(buf+18, 4);
342 memcpy(&h->y_resolution, buf+18, 4);
343 if(little) swawbip(buf+22, 4);
344 memcpy(&h->z_resolution, buf+22, 4);
345 if(little) swawbip(buf+26, 4);
346 memcpy(&h->w_resolution, buf+26, 4);
347 if(little) swawbip(buf+30, 4);
348 memcpy(&h->scale_factor, buf+30, 4);
349 if(little) swawbip(buf+34, 4);
350 memcpy(&h->x_offset, buf+34, 4);
351 if(little) swawbip(buf+38, 4);
352 memcpy(&h->y_offset, buf+38, 4);
353 if(little) swawbip(buf+42, 4);
354 memcpy(&h->x_radius, buf+42, 4);
355 if(little) swawbip(buf+46, 4);
356 memcpy(&h->y_radius, buf+46, 4);
357 if(little) swawbip(buf+50, 4);
358 memcpy(&h->tilt_angle, buf+50, 4);
359 if(little) swawbip(buf+54, 4);
360 memcpy(&h->attenuation_coeff, buf+54, 4);
361 if(little) swawbip(buf+58, 4);
362 memcpy(&h->attenuation_min, buf+58, 4);
363 if(little) swawbip(buf+62, 4);
364 memcpy(&h->attenuation_max, buf+62, 4);
365 if(little) swawbip(buf+66, 4);
366 memcpy(&h->skull_thickness, buf+66, 4);
367 if(little) swabip(buf+70, 2);
368 memcpy(&h->num_additional_atten_coeff, buf+70, 2);
369 if(little) swawbip(buf+72, 8*4);
370 memcpy(h->additional_atten_coeff, buf+72, 8*4);
371 if(little) swawbip(buf+104, 4);
372 memcpy(&h->edge_finding_threshold, buf+104, 4);
373 if(little) swabip(buf+108, 2);
374 memcpy(&h->storage_order, buf+108, 2);
375 if(little) swabip(buf+110, 2);
376 memcpy(&h->span, buf+110, 2);
377 if(little) swabip(buf+112, 64*2);
378 memcpy(h->z_elements, buf+112, 64*2);
379 if(little) swabip(buf+240, 86*2);
380 memcpy(h->fill_cti, buf+240, 86*2);
381 if(little) swabip(buf+412, 50*2);
382 memcpy(h->fill_user, buf+412, 50*2);
383 return(0);
384}
short int fill_cti[86]
short int fill_user[50]

Referenced by ecat7PrintSubheader(), ecat7ReadSubheaderToIFT(), and ecat7WriteSubheaderFromIFT().

◆ ecat7ReadHeaders()

int ecat7ReadHeaders ( const char * fname,
ECAT_HEADERS * ehdr,
int verbose )
extern

Read ECAT7 header contents (both main header and subheaders).

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fnameImage or sinogram file name
ehdrPointer to empty headers structure
verboseVerbose level

Definition at line 687 of file ecat7ift.c.

694 {
695 ECAT7_mainheader main_header;
696 ECAT7_MATRIXLIST mlist;
697 FILE *fp;
698 int ret, mi;
699
700
701 if(verbose>0) printf("ecat7ReadHeaders(%s, ehdr)\n", fname);
702 /* Check the arguments */
703 if(ehdr==NULL) return STATUS_FAULT;
704 if(fname==NULL) return STATUS_FAULT;
705
706 /* Open the file */
707 if(verbose>1) printf("open %s\n", fname);
708 if((fp=fopen(fname, "rb")) == NULL) return STATUS_NOFILE;
709
710 /* Read main header */
711 ret=ecat7ReadMainheader(fp, &main_header);
712 if(ret) {fclose(fp); return STATUS_NOMAINHEADER;}
713 /* Check for magic number */
714 if(verbose>1) printf("check magic number in %s\n", fname);
715 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {fclose(fp); return STATUS_UNKNOWNFORMAT;}
716 /* Copy main header information into IFT */
717 ret=ecat7MHeaderToIFT(&main_header, &ehdr->mh, verbose);
718 if(ret!=STATUS_OK) {fclose(fp); return ret;}
719 if(verbose>5) iftWrite(&ehdr->mh, "stdout", 0);
720
721 /* Read matrix list */
722 ecat7InitMatlist(&mlist);
723 ret=ecat7ReadMatlist(fp, &mlist, verbose-1);
724 if(ret || mlist.matrixNr<1 || ecat7CheckMatlist(&mlist)) {fclose(fp); return STATUS_INVALIDMATLIST;}
725 /* Allocate space for each matrix */
726 ret=ehdrAllocate(ehdr, mlist.matrixNr);
727 if(ret!=STATUS_OK) {fclose(fp); ecat7EmptyMatlist(&mlist); return ret;}
728 /* Read one subheader at a time */
729 for(mi=0; mi<mlist.matrixNr; mi++) {
730 ehdr->m[mi].mnum=mlist.matdir[mi].id;
731 ecat7_id_to_val(mlist.matdir[mi].id, &ehdr->m[mi].matval);
732 if(verbose>2) {
733 printf("frame := %d\n", ehdr->m[mi].matval.frame);
734 printf("plane := %d\n", ehdr->m[mi].matval.plane);
735 printf("gate := %d\n", ehdr->m[mi].matval.gate);
736 printf("data := %d\n", ehdr->m[mi].matval.data);
737 printf("bed := %d\n", ehdr->m[mi].matval.bed);
738 }
739 ret=ecat7ReadSubheaderToIFT(fp, &main_header, mlist.matdir[mi].strtblk,
740 &ehdr->m[mi].sh, verbose);
741 if(ret!=STATUS_OK) {fclose(fp); ecat7EmptyMatlist(&mlist); return ret;}
742 //iftWrite(&ehdr->m[mi].sh, "stdout");
743 } // next matrix
744 fclose(fp); ecat7EmptyMatlist(&mlist);
745
746 return STATUS_OK;
747}
int ecat7ReadSubheaderToIFT(FILE *fp, ECAT7_mainheader *h, int strtblk, IFT *ift, int verbose)
Definition ecat7ift.c:502
int ecat7MHeaderToIFT(ECAT7_mainheader *h, IFT *ift, int verbose)
Definition ecat7ift.c:85
int ehdrAllocate(ECAT_HEADERS *ehdr, int nr)
Definition ecat7ift.c:63
int ecat7CheckMatlist(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:329
int ecat7ReadMainheader(FILE *fp, ECAT7_mainheader *h)
Definition ecat7r.c:15
ECAT_MATRIX * m
ECAT7_Matval matval

Referenced by ecat7CopyHeadersNoQuant().

◆ ecat7ReadImageheader()

int ecat7ReadImageheader ( FILE * fp,
int blk,
ECAT7_imageheader * h )
extern

Read ECAT 7.x image header

Parameters
fpinput file pointer
blkblock number [1..number of blocks]
hEcat7 image header
Returns
0 if ok, 1 == invalid parameters, 2 == first header block not found, 3 == header block not read properly

Definition at line 162 of file ecat7r.c.

162 {
163 unsigned char buf[MatBLKSIZE];
164 int little; /* 1 if current platform is little endian (i386), else 0 */
165
166 if(ECAT7_TEST) printf("ecat7ReadImageheader()\n");
167 if(fp==NULL || h==NULL) return(1);
168 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
169
170 /* Seek the subheader block */
171 long long pos=(blk-1)*(long long)MatBLKSIZE;
172 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
173 /* Read the header block */
174 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
175
176 /* Copy the header fields and swap if necessary */
177 if(little) swabip(buf+0, 2);
178 memcpy(&h->data_type, buf+0, 2);
179 if(little) swabip(buf+2, 2);
180 memcpy(&h->num_dimensions, buf+2, 2);
181 if(little) swabip(buf+4, 2);
182 memcpy(&h->x_dimension, buf+4, 2);
183 if(little) swabip(buf+6, 2);
184 memcpy(&h->y_dimension, buf+6, 2);
185 if(little) swabip(buf+8, 2);
186 memcpy(&h->z_dimension, buf+8, 2);
187 if(little) swawbip(buf+10, 4);
188 memcpy(&h->x_offset, buf+10, 4);
189 if(little) swawbip(buf+14, 4);
190 memcpy(&h->y_offset, buf+14, 4);
191 if(little) swawbip(buf+18, 4);
192 memcpy(&h->z_offset, buf+18, 4);
193 if(little) swawbip(buf+22, 4);
194 memcpy(&h->recon_zoom, buf+22, 4);
195 if(little) swawbip(buf+26, 4);
196 memcpy(&h->scale_factor, buf+26, 4);
197 if(little) swabip(buf+30, 2);
198 memcpy(&h->image_min, buf+30, 2);
199 if(little) swabip(buf+32, 2);
200 memcpy(&h->image_max, buf+32, 2);
201 if(little) swawbip(buf+34, 4);
202 memcpy(&h->x_pixel_size, buf+34, 4);
203 if(little) swawbip(buf+38, 4);
204 memcpy(&h->y_pixel_size, buf+38, 4);
205 if(little) swawbip(buf+42, 4);
206 memcpy(&h->z_pixel_size, buf+42, 4);
207 if(little) swawbip(buf+46, 4);
208 memcpy(&h->frame_duration, buf+46, 4);
209 if(little) swawbip(buf+50, 4);
210 memcpy(&h->frame_start_time, buf+50, 4);
211 if(little) swabip(buf+54, 2);
212 memcpy(&h->filter_code, buf+54, 2);
213 if(little) swawbip(buf+56, 4);
214 memcpy(&h->x_resolution, buf+56, 4);
215 if(little) swawbip(buf+60, 4);
216 memcpy(&h->y_resolution, buf+60, 4);
217 if(little) swawbip(buf+64, 4);
218 memcpy(&h->z_resolution, buf+64, 4);
219 if(little) swawbip(buf+68, 4);
220 memcpy(&h->num_r_elements, buf+68, 4);
221 if(little) swawbip(buf+72, 4);
222 memcpy(&h->num_angles, buf+72, 4);
223 if(little) swawbip(buf+76, 4);
224 memcpy(&h->z_rotation_angle, buf+76, 4);
225 if(little) swawbip(buf+80, 4);
226 memcpy(&h->decay_corr_fctr, buf+80, 4);
227 if(little) swawbip(buf+84, 4);
228 memcpy(&h->processing_code, buf+84, 4);
229 if(little) swawbip(buf+88, 4);
230 memcpy(&h->gate_duration, buf+88, 4);
231 if(little) swawbip(buf+92, 4);
232 memcpy(&h->r_wave_offset, buf+92, 4);
233 if(little) swawbip(buf+96, 4);
234 memcpy(&h->num_accepted_beats, buf+96, 4);
235 if(little) swawbip(buf+100, 4);
236 memcpy(&h->filter_cutoff_frequency, buf+100, 4);
237 if(little) swawbip(buf+104, 4);
238 memcpy(&h->filter_resolution, buf+104, 4);
239 if(little) swawbip(buf+108, 4);
240 memcpy(&h->filter_ramp_slope, buf+108, 4);
241 if(little) swabip(buf+112, 2);
242 memcpy(&h->filter_order, buf+112, 2);
243 if(little) swawbip(buf+114, 4);
244 memcpy(&h->filter_scatter_fraction, buf+114, 4);
245 if(little) swawbip(buf+118, 4);
246 memcpy(&h->filter_scatter_slope, buf+118, 4);
247 memcpy(&h->annotation, buf+122, 40);
248 if(little) swawbip(buf+162, 4);
249 memcpy(&h->mt_1_1, buf+162, 4);
250 if(little) swawbip(buf+166, 4);
251 memcpy(&h->mt_1_2, buf+166, 4);
252 if(little) swawbip(buf+170, 4);
253 memcpy(&h->mt_1_3, buf+170, 4);
254 if(little) swawbip(buf+174, 4);
255 memcpy(&h->mt_2_1, buf+174, 4);
256 if(little) swawbip(buf+178, 4);
257 memcpy(&h->mt_2_2, buf+178, 4);
258 if(little) swawbip(buf+182, 4);
259 memcpy(&h->mt_2_3, buf+182, 4);
260 if(little) swawbip(buf+186, 4);
261 memcpy(&h->mt_3_1, buf+186, 4);
262 if(little) swawbip(buf+190, 4);
263 memcpy(&h->mt_3_2, buf+190, 4);
264 if(little) swawbip(buf+194, 4);
265 memcpy(&h->mt_3_3, buf+194, 4);
266 if(little) swawbip(buf+198, 4);
267 memcpy(&h->rfilter_cutoff, buf+198, 4);
268 if(little) swawbip(buf+202, 4);
269 memcpy(&h->rfilter_resolution, buf+202, 4);
270 if(little) swabip(buf+206, 2);
271 memcpy(&h->rfilter_code, buf+206, 2);
272 if(little) swabip(buf+208, 2);
273 memcpy(&h->rfilter_order, buf+208, 2);
274 if(little) swawbip(buf+210, 4);
275 memcpy(&h->zfilter_cutoff, buf+210, 4);
276 if(little) swawbip(buf+214, 4);
277 memcpy(&h->zfilter_resolution, buf+214, 4);
278 if(little) swabip(buf+218, 2);
279 memcpy(&h->zfilter_code, buf+218, 2);
280 if(little) swabip(buf+220, 2);
281 memcpy(&h->zfilter_order, buf+220, 2);
282 if(little) swawbip(buf+222, 4);
283 memcpy(&h->mt_1_4, buf+222, 4);
284 if(little) swawbip(buf+226, 4);
285 memcpy(&h->mt_2_4, buf+226, 4);
286 if(little) swawbip(buf+230, 4);
287 memcpy(&h->mt_3_4, buf+230, 4);
288 if(little) swabip(buf+234, 2);
289 memcpy(&h->scatter_type, buf+234, 2);
290 if(little) swabip(buf+236, 2);
291 memcpy(&h->recon_type, buf+236, 2);
292 if(little) swabip(buf+238, 2);
293 memcpy(&h->recon_views, buf+238, 2);
294 memcpy(&h->fill_cti, buf+240, 174);
295 memcpy(&h->fill_user, buf+414, 96);
296
297 return(0);
298}

Referenced by ecat7GetNums(), ecat7PrintSubheader(), ecat7ReadImageMatrix(), ecat7ReadSubheaderToIFT(), ecat7WriteSubheaderFromIFT(), imgReadEcat7(), and imgReadEcat7Header().

◆ ecat7ReadImageMatrix()

int ecat7ReadImageMatrix ( FILE * fp,
int first_block,
int last_block,
ECAT7_imageheader * h,
float ** fdata )
extern

Read ECAT7 image matrix header and data. If only header is to be read, set last_block=first_block. Note: data is not calibrated with factor in main header.

Parameters
fpECAT file pointer
first_blockSubheader record number
last_blockLast data block number
hPtr to subheader data which is filled
fdataPtr to the address of the matrix data
Returns
0 if ok, 1 invalid input, 5 failed to read subheader, 6 invalid image (x,y,z) dimensions, 8 failed to allocate memory for meta-data, 9 failed to read matrix data, 11 failed to allocate memory for voxel data

Definition at line 858 of file ecat7r.c.

860 {
861 int ret;
862 long long i, blockNr, pxlNr;
863 char *mdata, *mptr;
864 float *_fdata, *fptr;
865 short int *sptr;
866 int *iptr;
867
868
869 if(ECAT7_TEST) printf("ecat7ReadImageMatrix(fp, %d, %d, hdr, fdata)\n",
870 first_block, last_block);
871 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
872 sprintf(ecat7errmsg, "invalid function parameter.\n");
873 return(1);
874 }
875 *fdata=(float*)NULL;
876
877 /* Read subheader */
878 ret=ecat7ReadImageheader(fp, first_block, h);
879 if(ret) {
880 sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
881 return(5);
882 }
883 if(ECAT7_TEST>4) ecat7PrintImageheader(h, stdout);
884 pxlNr=h->x_dimension*h->y_dimension;
885 if(h->num_dimensions>2) pxlNr*=h->z_dimension;
886 if(pxlNr<=0) {
887 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
888 return(6);
889 }
890
891 /* Read matrix data */
892 blockNr=last_block-first_block; if(blockNr<1) return(0);
893 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
894 if(mdata==NULL) {
895 sprintf(ecat7errmsg, "cannot allocate memory.\n");
896 return(8);
897 }
898 mptr=mdata;
899 ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
900 if(ret || mdata==NULL) {
901 sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
902 free(mdata); return(9);
903 }
904
905 /* Allocate memory for float data */
906 _fdata=(float*)malloc(pxlNr*sizeof(float));
907 if(_fdata==NULL) {
908 sprintf(ecat7errmsg, "cannot allocate memory.\n");
909 free(mdata); return(11);
910 }
911
912 /* Convert matrix data to floats */
913 fptr=_fdata; mptr=mdata;
914 if(h->data_type==ECAT7_BYTE) {
915 for(i=0; i<pxlNr; i++, mptr++, fptr++)
916 *fptr=h->scale_factor*(float)(*mptr);
917 } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
918 for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
919 sptr=(short int*)mptr;
920 *fptr=h->scale_factor*(float)(*sptr);
921 if(!(*fptr>-1.0E+22 && *fptr<1.0E+22)) *fptr=0.0;
922 }
923 } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
924 for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
925 iptr=(int*)mptr;
926 *fptr=h->scale_factor*(float)(*iptr);
927 if(!(*fptr>-1.0E+22 && *fptr<1.0E+22)) *fptr=0.0;
928 }
929 } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
930 memcpy(fptr, mptr, pxlNr*4);
931 for(i=0; i<pxlNr; i++, fptr++) {
932 *fptr *= h->scale_factor;
933 if(!(*fptr>-1.0E+22 && *fptr<1.0E+22)) *fptr=0.0;
934 }
935 }
936 free(mdata);
937 *fdata=_fdata;
938
939 return(0);
940}

Referenced by imgReadEcat7(), and imgReadEcat7Frame().

◆ ecat7ReadMainheader()

int ecat7ReadMainheader ( FILE * fp,
ECAT7_mainheader * h )
extern

Read ECAT 7.x main header

Returns
0 if ok, 1 == invalid parameters, 2 == first header block not found, 3 == header block not read properly
Parameters
fpinput file pointer
hEcat7 main header

Definition at line 15 of file ecat7r.c.

20 {
21 unsigned char buf[MatBLKSIZE];
22 int little; /* 1 if current platform is little endian (i386), else 0 */
23 struct tm st;
24
25 if(ECAT7_TEST) printf("ecat7ReadMainheader()\n");
26 if(fp==NULL || h==NULL) return(1);
27 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
28
29 /* Seek the first block */
30 fseek(fp, 0, SEEK_SET); if(ftell(fp)!=0) return(2);
31 /* Read the header block */
32 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
33
34 /* Copy the header fields and swap if necessary */
35 memcpy(&h->magic_number, buf+0, 14);
36 memcpy(&h->original_file_name, buf+14, 32);
37 if(little) swabip(buf+46, 2);
38 memcpy(&h->sw_version, buf+46, 2);
39 if(little) swabip(buf+48, 2);
40 memcpy(&h->system_type, buf+48, 2);
41 if(little) swabip(buf+50, 2);
42 memcpy(&h->file_type, buf+50, 2);
43 memcpy(&h->serial_number, buf+52, 10);
44 if(little) swawbip(buf+62, 4);
45 memcpy(&h->scan_start_time, buf+62, 4);
46 //printf("ecat7ReadMainheader(): scan_start_time := %d\n", h->scan_start_time);
47 memcpy(&h->isotope_name, buf+66, 8);
48 if(little) swawbip(buf+74, 4);
49 memcpy(&h->isotope_halflife, buf+74, 4);
50 memcpy(&h->radiopharmaceutical, buf+78, 32);
51 if(little) swawbip(buf+110, 4);
52 memcpy(&h->gantry_tilt, buf+110, 4);
53 if(little) swawbip(buf+114, 4);
54 memcpy(&h->gantry_rotation, buf+114, 4);
55 if(little) swawbip(buf+118, 4);
56 memcpy(&h->bed_elevation, buf+118, 4);
57 if(little) swawbip(buf+122, 4);
58 memcpy(&h->intrinsic_tilt, buf+122, 4);
59 if(little) swabip(buf+126, 2);
60 memcpy(&h->wobble_speed, buf+126, 2);
61 if(little) swabip(buf+128, 2);
62 memcpy(&h->transm_source_type, buf+128, 2);
63 if(little) swawbip(buf+130, 4);
64 memcpy(&h->distance_scanned, buf+130, 4);
65 if(little) swawbip(buf+134, 4);
66 memcpy(&h->transaxial_fov, buf+134, 4);
67 if(little) swabip(buf+138, 2);
68 memcpy(&h->angular_compression, buf+138, 2);
69 if(little) swabip(buf+140, 2);
70 memcpy(&h->coin_samp_mode, buf+140, 2);
71 if(little) swabip(buf+142, 2);
72 memcpy(&h->axial_samp_mode, buf+142, 2);
73 if(little) swawbip(buf+144, 4);
74 memcpy(&h->ecat_calibration_factor, buf+144, 4);
75 if(little) swabip(buf+148, 2);
76 memcpy(&h->calibration_units, buf+148, 2);
77 if(little) swabip(buf+150, 2);
78 memcpy(&h->calibration_units_label, buf+150, 2);
79 if(little) swabip(buf+152, 2);
80 memcpy(&h->compression_code, buf+152, 2);
81 memcpy(&h->study_type, buf+154, 12);
82 memcpy(&h->patient_id, buf+166, 16);
83 memcpy(&h->patient_name, buf+182, 32);
84 memcpy(&h->patient_sex, buf+214, 1);
85 memcpy(&h->patient_dexterity, buf+215, 1);
86 if(little) swawbip(buf+216, 4);
87 memcpy(&h->patient_age, buf+216, 4);
88 if(little) swawbip(buf+220, 4);
89 memcpy(&h->patient_height, buf+220, 4);
90 if(little) swawbip(buf+224, 4);
91 memcpy(&h->patient_weight, buf+224, 4);
92 if(little) swawbip(buf+228, 4);
93 memcpy(&h->patient_birth_date, buf+228, 4);
94 memcpy(&h->physician_name, buf+232, 32);
95 memcpy(&h->operator_name, buf+264, 32);
96 memcpy(&h->study_description, buf+296, 32);
97 if(little) swabip(buf+328, 2);
98 memcpy(&h->acquisition_type, buf+328, 2);
99 if(little) swabip(buf+330, 2);
100 memcpy(&h->patient_orientation, buf+330, 2);
101 memcpy(&h->facility_name, buf+332, 20);
102 if(little) swabip(buf+352, 2);
103 memcpy(&h->num_planes, buf+352, 2);
104 if(little) swabip(buf+354, 2);
105 memcpy(&h->num_frames, buf+354, 2);
106 if(little) swabip(buf+356, 2);
107 memcpy(&h->num_gates, buf+356, 2);
108 if(little) swabip(buf+358, 2);
109 memcpy(&h->num_bed_pos, buf+358, 2);
110 if(little) swawbip(buf+360, 4);
111 memcpy(&h->init_bed_position, buf+360, 4);
112 if(little) swawbip(buf+364, 15*4);
113 memcpy(h->bed_position, buf+364, 15*4);
114 if(little) swawbip(buf+424, 4);
115 memcpy(&h->plane_separation, buf+424, 4);
116 if(little) swabip(buf+428, 2);
117 memcpy(&h->lwr_sctr_thres, buf+428, 2);
118 if(little) swabip(buf+430, 2);
119 memcpy(&h->lwr_true_thres, buf+430, 2);
120 memcpy(&h->upr_true_thres, buf+432, 2); if(little) swabip(&h->upr_true_thres,2);
121 memcpy(&h->user_process_code, buf+434, 10);
122 if(little) swabip(buf+444, 2);
123 memcpy(&h->acquisition_mode, buf+444, 2);
124 if(little) swawbip(buf+446, 4);
125 memcpy(&h->bin_size, buf+446, 4);
126 if(little) swawbip(buf+450, 4);
127 memcpy(&h->branching_fraction, buf+450, 4);
128 if(little) swawbip(buf+454, 4);
129 memcpy(&h->dose_start_time, buf+454, 4);
130 if(little) swawbip(buf+458, 4);
131 memcpy(&h->dosage, buf+458, 4);
132 if(little) swawbip(buf+462, 4);
133 memcpy(&h->well_counter_corr_factor, buf+462,4);
134 memcpy(&h->data_units, buf+466, 32);
135 if(little) swabip(buf+498, 2);
136 memcpy(&h->septa_state, buf+498, 2);
137 memcpy(&h->fill_cti, buf+500, 12);
138
139 /* Patient birth date can have been saved in two different int formats,
140 either YYYYMMDD or as seconds from start of year 1970. In latter case
141 the number can be negative. */
142 /* Seconds from start of year 1970 are converted to YYYYMMDD format */
143 if(isdate4(h->patient_birth_date, NULL, NULL, NULL)!=0) {
144 time_t t=h->patient_birth_date; gmtime_r(&t, &st);
145 h->patient_birth_date=10000*(st.tm_year+1900)+100*(st.tm_mon+1)+st.tm_mday;
146 }
147
148 return(0);
149}
int isdate4(int dateint, int *year, int *month, int *day)
Definition datetime.c:230

Referenced by ecat7ReadHeaders(), ecat7WriteHeaders(), ecatFixMatrixlist(), imgRead(), imgReadEcat7(), imgReadEcat7Frame(), imgReadEcat7Header(), and imgWriteEcat7Frame().

◆ ecat7ReadMatlist()

int ecat7ReadMatlist ( FILE * fp,
ECAT7_MATRIXLIST * ml,
int verbose )
extern

Read ECAT matrix list.

Matrix list must be initiated (once) before calling this.

Returns
returns 0 if ok, 1 if invalid input, 2 if first matrix is not found, 3 if failed to read matrix, 4 if data allocation failed for matrix, 5 if other error occurred.
Parameters
fpFile pointer.
mlPointer to initiated matrix list.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 41 of file ecat7ml.c.

48 {
49 int err=0, little;
50 int blk=MatFirstDirBlk, next_blk=0, nr_free, prev_blk, nr_used;
51 size_t sn;
52 unsigned int dirbuf[MatBLKSIZE/4];
53
54
55 if(verbose>0) printf("ecat7ReadMatlist(fp, mlist)\n");
56 if(fp==NULL) return(1);
57 little=little_endian();
58 /* Make sure that matrix list is empty */
60 /* Seek the first list block */
61 fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
62 do {
63 /* Read the data block */
64 if(verbose>1) printf(" reading dirblock %d\n", blk);
65 sn=fread(dirbuf, sizeof(int), MatBLKSIZE/4, fp); if(sn<MatBLKSIZE/4) return(3);
66 /* Allocate (more) memory for one block */
67 if(ml->matrixSpace==0) {
69 ml->matdir=(ECAT7_MatDir*)malloc(ml->matrixSpace*sizeof(ECAT7_MatDir));
70 } else if(ml->matrixSpace<(ml->matrixNr+MatBLKSIZE/4)) {
72 ml->matdir=(ECAT7_MatDir*)realloc(ml->matdir, sizeof(ECAT7_MatDir)*ml->matrixSpace);
73 }
74 if(ml->matdir==NULL) return(4);
75 /* Byte order conversion for ints in little endian platforms */
76 if(little) swawbip(dirbuf, MatBLKSIZE);
77 /* Read "header" integers */
78 nr_free = dirbuf[0];
79 next_blk = dirbuf[1];
80 prev_blk = dirbuf[2];
81 nr_used = dirbuf[3];
82 if(verbose>2) printf("nr_free=%d next_blk=%d prev_blk=%d nr_used=%d\n", nr_free, next_blk, prev_blk, nr_used);
83 for(int i=4; i<MatBLKSIZE/4; i+=4) if(dirbuf[i]>0) {
84 ml->matdir[ml->matrixNr].id=dirbuf[i];
85 ml->matdir[ml->matrixNr].strtblk=dirbuf[i+1];
86 ml->matdir[ml->matrixNr].endblk=dirbuf[i+2];
87 ml->matdir[ml->matrixNr].status=dirbuf[i+3];
88 if(verbose>3) {
89 printf("matnum=%d strtblk=%d endblk=%d matstat=%d matrixNr=%d\n",
90 ml->matdir[ml->matrixNr].id, ml->matdir[ml->matrixNr].strtblk,
91 ml->matdir[ml->matrixNr].endblk, ml->matdir[ml->matrixNr].status,
92 ml->matrixNr);
93 }
94 ml->matrixNr++;
95 }
96 blk=next_blk;
97 /* Seek the next list block */
98 long long pos=(blk-1)*(long long)MatBLKSIZE;
99 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) err=1;
100 } while(err==0 && feof(fp)==0 && blk!=MatFirstDirBlk);
101 if(err) {ecat7EmptyMatlist(ml); return(5);}
102 return(0);
103}

Referenced by ecat7PrintSubheader(), ecat7ReadHeaders(), ecat7WriteHeaders(), ecatFixMatrixlist(), imgReadEcat7(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ ecat7ReadMatrixdata()

int ecat7ReadMatrixdata ( FILE * fp,
int start_block,
int block_nr,
char * data,
int dtype )
extern

Read ECAT7 matrix data and convert byte order if necessary Remember to allocate memory for full blocks! There are differences here when compared to ecat63.c

Parameters
fpinput file pointer
start_blockstarting block index
block_nrnumber of blocks to be read
datatarget buffer
dtypedata type of target buffer
Returns
0 if ok, 1 == invalid parameters, 9 == start block not found, 2 == data blocks read properly

Definition at line 791 of file ecat7r.c.

793 {
794 int i, n, little, err=0;
795 char *cptr;
796 float f;
797
798 if(ECAT7_TEST) printf("ecat7ReadMatrixdata(fp, %d, %d, data, %d)\n",
799 start_block, block_nr, dtype);
800 /* Check the arguments */
801 if(block_nr<=0 || start_block<1 || data==NULL) return(1);
802 /* Seek the first data block */
803 long long pos=(start_block-1)*(long long)MatBLKSIZE;
804 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(9);
805 /* Read the data blocks */
806 if(fread(data, MatBLKSIZE, block_nr, fp) < (unsigned int)block_nr) return(2);
807 /* Translate data if necessary */
808 little=little_endian();
809 switch(dtype) {
810 case ECAT7_BYTE: /* byte format...no translation necessary */
811 break;
812 case ECAT7_VAXI2: /* byte conversion necessary on big endian platform */
813 if(!little) {cptr=data; swabip(cptr, block_nr*MatBLKSIZE);}
814 break;
815 case ECAT7_VAXI4:
816 for(i=0, cptr=data; i<block_nr*MatBLKSIZE; i+=4, cptr+=4) {
817 n=ecat7rInt(cptr, 1, little); memcpy(cptr, &n, 4);
818 }
819 break;
820 case ECAT7_VAXR4:
821 for(i=0, cptr=data; i<block_nr*MatBLKSIZE; i+=4, cptr+=4) {
822 f=ecat7rFloat(cptr, 1, little); memcpy(cptr, &f, 4);
823 }
824 break;
825 case ECAT7_IEEER4: /* IEEE float ; byte conversion necessary on
826 little endian platforms */
827 case ECAT7_SUNI4: /* SUN int ; byte conversion necessary on
828 little endian platforms */
829 if(little) swawbip(data, block_nr*MatBLKSIZE);
830 break;
831 case ECAT7_SUNI2: /* SUN short ; byte conversion necessary on
832 little endian platforms */
833 if(little) swabip(data, block_nr*MatBLKSIZE);
834 break;
835 default: /* if something else, for now think it as an error */
836 err=2;
837 break;
838 }
839 return(err);
840}
float ecat7rFloat(void *bufi, int isvax, int islittle)
Definition ecat7r.c:1233
int ecat7rInt(void *bufi, int isvax, int islittle)
Definition ecat7r.c:1256

Referenced by ecat7Read2DScanMatrix(), ecat7ReadImageMatrix(), ecat7ReadPolarmapMatrix(), and ecat7ReadScanMatrix().

◆ ecat7ReadNormheader()

int ecat7ReadNormheader ( FILE * fp,
int blk,
ECAT7_normheader * h )
extern

Read ECAT 7.x 3D normalization header

Parameters
fpinput file pointer
blkblock number [1..number of blocks]
hEcat7 normalization header
Returns
0 if ok, 1 == invalid parameters, 2 == first header block not found, 3 == header block not read properly

Definition at line 472 of file ecat7r.c.

472 {
473 unsigned char buf[MatBLKSIZE];
474 int little; /* 1 if current platform is little endian (i386), else 0 */
475
476 if(ECAT7_TEST) printf("ecat7ReadNormheader()\n");
477 if(fp==NULL || h==NULL) return(1);
478 little=little_endian();
479
480 /* Seek the subheader block */
481 long long pos=(blk-1)*(long long)MatBLKSIZE;
482 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
483 /* Read the header block */
484 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
485 /* Copy the header fields and swap if necessary */
486 if(little) swabip(buf+0, 2);
487 memcpy(&h->data_type, buf+0, 2);
488 if(little) swabip(buf+2, 2);
489 memcpy(&h->num_r_elements, buf+2, 2);
490 if(little) swabip(buf+4, 2);
491 memcpy(&h->num_transaxial_crystals, buf+4, 2);
492 if(little) swabip(buf+6, 2);
493 memcpy(&h->num_crystal_rings, buf+6, 2);
494 if(little) swabip(buf+8, 2);
495 memcpy(&h->crystals_per_ring, buf+8, 2);
496 if(little) swabip(buf+10, 2);
497 memcpy(&h->num_geo_corr_planes, buf+10, 2);
498 if(little) swabip(buf+12, 2);
499 memcpy(&h->uld, buf+12, 2);
500 if(little) swabip(buf+14, 2);
501 memcpy(&h->lld, buf+14, 2);
502 if(little) swabip(buf+16, 2);
503 memcpy(&h->scatter_energy, buf+16, 2);
504 if(little) swawbip(buf+18, 4);
505 memcpy(&h->norm_quality_factor, buf+18, 4);
506 if(little) swabip(buf+22, 2);
507 memcpy(&h->norm_quality_factor_code, buf+22, 2);
508 if(little) swawbip(buf+24, 32*4);
509 memcpy(h->ring_dtcor1, buf+24, 32*4);
510 if(little) swawbip(buf+152, 32*4);
511 memcpy(h->ring_dtcor2, buf+152, 32*4);
512 if(little) swawbip(buf+280, 8*4);
513 memcpy(h->crystal_dtcor, buf+280, 8*4);
514 if(little) swabip(buf+312, 2);
515 memcpy(&h->span, buf+312, 2);
516 if(little) swabip(buf+314, 2);
517 memcpy(&h->max_ring_diff, buf+314, 2);
518 if(little) swabip(buf+316, 48*2);
519 memcpy(h->fill_cti, buf+316, 48*2);
520 if(little) swabip(buf+412, 50*2);
521 memcpy(h->fill_user, buf+412, 50*2);
522 return(0);
523}
short int fill_user[50]
short int fill_cti[48]

Referenced by ecat7PrintSubheader(), ecat7ReadSubheaderToIFT(), and ecat7WriteSubheaderFromIFT().

◆ ecat7ReadPolarmapMatrix()

int ecat7ReadPolarmapMatrix ( FILE * fp,
int first_block,
int last_block,
ECAT7_polmapheader * h,
float ** fdata )
extern

Read ECAT7 polar map matrix header and data. If only header is to be read, set last_block=first_block. Note: data is not calibrated with factor in main header.

Parameters
fpECAT file pointer
first_blockSubheader record number
last_blockLast data block number
hPtr to subheader data which is filled
fdataPtr to the address of the matrix data
Returns
0 if ok, 1 invalid input, 5 failed to read scan header, 6 invalid image (x,y,z) dimensions, 8 failed to allocate memory for meta-data, 9 failed to read matrix data, 11 failed to allocate memory for voxel data

Definition at line 1154 of file ecat7r.c.

1156 {
1157 int ret;
1158 long long i, blockNr, pxlNr;
1159 char *mdata, *mptr;
1160 float *_fdata, *fptr;
1161 short int *sptr;
1162 int *iptr;
1163
1164
1165 if(ECAT7_TEST) printf("ecat7ReadPolarmapMatrix(fp, %d, %d, hdr, fdata)\n",
1166 first_block, last_block);
1167 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) return 1;
1168 *fdata=(float*)NULL;
1169
1170 /* Read subheader */
1171 ret=ecat7ReadPolmapheader(fp, first_block, h);
1172 if(ret) {
1173 sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
1174 return 2;
1175 }
1176 if(ECAT7_TEST>4) ecat7PrintPolmapheader(h, stdout);
1177 for(i=pxlNr=0; i<h->num_rings; i++) pxlNr+=h->sectors_per_ring[i];
1178 if(pxlNr<=0) return 3;
1179
1180 /* Read matrix data */
1181 blockNr=last_block-first_block; if(blockNr<1) return 0;
1182 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
1183 if(mdata==NULL) return 4;
1184 mptr=mdata;
1185 ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
1186 if(ret || mdata==NULL) {
1187 if(mdata!=NULL) free(mdata);
1188 return 5;
1189 }
1190
1191 /* Allocate memory for float data */
1192 _fdata=(float*)malloc(pxlNr*sizeof(float));
1193 if(_fdata==NULL) {
1194 sprintf(ecat7errmsg, "cannot allocate memory.\n");
1195 free(mdata); return 4;
1196 }
1197
1198 /* Convert matrix data to floats */
1199 fptr=_fdata; mptr=mdata;
1200 if(h->data_type==ECAT7_BYTE) {
1201 for(i=0; i<pxlNr; i++, mptr++, fptr++)
1202 *fptr=h->scale_factor*(float)(*mptr);
1203 } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
1204 for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
1205 sptr=(short int*)mptr;
1206 *fptr=h->scale_factor*(float)(*sptr);
1207 }
1208 } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
1209 for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
1210 iptr=(int*)mptr;
1211 *fptr=h->scale_factor*(float)(*iptr);
1212 }
1213 } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
1214 memcpy(fptr, mptr, pxlNr*4);
1215 for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
1216 }
1217 free(mdata);
1218 *fdata=_fdata;
1219
1220 return 0;
1221}

Referenced by imgReadEcat7(), and imgReadEcat7Frame().

◆ ecat7ReadPolmapheader()

int ecat7ReadPolmapheader ( FILE * fp,
int blk,
ECAT7_polmapheader * h )
extern

Read ECAT 7.x polar map header

Parameters
fpinput file pointer
blkblock number [1..number of blocks]
hEcat7 polar map header
Returns
0 if ok, 1 == invalid parameters, 2 == first header block not found, 3 == header block not read properly

Definition at line 397 of file ecat7r.c.

397 {
398 unsigned char buf[MatBLKSIZE];
399 int little; /* 1 if current platform is little endian (i386), else 0 */
400
401 if(ECAT7_TEST) printf("ecat7ReadPolarmapheader()\n");
402 if(fp==NULL || h==NULL) return(1);
403 little=little_endian();
404
405 /* Seek the subheader block */
406 long long pos=(blk-1)*(long long)MatBLKSIZE;
407 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
408 /* Read the header block */
409 if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
410 /* Copy the header fields and swap if necessary */
411 if(little) swabip(buf+0, 2);
412 memcpy(&h->data_type, buf+0, 2);
413 if(little) swabip(buf+2, 2);
414 memcpy(&h->polar_map_type, buf+2, 2);
415 if(little) swabip(buf+4, 2);
416 memcpy(&h->num_rings, buf+4, 2);
417 if(little) swabip(buf+6, 32*2);
418 memcpy(h->sectors_per_ring, buf+6, 32*2);
419 if(little) swawbip(buf+70, 32*4);
420 memcpy(h->ring_position, buf+70, 32*4);
421 if(little) swabip(buf+198, 32*2);
422 memcpy(h->ring_angle, buf+198, 32*2);
423 if(little) swabip(buf+262, 2);
424 memcpy(&h->start_angle, buf+262, 2);
425 if(little) swabip(buf+264, 3*2);
426 memcpy(h->long_axis_left, buf+264, 3*2);
427 if(little) swabip(buf+270, 3*2);
428 memcpy(h->long_axis_right, buf+270, 3*2);
429 if(little) swabip(buf+276, 2);
430 memcpy(&h->position_data, buf+276, 2);
431 if(little) swabip(buf+278, 2);
432 memcpy(&h->image_min, buf+278, 2);
433 if(little) swabip(buf+280, 2);
434 memcpy(&h->image_max, buf+280, 2);
435 if(little) swawbip(buf+282, 4);
436 memcpy(&h->scale_factor, buf+282, 4);
437 if(little) swawbip(buf+286, 4);
438 memcpy(&h->pixel_size, buf+286, 4);
439 if(little) swawbip(buf+290, 4);
440 memcpy(&h->frame_duration, buf+290, 4);
441 if(little) swawbip(buf+294, 4);
442 memcpy(&h->frame_start_time, buf+294, 4);
443 if(little) swabip(buf+298, 2);
444 memcpy(&h->processing_code, buf+298, 2);
445 if(little) swabip(buf+300, 2);
446 memcpy(&h->quant_units, buf+300, 2);
447 memcpy(h->annotation, buf+302, 40);
448 if(little) swawbip(buf+342, 4);
449 memcpy(&h->gate_duration, buf+342, 4);
450 if(little) swawbip(buf+346, 4);
451 memcpy(&h->r_wave_offset, buf+346, 4);
452 if(little) swawbip(buf+350, 4);
453 memcpy(&h->num_accepted_beats, buf+350, 4);
454 memcpy(h->polar_map_protocol, buf+354, 20);
455 memcpy(h->database_name, buf+374, 30);
456 if(little) swabip(buf+404, 27*2);
457 memcpy(h->fill_cti, buf+404, 27*2);
458 return(0);
459}
short int fill_cti[27]

Referenced by ecat7PrintSubheader(), ecat7ReadPolarmapMatrix(), ecat7ReadSubheaderToIFT(), ecat7WriteSubheaderFromIFT(), imgReadEcat7(), and imgReadEcat7Header().

◆ ecat7ReadScanheader()

int ecat7ReadScanheader ( FILE * fp,
int blk,
ECAT7_scanheader * h )
extern

Read ECAT 7.x 3D scan header (512 bytes)

Parameters
fpinput file pointer
blkblock number [1..number of blocks]
hEcat7 scan header
Returns
0 if ok, 1 == invalid parameters, 2 == first header block not found, 3 == header block not read properly

Definition at line 536 of file ecat7r.c.

536 {
537 unsigned char buf[2*MatBLKSIZE];
538 int little; /* 1 if current platform is little endian (i386), else 0 */
539
540 if(ECAT7_TEST) printf("ecat7ReadScanheader()\n");
541 if(fp==NULL || h==NULL) return(1);
542 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
543
544 /* Seek the subheader block */
545 long long pos=(blk-1)*(long long)MatBLKSIZE;
546 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
547 /* Read the header block */
548 if(fread(buf, MatBLKSIZE, 2, fp)<1) return(3);
549
550 /* Copy the header fields and swap if necessary */
551 if(little) swabip(buf+0, 2);
552 memcpy(&h->data_type, buf+0, 2);
553 if(little) swabip(buf+2, 2);
554 memcpy(&h->num_dimensions, buf+2, 2);
555 if(little) swabip(buf+4, 2);
556 memcpy(&h->num_r_elements, buf+4, 2);
557 if(little) swabip(buf+6, 2);
558 memcpy(&h->num_angles, buf+6, 2);
559 if(little) swabip(buf+8, 2);
560 memcpy(&h->corrections_applied, buf+8, 2);
561 if(little) swabip(buf+10, 64*2);
562 memcpy(h->num_z_elements, buf+10, 64*2);
563 if(little) swabip(buf+138, 2);
564 memcpy(&h->ring_difference, buf+138, 2);
565 if(little) swabip(buf+140, 2);
566 memcpy(&h->storage_order, buf+140, 2);
567 if(little) swabip(buf+142, 2);
568 memcpy(&h->axial_compression, buf+142, 2);
569 if(little) swawbip(buf+144, 4);
570 memcpy(&h->x_resolution, buf+144, 4);
571 if(little) swawbip(buf+148, 4);
572 memcpy(&h->v_resolution, buf+148, 4);
573 if(little) swawbip(buf+152, 4);
574 memcpy(&h->z_resolution, buf+152, 4);
575 if(little) swawbip(buf+156, 4);
576 memcpy(&h->w_resolution, buf+156, 4);
577 if(little) swabip(buf+160, 6*2);
578 memcpy(h->fill_gate, buf+160, 6*2);
579 if(little) swawbip(buf+172, 4);
580 memcpy(&h->gate_duration, buf+172, 4);
581 if(little) swawbip(buf+176, 4);
582 memcpy(&h->r_wave_offset, buf+176, 4);
583 if(little) swawbip(buf+180, 4);
584 memcpy(&h->num_accepted_beats, buf+180, 4);
585 if(little) swawbip(buf+184, 4);
586 memcpy(&h->scale_factor, buf+184, 4);
587 if(little) swabip(buf+188, 2);
588 memcpy(&h->scan_min, buf+188, 2);
589 if(little) swabip(buf+190, 2);
590 memcpy(&h->scan_max, buf+190, 2);
591 if(little) swawbip(buf+192, 4);
592 memcpy(&h->prompts, buf+192, 4);
593 if(little) swawbip(buf+196, 4);
594 memcpy(&h->delayed, buf+196, 4);
595 if(little) swawbip(buf+200, 4);
596 memcpy(&h->multiples, buf+200, 4);
597 if(little) swawbip(buf+204, 4);
598 memcpy(&h->net_trues, buf+204, 4);
599 if(little) swawbip(buf+208, 4);
600 memcpy(&h->tot_avg_cor, buf+208, 4);
601 if(little) swawbip(buf+212, 4);
602 memcpy(&h->tot_avg_uncor, buf+212, 4);
603 if(little) swawbip(buf+216, 4);
604 memcpy(&h->total_coin_rate, buf+216, 4);
605 if(little) swawbip(buf+220, 4);
606 memcpy(&h->frame_start_time, buf+220, 4);
607 if(little) swawbip(buf+224, 4);
608 memcpy(&h->frame_duration, buf+224, 4);
609 if(little) swawbip(buf+228, 4);
610 memcpy(&h->deadtime_correction_factor, buf+228,4);
611 if(little) swabip(buf+232, 90*2);
612 memcpy(h->fill_cti, buf+232, 90*2);
613 if(little) swabip(buf+412, 50*2);
614 memcpy(h->fill_user, buf+412, 50*2);
615 if(little) swawbip(buf+512, 128*4);
616 memcpy(h->uncor_singles, buf+512, 128*4);
617 return(0);
618}

Referenced by ecat7GetNums(), ecat7PrintSubheader(), ecat7ReadScanMatrix(), ecat7ReadSubheaderToIFT(), ecat7WriteSubheaderFromIFT(), imgReadEcat7(), and imgReadEcat7Header().

◆ ecat7ReadScanMatrix()

int ecat7ReadScanMatrix ( FILE * fp,
int first_block,
int last_block,
ECAT7_scanheader * h,
float ** fdata )
extern

Read ECAT7 3D sinogram matrix header and data. Memory for fdata[] is allocated here, remember to free memory after usage. Note: data is converted to floats with scale_factor in the scan matrix header. Note: data is not calibrated with ecat_calibration_factor in main header. Note: data is not multiplied with deadtime_correction_factor.

Parameters
fpECAT file pointer
first_blockSubheader record number
last_blockLast data block number
hPtr to subheader data which is filled
fdataPtr to the address of the matrix data
Returns
0 if ok, 1 invalid input, 5 failed to read scan header, 6 invalid image (x,y,z) dimensions, 8 failed to allocate memory for meta-data, 9 failed to read matrix data, 11 failed to allocate memory for voxel data

Definition at line 1055 of file ecat7r.c.

1057 {
1058 int ret;
1059 long long i, blockNr, trueblockNr, pxlNr, dimz;
1060 char *mdata, *mptr;
1061 float *_fdata, *fptr;
1062 short int *sptr;
1063 int *iptr;
1064
1065
1066 if(ECAT7_TEST) printf("ecat7ReadScanMatrix(fp, %d, %d, hdr, fdata)\n",
1067 first_block, last_block);
1068 if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
1069 sprintf(ecat7errmsg, "invalid function parameter.\n");
1070 return(1);
1071 }
1072 *fdata=(float*)NULL;
1073
1074 /* Read subheader */
1075 ret=ecat7ReadScanheader(fp, first_block, h);
1076 if(ret) {
1077 sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
1078 return(5);
1079 }
1080 if(ECAT7_TEST>4) ecat7PrintScanheader(h, stdout);
1081 pxlNr=h->num_r_elements*h->num_angles;
1082 for(i=dimz=0; i<64; i++) dimz+=h->num_z_elements[i];
1083 pxlNr*=dimz;
1084 if(pxlNr<=0) {
1085 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
1086 return(6);
1087 }
1088 trueblockNr=pxlNr*ecat7pxlbytes(h->data_type);
1089 trueblockNr=(trueblockNr+MatBLKSIZE-1)/MatBLKSIZE;
1090
1091 /* Read matrix data; note that header takes 2 blocks */
1092 blockNr=last_block-first_block-1; if(blockNr<1) return(0);
1093 if(blockNr<trueblockNr) trueblockNr=blockNr;
1094 mdata=(char*)malloc((size_t)blockNr*MatBLKSIZE);
1095 if(mdata==NULL) {
1096 sprintf(ecat7errmsg, "cannot allocate memory.\n");
1097 return(8);
1098 }
1099 mptr=mdata; /* note that only true block nr is read! */
1100 ret=ecat7ReadMatrixdata(fp, first_block+2, trueblockNr, mptr, h->data_type);
1101 if(ret || mdata==NULL) {
1102 sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
1103 free(mdata); return(9);
1104 }
1105
1106 /* Allocate memory for float data */
1107 _fdata=(float*)malloc(pxlNr*sizeof(float));
1108 if(_fdata==NULL) {
1109 sprintf(ecat7errmsg, "cannot allocate memory.\n");
1110 free(mdata); return(11);
1111 }
1112
1113 /* Convert matrix data to floats */
1114 fptr=_fdata; mptr=mdata;
1115 if(h->data_type==ECAT7_BYTE) {
1116 for(i=0; i<pxlNr; i++, mptr++, fptr++)
1117 *fptr=h->scale_factor*(float)(*mptr);
1118 } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
1119 for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
1120 sptr=(short int*)mptr;
1121 *fptr=h->scale_factor*(float)(*sptr);
1122 }
1123 } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
1124 for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
1125 iptr=(int*)mptr;
1126 *fptr=h->scale_factor*(float)(*iptr);
1127 }
1128 } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
1129 memcpy(fptr, mptr, pxlNr*4);
1130 for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
1131 }
1132 free(mdata);
1133 *fdata=_fdata;
1134
1135 return(0);
1136}
int ecat7pxlbytes(short int data_type)
Definition ecat7r.c:1274

Referenced by imgReadEcat7(), and imgReadEcat7Frame().

◆ ecat7ReadSubheaderToIFT()

int ecat7ReadSubheaderToIFT ( FILE * fp,
ECAT7_mainheader * h,
int strtblk,
IFT * ift,
int verbose )
extern

Read ECAT 7 subheader from file and store in IFT struct.

Returns
Returns STATUS_OK when succesful.
Parameters
fpFile pointer to opened ECAT7 file
hECAT7 mainheader
strtblkSubheader location
iftPreallocated location for header data
verboseVerbose level

Definition at line 502 of file ecat7ift.c.

513 {
514 ECAT7_imageheader image_header;
515 ECAT7_scanheader scan_header;
516 ECAT7_2Dscanheader scan2D_header;
517 ECAT7_2Dnormheader norm2D_header;
518 ECAT7_normheader norm_header;
519 ECAT7_attenheader atten_header;
520 ECAT7_polmapheader polmap_header;
521 int ret;
522
523 if(verbose>0) printf("ecat7ReadSubheaderToIFT(fp, mh, %d, ift)\n", strtblk);
524 /* Check input */
525 if(fp==NULL || h==NULL || strtblk<3 || ift==NULL) return STATUS_FAULT;
526
527 /* Read subheader and copy into IFT */
528 //if(iftPut(ift, "test_key", "test_value", NULL)!=0) return STATUS_UNSUPPORTED;
529 switch(h->file_type) {
530 case ECAT7_ATTEN:
531 ret=ecat7ReadAttenheader(fp, strtblk, &atten_header);
532 if(ret!=0) return STATUS_NOSUBHEADER;
533 return STATUS_UNSUPPORTED;
534 break;
535 case ECAT7_3DNORM:
536 ret=ecat7ReadNormheader(fp, strtblk, &norm_header);
537 if(ret!=0) return STATUS_NOSUBHEADER;
538 return STATUS_UNSUPPORTED;
539 break;
540 case ECAT7_IMAGE8:
541 case ECAT7_IMAGE16:
542 case ECAT7_VOLUME8:
543 case ECAT7_VOLUME16:
544 ret=ecat7ReadImageheader(fp, strtblk, &image_header);
545 if(ret!=0) return STATUS_NOSUBHEADER;
546 ret=ecat7ImageheaderToIFT(&image_header, ift, verbose);
547 if(ret!=STATUS_OK) return ret;
548 break;
549 case ECAT7_3DSCAN:
550 case ECAT7_3DSCAN8:
551 case ECAT7_3DSCANFIT:
552 ret=ecat7ReadScanheader(fp, strtblk, &scan_header);
553 if(ret!=0) return STATUS_NOSUBHEADER;
554 ret=ecat7ScanheaderToIFT(&scan_header, ift, verbose);
555 if(ret!=STATUS_OK) return ret;
556 ret=ecat7WriteScanheader(fp, strtblk, &scan_header);
557 break;
558 case ECAT7_POLARMAP:
559 ret=ecat7ReadPolmapheader(fp, strtblk, &polmap_header);
560 if(ret!=0) return STATUS_NOSUBHEADER;
561 return STATUS_UNSUPPORTED;
562 break;
563 case ECAT7_2DSCAN:
564 ret=ecat7Read2DScanheader(fp, strtblk, &scan2D_header);
565 if(ret!=0) return STATUS_NOSUBHEADER;
566 return STATUS_UNSUPPORTED;
567 break;
568 case ECAT7_2DNORM:
569 ret=ecat7Read2DNormheader(fp, strtblk, &norm2D_header);
570 if(ret!=0) return STATUS_NOSUBHEADER;
571 return STATUS_UNSUPPORTED;
572 break;
573 default:
574 return STATUS_UNSUPPORTED;
575 }
576 return STATUS_OK;
577}
int ecat7ScanheaderToIFT(ECAT7_scanheader *h, IFT *ift, int verbose)
Definition ecat7ift.c:408
int ecat7ImageheaderToIFT(ECAT7_imageheader *h, IFT *ift, int verbose)
Definition ecat7ift.c:251
int ecat7WriteScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition ecat7w.c:383

Referenced by ecat7ReadHeaders().

◆ ecat7rFloat()

float ecat7rFloat ( void * bufi,
int isvax,
int islittle )
extern

Read ECAT7 floats

Parameters
bufipointer to 32-bit data block
isvax!= 0 for VAX format
islittle!= 0 for little endian conversion
Returns
data in bufi as float value

Definition at line 1233 of file ecat7r.c.

1233 {
1234 union {unsigned int ul; float f;} t;
1235
1236 memcpy(&t.ul, bufi, 4); if(t.ul==0) {return(0.0);}
1237 if(isvax) { /* if input is in VAX format */
1238 /* Swap words on i386 and bytes on SUN */
1239 if(islittle) swawip(&t.ul, 4); else swabip(&t.ul, 4);
1240 t.ul-=(2L<<23); /* subtract 2 from exp */
1241 } else { /* input is in i386 format */
1242 if(!islittle) swawbip(&t.ul, 4); /* Switch words and bytes on SUN */
1243 }
1244 return(t.f);
1245}

Referenced by ecat7ReadMatrixdata().

◆ ecat7rInt()

int ecat7rInt ( void * bufi,
int isvax,
int islittle )
extern

Reading and writing ECAT7 32-bit ints 32-bit int format is same in VAX and i386

Parameters
bufipointer to one 32-bit data block
isvaxignored
islittle!= 0 for little endian conversion
Returns
converted 32-bit integer

Definition at line 1256 of file ecat7r.c.

1256 {
1257 int i;
1258
1259 if(isvax==0) {} // prevent compiler warning
1260 /* Swap both words and bytes on SUN */
1261 memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4);
1262 return(i);
1263}

Referenced by ecat7ReadMatrixdata().

◆ ecat7ScanheaderToIFT()

int ecat7ScanheaderToIFT ( ECAT7_scanheader * h,
IFT * ift,
int verbose )
extern

Copy ECAT 7 scan header into IFT struct.

Returns
Returns STATUS_OK when succesful.
Parameters
hPointer to source ECAT 7 scan header
iftPointer to initiated IFT struct. Any previous contents are preserved.
verboseVerbose level

Definition at line 408 of file ecat7ift.c.

415 {
416 int i;
417 char tmp[1024], tmp2[32];
418
419 if(verbose>0) printf("ecat7ScanheaderToIFT(h, ift)\n");
420 if(h==NULL || ift==NULL) return STATUS_FAULT;
421 if(h->data_type<=0) return STATUS_UNKNOWNFORMAT;
422
423 sprintf(tmp, "%d", h->data_type);
424 if(iftPut(ift, "data_type", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
425 sprintf(tmp, "%d", h->num_dimensions);
426 if(iftPut(ift, "num_dimensions", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
427 sprintf(tmp, "%d", h->num_r_elements);
428 if(iftPut(ift, "num_r_elements", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
429 sprintf(tmp, "%d", h->num_angles);
430 if(iftPut(ift, "num_angles", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
431 sprintf(tmp, "%d", h->corrections_applied);
432 if(iftPut(ift, "corrections_applied", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
433 sprintf(tmp, "%d", h->num_z_elements[0]);
434 for(i=1; i<64; i++) {sprintf(tmp2, " %d", h->fill_cti[i]); strcat(tmp, tmp2);}
435 if(iftPut(ift, "num_z_elements", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
436 sprintf(tmp, "%d", h->ring_difference);
437 if(iftPut(ift, "ring_difference", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
438 sprintf(tmp, "%d", h->storage_order);
439 if(iftPut(ift, "storage_order", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
440 sprintf(tmp, "%d", h->axial_compression);
441 if(iftPut(ift, "axial_compression", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
442 sprintf(tmp, "%g", h->x_resolution);
443 if(iftPut(ift, "x_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
444 sprintf(tmp, "%g", h->v_resolution);
445 if(iftPut(ift, "v_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
446 sprintf(tmp, "%g", h->z_resolution);
447 if(iftPut(ift, "z_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
448 sprintf(tmp, "%g", h->w_resolution);
449 if(iftPut(ift, "w_resolution", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
450 sprintf(tmp, "%d", h->gate_duration);
451 if(iftPut(ift, "gate_duration", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
452 sprintf(tmp, "%d", h->r_wave_offset);
453 if(iftPut(ift, "r_wave_offset", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
454 sprintf(tmp, "%d", h->num_accepted_beats);
455 if(iftPut(ift, "num_accepted_beats", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
456 sprintf(tmp, "%E", h->scale_factor);
457 if(iftPut(ift, "scale_factor", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
458 sprintf(tmp, "%d", h->scan_min);
459 if(iftPut(ift, "scan_min", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
460 sprintf(tmp, "%d", h->scan_max);
461 if(iftPut(ift, "scan_max", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
462 sprintf(tmp, "%d", h->prompts);
463 if(iftPut(ift, "prompts", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
464 sprintf(tmp, "%d", h->delayed);
465 if(iftPut(ift, "delayed", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
466 sprintf(tmp, "%d", h->multiples);
467 if(iftPut(ift, "multiples", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
468 sprintf(tmp, "%d", h->net_trues);
469 if(iftPut(ift, "net_trues", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
470 sprintf(tmp, "%g", h->tot_avg_cor);
471 if(iftPut(ift, "tot_avg_cor", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
472 sprintf(tmp, "%g", h->tot_avg_uncor);
473 if(iftPut(ift, "tot_avg_uncor", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
474 sprintf(tmp, "%d", h->total_coin_rate);
475 if(iftPut(ift, "total_coin_rate", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
476 sprintf(tmp, "%d", h->frame_start_time);
477 if(iftPut(ift, "frame_start_time", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
478 sprintf(tmp, "%d", h->frame_duration);
479 if(iftPut(ift, "frame_duration", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
480 sprintf(tmp, "%g", h->deadtime_correction_factor);
481 if(iftPut(ift, "deadtime_correction_factor", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
482 sprintf(tmp, "%g", h->uncor_singles[0]);
483 for(i=1; i<128; i++) {sprintf(tmp2, " %g", h->uncor_singles[i]); strcat(tmp, tmp2);}
484 if(iftPut(ift, "uncor_singles", tmp, NULL, 0)!=0) return STATUS_UNSUPPORTED;
485
486/*
487 if(iftPut(ift, "", h->, NULL)!=0) return STATUS_UNSUPPORTED;
488
489 sprintf(tmp, "%g", h->);
490 if(iftPut(ift, "", tmp, NULL)!=0) return STATUS_UNSUPPORTED;
491
492 sprintf(tmp, "%d", h->);
493 if(iftPut(ift, "", tmp, NULL)!=0) return STATUS_UNSUPPORTED;
494 */
495 return STATUS_OK;
496}

Referenced by ecat7ReadSubheaderToIFT().

◆ ecat7SortMatlistByFrame()

void ecat7SortMatlistByFrame ( ECAT7_MATRIXLIST * ml)
extern

Sort matrixlist by frame and plane. Bubble sorting algorithm.

Parameters
mltarget matrix list

Definition at line 303 of file ecat7ml.c.

303 {
304 int i, j;
305 ECAT7_Matval mv1, mv2;
306 ECAT7_MatDir tmpMatdir;
307
308 for(i=0; i<ml->matrixNr-1; i++) {
309 ecat7_id_to_val(ml->matdir[i].id, &mv1);
310 for(j=i+1; j<ml->matrixNr; j++) {
311 ecat7_id_to_val(ml->matdir[j].id, &mv2);
312 if(mv2.frame<mv1.frame||(mv2.frame==mv1.frame&&mv2.plane<mv1.plane)) {
313 tmpMatdir=ml->matdir[i];
314 ml->matdir[i]=ml->matdir[j]; ml->matdir[j]=tmpMatdir;
315 ecat7_id_to_val(ml->matdir[i].id, &mv1);
316 }
317 }
318 }
319}

Referenced by imgReadEcat7Frame().

◆ ecat7SortMatlistByPlane()

void ecat7SortMatlistByPlane ( ECAT7_MATRIXLIST * ml)
extern

Sort matrixlist by plane and frame. Bubble sorting algorithm.

Parameters
mltarget matrix list

Definition at line 277 of file ecat7ml.c.

277 {
278 int i, j;
279 ECAT7_Matval mv1, mv2;
280 ECAT7_MatDir tmpMatdir;
281
282 for(i=0; i<ml->matrixNr-1; i++) {
283 ecat7_id_to_val(ml->matdir[i].id, &mv1);
284 for(j=i+1; j<ml->matrixNr; j++) {
285 ecat7_id_to_val(ml->matdir[j].id, &mv2);
286 if(mv2.plane<mv1.plane||(mv2.plane==mv1.plane&&mv2.frame<mv1.frame)) {
287 tmpMatdir=ml->matdir[i];
288 ml->matdir[i]=ml->matdir[j];
289 ml->matdir[j]=tmpMatdir;
290 ecat7_id_to_val(ml->matdir[i].id, &mv1);
291 }
292 }
293 }
294}

Referenced by ecat7GetPlaneAndFrameNr(), and imgReadEcat7().

◆ ecat7Write2DNormheader()

int ecat7Write2DNormheader ( FILE * fp,
int blk,
ECAT7_2Dnormheader * h )
extern

Write ECAT 7.x 2D normalization header.

Parameters
fpfile pointer
blkheader block number, blk >= 2
hEcat7 2D normalization header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 517 of file ecat7w.c.

517 {
518 unsigned char buf[MatBLKSIZE];
519 int little; /* 1 if current platform is little endian (i386), else 0 */
520
521 if(ECAT7_TEST) printf("ecat7Write2DNormheader()\n");
522 if(fp==NULL || blk<2 || h==NULL) return(1);
523 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
524 /* Clear buf */
525 memset(buf, 0, MatBLKSIZE);
529
530 /* Copy the header fields and swap if necessary */
531 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
532 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
533 memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
534 memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
535 memcpy(buf+8, &h->num_z_elements, 2); if(little) swabip(buf+8, 2);
536 memcpy(buf+10, &h->ring_difference, 2); if(little) swabip(buf+10, 2);
537 memcpy(buf+12, &h->scale_factor, 4); if(little) swawbip(buf+12, 4);
538 memcpy(buf+16, &h->norm_min, 4); if(little) swawbip(buf+16, 4);
539 memcpy(buf+20, &h->norm_max, 4); if(little) swawbip(buf+20, 4);
540 memcpy(buf+24, &h->fov_source_width, 4); if(little) swawbip(buf+24, 4);
541 memcpy(buf+28, &h->norm_quality_factor, 4); if(little) swawbip(buf+28, 4);
542 memcpy(buf+32, &h->norm_quality_factor_code, 2); if(little) swabip(buf+32, 2);
543 memcpy(buf+34, &h->storage_order, 2); if(little) swabip(buf+34, 2);
544 memcpy(buf+36, &h->span, 2); if(little) swabip(buf+36, 2);
545 memcpy(buf+38, h->fill_cti, 64*2); if(little) swabip(buf+38, 64*2);
546 memcpy(buf+166, h->fill_cti, 123*2); if(little) swabip(buf+166, 123*2);
547 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
548
549 /* Write header */
550 long long pos=(blk-1)*(long long)MatBLKSIZE;
551 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
552 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
553
554 return(0);
555}

◆ ecat7Write2DScanheader()

int ecat7Write2DScanheader ( FILE * fp,
int blk,
ECAT7_2Dscanheader * h )
extern

Write ECAT 7.x 2D scan header

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 2D scan header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 450 of file ecat7w.c.

450 {
451 unsigned char buf[MatBLKSIZE];
452 int little; /* 1 if current platform is little endian (i386), else 0 */
453
454 if(ECAT7_TEST) printf("ecat7Write2DScanheader()\n");
455 if(fp==NULL || blk<2 || h==NULL) return(1);
456 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
457 /* Clear buf */
458 memset(buf, 0, MatBLKSIZE);
462
463 /* Copy the header fields and swap if necessary */
464 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
465 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
466 memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
467 memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
468 memcpy(buf+8, &h->corrections_applied, 2); if(little) swabip(buf+8, 2);
469 memcpy(buf+10, &h->num_z_elements, 2); if(little) swabip(buf+10, 2);
470 memcpy(buf+12, &h->ring_difference, 2); if(little) swabip(buf+12, 2);
471 memcpy(buf+14, &h->x_resolution, 4); if(little) swawbip(buf+14, 4);
472 memcpy(buf+18, &h->y_resolution, 4); if(little) swawbip(buf+18, 4);
473 memcpy(buf+22, &h->z_resolution, 4); if(little) swawbip(buf+22, 4);
474 memcpy(buf+26, &h->w_resolution, 4); if(little) swawbip(buf+26, 4);
475 memcpy(buf+30, h->fill_gate, 6*2); if(little) swabip(buf+30, 6*2);
476 memcpy(buf+42, &h->gate_duration, 4); if(little) swawbip(buf+42, 4);
477 memcpy(buf+46, &h->r_wave_offset, 4); if(little) swawbip(buf+46, 4);
478 memcpy(buf+50, &h->num_accepted_beats, 4); if(little) swawbip(buf+50, 4);
479 memcpy(buf+54, &h->scale_factor, 4); if(little) swawbip(buf+54, 4);
480 memcpy(buf+58, &h->scan_min, 2); if(little) swabip(buf+58, 2);
481 memcpy(buf+60, &h->scan_max, 2); if(little) swabip(buf+60, 2);
482 memcpy(buf+62, &h->prompts, 4); if(little) swawbip(buf+62, 4);
483 memcpy(buf+66, &h->delayed, 4); if(little) swawbip(buf+66, 4);
484 memcpy(buf+70, &h->multiples, 4); if(little) swawbip(buf+70, 4);
485 memcpy(buf+74, &h->net_trues, 4); if(little) swawbip(buf+74, 4);
486 memcpy(buf+78, h->cor_singles, 16*4); if(little) swawbip(buf+78, 16*4);
487 memcpy(buf+142, h->uncor_singles, 16*4); if(little) swawbip(buf+142, 16*4);
488 memcpy(buf+206, &h->tot_avg_cor, 4); if(little) swawbip(buf+206, 4);
489 memcpy(buf+210, &h->tot_avg_uncor, 4); if(little) swawbip(buf+210, 4);
490 memcpy(buf+214, &h->total_coin_rate, 4); if(little) swawbip(buf+214, 4);
491 memcpy(buf+218, &h->frame_start_time, 4); if(little) swawbip(buf+218, 4);
492 memcpy(buf+222, &h->frame_duration, 4); if(little) swawbip(buf+222, 4);
493 memcpy(buf+226, &h->deadtime_correction_factor, 4); if(little) swawbip(buf+226, 4);
494 memcpy(buf+230, h->physical_planes, 8*2); if(little) swabip(buf+230, 8*2);
495 memcpy(buf+246, h->fill_cti, 83*2); if(little) swabip(buf+246, 83*2);
496 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
497
498 /* Write header */
499 long long pos=(blk-1)*(long long)MatBLKSIZE;
500 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
501 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
502
503 return(0);
504}

Referenced by ecat7Write2DScanMatrix().

◆ ecat7Write2DScanMatrix()

int ecat7Write2DScanMatrix ( FILE * fp,
int matrix_id,
ECAT7_2Dscanheader * h,
float * fdata )
extern

Write ECAT 7.x 2D sinogram matrix header and data

Parameters
fpoutput file pointer
matrix_idcoded matrix id
hEcat7 2D image scan header
fdatafloat data to be written
Returns
0 if ok.

Definition at line 719 of file ecat7w.c.

719 {
720 int ret;
721 long long i, data_size, nxtblk, blkNr, pxlNr;
722 float *fptr, fmin, fmax, g, f;
723 char *mdata, *mptr;
724 short int *sptr;
725
726
727 if(ECAT7_TEST) printf("ecat7Write2DScanMatrix(fp, %d, h, data)\n", matrix_id);
728 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
729 sprintf(ecat7errmsg, "invalid function parameter.\n");
730 return(1);
731 }
732 if(h->data_type!=ECAT7_SUNI2) {
733 sprintf(ecat7errmsg, "invalid data_type.\n");
734 return(2);
735 }
736 /* nr of pixels */
737 pxlNr=h->num_r_elements*h->num_angles;
738 if(h->num_dimensions>2) pxlNr*=h->num_z_elements;
739 if(pxlNr<1) {
740 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
741 return(3);
742 }
743 /* How much memory is needed for ALL pixels */
744 data_size=pxlNr*ecat7pxlbytes(h->data_type);
745 /* block nr taken by all pixels */
746 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
747 sprintf(ecat7errmsg, "invalid block number.\n");
748 return(4);
749 }
750 /* Allocate memory for matrix data */
751 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
752 sprintf(ecat7errmsg, "out of memory.\n");
753 return(5);
754 }
755 /* Search for min and max for calculation of scale factor */
756 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
757 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
758 if(g>0) f=32766./g; else f=1.0;
759 /* Check if pixels values can be left as such with scale_factor = 1 */
760 fptr=fdata;
761 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
762 /* Scale matrix data to shorts */
763 h->scale_factor=1.0/f;
764 sptr=(short int*)mdata; fptr=fdata;
765 for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
766 /* Set header short min & max */
767 h->scan_min=(short int)temp_roundf(f*fmin);
768 h->scan_max=(short int)temp_roundf(f*fmax);
769 /* Get block number for matrix header and data */
770 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
771 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
772 free(mdata); return(8);
773 }
774 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
775 /* Write header */
776 ret=ecat7Write2DScanheader(fp, nxtblk, h); if(ret) {
777 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
778 free(mdata); return(10);
779 }
780 /* Write matrix data */
781 mptr=mdata;
782 ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
783 free(mdata);
784 if(ret) {
785 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
786 return(13);
787 }
788 return(0);
789}
int ecat7EnterMatrix(FILE *fp, int matrix_id, int block_nr)
Definition ecat7ml.c:147
int ecat7_is_scaling_needed(float amax, float *data, long long nr)
Definition ecat7w.c:604
int ecat7WriteMatrixdata(FILE *fp, int start_block, char *data, long long pxl_nr, int pxl_size)
Definition ecat7w.c:974
int ecat7Write2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h)
Definition ecat7w.c:450

Referenced by imgWrite2DEcat7(), and imgWriteEcat7Frame().

◆ ecat7WriteAttenheader()

int ecat7WriteAttenheader ( FILE * fp,
int blk,
ECAT7_attenheader * h )
extern

Write ECAT 7.x attenuation header

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 attenuation header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 208 of file ecat7w.c.

208 {
209 unsigned char buf[MatBLKSIZE];
210 int little; /* 1 if current platform is little endian (i386), else 0 */
211
212 if(ECAT7_TEST) printf("ecat7WriteAttenheader()\n");
213 if(fp==NULL || blk<2 || h==NULL) return(1);
214 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
215 /* Clear buf */
216 memset(buf, 0, MatBLKSIZE);
220
221 /* Copy the header fields and swap if necessary */
222 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
223 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
224 memcpy(buf+4, &h->attenuation_type, 2); if(little) swabip(buf+4, 2);
225 memcpy(buf+6, &h->num_r_elements, 2); if(little) swabip(buf+6, 2);
226 memcpy(buf+8, &h->num_angles, 2); if(little) swabip(buf+8, 2);
227 memcpy(buf+10, &h->num_z_elements, 2); if(little) swabip(buf+10, 2);
228 memcpy(buf+12, &h->ring_difference, 2); if(little) swabip(buf+12, 2);
229 memcpy(buf+14, &h->x_resolution, 4); if(little) swawbip(buf+14, 4);
230 memcpy(buf+18, &h->y_resolution, 4); if(little) swawbip(buf+18, 4);
231 memcpy(buf+22, &h->z_resolution, 4); if(little) swawbip(buf+22, 4);
232 memcpy(buf+26, &h->w_resolution, 4); if(little) swawbip(buf+26, 4);
233 memcpy(buf+30, &h->scale_factor, 4); if(little) swawbip(buf+30, 4);
234 memcpy(buf+34, &h->x_offset, 4); if(little) swawbip(buf+34, 4);
235 memcpy(buf+38, &h->y_offset, 4); if(little) swawbip(buf+38, 4);
236 memcpy(buf+42, &h->x_radius, 4); if(little) swawbip(buf+42, 4);
237 memcpy(buf+46, &h->y_radius, 4); if(little) swawbip(buf+46, 4);
238 memcpy(buf+50, &h->tilt_angle, 4); if(little) swawbip(buf+50, 4);
239 memcpy(buf+54, &h->attenuation_coeff, 4); if(little) swawbip(buf+54, 4);
240 memcpy(buf+58, &h->attenuation_min, 4); if(little) swawbip(buf+58, 4);
241 memcpy(buf+62, &h->attenuation_max, 4); if(little) swawbip(buf+62, 4);
242 memcpy(buf+66, &h->skull_thickness, 4); if(little) swawbip(buf+66, 4);
243 memcpy(buf+70, &h->num_additional_atten_coeff, 2); if(little) swabip(buf+70, 2);
244 memcpy(buf+72, h->additional_atten_coeff, 8*4); if(little) swawbip(buf+72, 8*4);
245 memcpy(buf+104, &h->edge_finding_threshold, 4); if(little) swawbip(buf+104, 4);
246 memcpy(buf+108, &h->storage_order, 2); if(little) swabip(buf+108, 2);
247 memcpy(buf+110, &h->span, 2); if(little) swabip(buf+110, 2);
248 memcpy(buf+112, h->z_elements, 64*2); if(little) swabip(buf+112, 64*2);
249 memcpy(buf+240, h->fill_cti, 86*2); if(little) swabip(buf+240, 86*2);
250 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
251
252 /* Write header */
253 long long pos=(blk-1)*(long long)MatBLKSIZE;
254 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
255 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
256
257 return(0);
258}

◆ ecat7WriteHeaders()

int ecat7WriteHeaders ( const char * fname,
ECAT_HEADERS * ehdr,
int verbose )
extern

Write ECAT7 header contents (both main header and subheaders).

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fnameImage or sinogram filename
ehdrPointer to filled headers structure
verboseVerbose level

Definition at line 755 of file ecat7ift.c.

762 {
763 ECAT7_mainheader main_header;
764 ECAT7_MATRIXLIST mlist;
765 FILE *fp;
766 int ret, mi;
767
768
769 if(verbose>0) printf("ecat7WriteHeaders(%s, ehdr)\n", fname);
770 /* Check the arguments */
771 if(ehdr==NULL) return STATUS_FAULT;
772 if(fname==NULL) return STATUS_FAULT;
773
774 /* Open the file */
775 if((fp=fopen(fname, "r+b")) == NULL) return STATUS_NOFILE;
776
777 /* Read main header */
778 ret=ecat7ReadMainheader(fp, &main_header);
779 if(ret) {fclose(fp); return STATUS_NOMAINHEADER;}
780 /* Check for magic number */
781 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {fclose(fp); return STATUS_UNKNOWNFORMAT;}
782 /* Copy IFT contents into main header */
783 //iftWrite(&ehdr->mh, "stdout");
784 ret=ecat7MainheaderFromIFT(&main_header, &ehdr->mh, verbose);
785 if(ret!=STATUS_OK) {fclose(fp); return ret;}
786 //if(HEADER_TEST>5) iftWrite(&ehdr->mh, "stdout");
787 /* Write mainheader */
788 ret=ecat7WriteMainheader(fp, &main_header);
789 if(ret!=0) {fclose(fp); return STATUS_CANNOTWRITE;}
790 /* Read matrix list */
791 ecat7InitMatlist(&mlist);
792 ret=ecat7ReadMatlist(fp, &mlist, verbose-1);
793 if(ret || mlist.matrixNr<1 || ecat7CheckMatlist(&mlist)) {fclose(fp); return STATUS_INVALIDMATLIST;}
794#if(0)
795 /* Allocate space for each matrix */
796 ret=ehdrAllocate(ehdr, mlist.matrixNr);
797 if(ret!=STATUS_OK) {fclose(fp); ecat7EmptyMatlist(&mlist); return ret;}
798#endif
799 /* Edit one subheader at a time */
800 for(mi=0; mi<mlist.matrixNr; mi++) {
801 ehdr->m[mi].mnum=mlist.matdir[mi].id;
802 ecat7_id_to_val(mlist.matdir[mi].id, &ehdr->m[mi].matval);
803 if(verbose>2) {
804 printf("frame := %d\n", ehdr->m[mi].matval.frame);
805 printf("plane := %d\n", ehdr->m[mi].matval.plane);
806 printf("gate := %d\n", ehdr->m[mi].matval.gate);
807 printf("data := %d\n", ehdr->m[mi].matval.data);
808 printf("bed := %d\n", ehdr->m[mi].matval.bed);
809 }
810 ret=ecat7WriteSubheaderFromIFT(fp, &main_header, mlist.matdir[mi].strtblk,
811 &ehdr->m[mi].sh, verbose);
812 if(ret!=STATUS_OK) {fclose(fp); ecat7EmptyMatlist(&mlist); return ret;}
813 //iftWrite(&ehdr->m[mi].sh, "stdout");
814 } // next matrix
815 fclose(fp); ecat7EmptyMatlist(&mlist);
816
817 return STATUS_OK;
818}
int ecat7MainheaderFromIFT(ECAT7_mainheader *h, IFT *ift, int verbose)
Definition ecat7ift.c:221
int ecat7WriteSubheaderFromIFT(FILE *fp, ECAT7_mainheader *h, int strtblk, IFT *ift, int verbose)
Definition ecat7ift.c:583

Referenced by ecat7CopyHeadersNoQuant().

◆ ecat7WriteImageheader()

int ecat7WriteImageheader ( FILE * fp,
int blk,
ECAT7_imageheader * h )
extern

Write ECAT 7.x image header. Changes data type to big endian.

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 image header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 113 of file ecat7w.c.

113 {
114 unsigned char buf[MatBLKSIZE];
115 int little; /* 1 if current platform is little endian (i386), else 0 */
116
117 if(ECAT7_TEST) printf("ecat7WriteImageheader(%d)\n", blk);
118 if(fp==NULL || blk<2 || h==NULL) return(1);
119 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
120 /* Clear buf */
121 memset(buf, 0, MatBLKSIZE);
125
126 /* Copy the header fields and swap if necessary */
127 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
128 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
129 memcpy(buf+4, &h->x_dimension, 2); if(little) swabip(buf+4, 2);
130 memcpy(buf+6, &h->y_dimension, 2); if(little) swabip(buf+6, 2);
131 memcpy(buf+8, &h->z_dimension, 2); if(little) swabip(buf+8, 2);
132 memcpy(buf+10, &h->x_offset, 4); if(little) swawbip(buf+10, 4);
133 memcpy(buf+14, &h->y_offset, 4); if(little) swawbip(buf+14, 4);
134 memcpy(buf+18, &h->z_offset, 4); if(little) swawbip(buf+18, 4);
135 memcpy(buf+22, &h->recon_zoom, 4); if(little) swawbip(buf+22, 4);
136 memcpy(buf+26, &h->scale_factor, 4); if(little) swawbip(buf+26, 4);
137 memcpy(buf+30, &h->image_min, 2); if(little) swabip(buf+30, 2);
138 memcpy(buf+32, &h->image_max, 2); if(little) swabip(buf+32, 2);
139 memcpy(buf+34, &h->x_pixel_size, 4); if(little) swawbip(buf+34, 4);
140 memcpy(buf+38, &h->y_pixel_size, 4); if(little) swawbip(buf+38, 4);
141 memcpy(buf+42, &h->z_pixel_size, 4); if(little) swawbip(buf+42, 4);
142 memcpy(buf+46, &h->frame_duration, 4); if(little) swawbip(buf+46, 4);
143 memcpy(buf+50, &h->frame_start_time, 4); if(little) swawbip(buf+50, 4);
144 memcpy(buf+54, &h->filter_code, 2); if(little) swabip(buf+54, 2);
145 memcpy(buf+56, &h->x_resolution, 4); if(little) swawbip(buf+56, 4);
146 memcpy(buf+60, &h->y_resolution, 4); if(little) swawbip(buf+60, 4);
147 memcpy(buf+64, &h->z_resolution, 4); if(little) swawbip(buf+64, 4);
148 memcpy(buf+68, &h->num_r_elements, 4); if(little) swawbip(buf+68, 4);
149 memcpy(buf+72, &h->num_angles, 4); if(little) swawbip(buf+72, 4);
150 memcpy(buf+76, &h->z_rotation_angle, 4); if(little) swawbip(buf+76, 4);
151 memcpy(buf+80, &h->decay_corr_fctr, 4); if(little) swawbip(buf+80, 4);
152 memcpy(buf+84, &h->processing_code, 4); if(little) swawbip(buf+84, 4);
153 memcpy(buf+88, &h->gate_duration, 4); if(little) swawbip(buf+88, 4);
154 memcpy(buf+92, &h->r_wave_offset, 4); if(little) swawbip(buf+92, 4);
155 memcpy(buf+96, &h->num_accepted_beats, 4); if(little) swawbip(buf+96, 4);
156 memcpy(buf+100, &h->filter_cutoff_frequency, 4); if(little) swawbip(buf+100, 4);
157 memcpy(buf+104, &h->filter_resolution, 4); if(little) swawbip(buf+104, 4);
158 memcpy(buf+108, &h->filter_ramp_slope, 4); if(little) swawbip(buf+108, 4);
159 memcpy(buf+112, &h->filter_order, 2); if(little) swabip(buf+112, 2);
160 memcpy(buf+114, &h->filter_scatter_fraction, 4); if(little) swawbip(buf+114, 4);
161 memcpy(buf+118, &h->filter_scatter_slope, 4); if(little) swawbip(buf+118, 4);
162 memcpy(buf+122, &h->annotation, 40);
163 memcpy(buf+162, &h->mt_1_1, 4); if(little) swawbip(buf+162, 4);
164 memcpy(buf+166, &h->mt_1_2, 4); if(little) swawbip(buf+166, 4);
165 memcpy(buf+170, &h->mt_1_3, 4); if(little) swawbip(buf+170, 4);
166 memcpy(buf+174, &h->mt_2_1, 4); if(little) swawbip(buf+174, 4);
167 memcpy(buf+178, &h->mt_2_2, 4); if(little) swawbip(buf+178, 4);
168 memcpy(buf+182, &h->mt_2_3, 4); if(little) swawbip(buf+182, 4);
169 memcpy(buf+186, &h->mt_3_1, 4); if(little) swawbip(buf+186, 4);
170 memcpy(buf+190, &h->mt_3_2, 4); if(little) swawbip(buf+190, 4);
171 memcpy(buf+194, &h->mt_3_3, 4); if(little) swawbip(buf+194, 4);
172 memcpy(buf+198, &h->rfilter_cutoff, 4); if(little) swawbip(buf+198, 4);
173 memcpy(buf+202, &h->rfilter_resolution, 4); if(little) swawbip(buf+202, 4);
174 memcpy(buf+206, &h->rfilter_code, 2); if(little) swabip(buf+206, 2);
175 memcpy(buf+208, &h->rfilter_order, 2); if(little) swabip(buf+208, 2);
176 memcpy(buf+210, &h->zfilter_cutoff, 4); if(little) swawbip(buf+210, 4);
177 memcpy(buf+214, &h->zfilter_resolution, 4); if(little) swawbip(buf+214, 4);
178 memcpy(buf+218, &h->zfilter_code, 2); if(little) swabip(buf+218, 2);
179 memcpy(buf+220, &h->zfilter_order, 2); if(little) swabip(buf+220, 2);
180 memcpy(buf+222, &h->mt_1_4, 4); if(little) swawbip(buf+222, 4);
181 memcpy(buf+226, &h->mt_2_4, 4); if(little) swawbip(buf+226, 4);
182 memcpy(buf+230, &h->mt_3_4, 4); if(little) swawbip(buf+230, 4);
183 memcpy(buf+234, &h->scatter_type, 2); if(little) swabip(buf+234, 2);
184 memcpy(buf+236, &h->recon_type, 2); if(little) swabip(buf+236, 2);
185 memcpy(buf+238, &h->recon_views, 2); if(little) swabip(buf+238, 2);
186 memcpy(buf+240, &h->fill_cti, 87);
187 memcpy(buf+414, &h->fill_user, 48);
188
189 /* Write header */
190 long long pos=(blk-1)*(long long)MatBLKSIZE;
191 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
192 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
193
194 return(0);
195}

Referenced by ecat7WriteImageMatrix(), and ecat7WriteSubheaderFromIFT().

◆ ecat7WriteImageMatrix()

int ecat7WriteImageMatrix ( FILE * fp,
int matrix_id,
ECAT7_imageheader * h,
float * fdata )
extern

Write ECAT 7.x image or volume matrix header and data

Parameters
fpoutput file pointer
matrix_idcoded matrix id
hEcat7 image header
fdatafloat data to be written
Returns
0 if ok.

Definition at line 635 of file ecat7w.c.

635 {
636 int ret;
637 long long pxlNr, blkNr, nxtblk, data_size;
638 float *fptr, fmin, fmax, g, f;
639 char *mdata, *mptr;
640 short int *sptr;
641
642
643 if(ECAT7_TEST) printf("ecat7WriteImageMatrix(fp, %d, h, data)\n", matrix_id);
644 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
645 sprintf(ecat7errmsg, "invalid function parameter.\n");
646 return(1);
647 }
648 if(h->data_type!=ECAT7_SUNI2) {
649 sprintf(ecat7errmsg, "invalid data_type.\n");
650 return(2);
651 }
652 /* nr of pixels */
653 pxlNr=h->x_dimension*h->y_dimension;
654 if(h->num_dimensions>2) pxlNr*=h->z_dimension;
655 if(pxlNr<1) {
656 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
657 return(3);
658 }
659
660 /* How much memory is needed for ALL pixels */
661 data_size=pxlNr*ecat7pxlbytes(h->data_type);
662 /* block nr taken by all pixels */
663 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
664 sprintf(ecat7errmsg, "invalid block number.\n");
665 return(4);
666 }
667 /* Allocate memory for matrix data */
668 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
669 sprintf(ecat7errmsg, "out of memory.\n");
670 return(5);
671 }
672 /* Search for min and max for calculation of scale factor */
673 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
674 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
675 if(g>0) f=32766./g; else f=1.0;
676 /* Check if pixels values can be left as such with scale_factor = 1 */
677 fptr=fdata;
678 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
679 /* Scale matrix data to shorts */
680 h->scale_factor=1.0/f;
681 sptr=(short int*)mdata; fptr=fdata;
682 for(long long i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
683 /* Set header short min & max */
684 h->image_min=(short int)temp_roundf(f*fmin);
685 h->image_max=(short int)temp_roundf(f*fmax);
686 /* Get block number for matrix header and data */
687 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
688 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
689 free(mdata); return(8);
690 }
691 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
692 /* Write header */
693 ret=ecat7WriteImageheader(fp, nxtblk, h); if(ret) {
694 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
695 free(mdata); return(10);
696 }
697 /* Write matrix data */
698 mptr=mdata;
699 ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
700 free(mdata);
701 if(ret) {
702 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
703 return(13);
704 }
705 return(0);
706}
int ecat7WriteImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition ecat7w.c:113

Referenced by imgWrite2DEcat7(), imgWriteEcat7(), and imgWriteEcat7Frame().

◆ ecat7WriteMainheader()

int ecat7WriteMainheader ( FILE * fp,
ECAT7_mainheader * h )
extern

Write ECAT 7.x main header.

Writes header always in big endian byte order.

Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success
Parameters
fpoutput file pointer
hEcat7 main header

Definition at line 16 of file ecat7w.c.

21 {
22 unsigned char buf[MatBLKSIZE];
23 int little;
24
25 if(ECAT7_TEST) printf("ecat7WriteMainheader()\n");
26 /* Check arguments */
27 if(fp==NULL || h==NULL) return(1);
28 little=little_endian();
29 /* Clear buf */
30 memset(buf, 0, MatBLKSIZE);
31
32 /* Copy header contents into buffer and change byte order if necessary */
33 memcpy(buf+0, &h->magic_number, 14);
34 memcpy(buf+14, &h->original_file_name, 32);
35 memcpy(buf+46, &h->sw_version, 2); if(little) swabip(buf+46, 2);
36 memcpy(buf+48, &h->system_type, 2); if(little) swabip(buf+48, 2);
37 memcpy(buf+50, &h->file_type, 2); if(little) swabip(buf+50, 2);
38 memcpy(buf+52, &h->serial_number, 10);
39 //printf("ecat7WriteMainheader(): scan_start_time := %d\n", h->scan_start_time);
40 memcpy(buf+62, &h->scan_start_time, 4); if(little) swawbip(buf+62, 4);
41 memcpy(buf+66, &h->isotope_name, 8);
42 memcpy(buf+74, &h->isotope_halflife, 4); if(little) swawbip(buf+74, 4);
43 memcpy(buf+78, &h->radiopharmaceutical, 32);
44 memcpy(buf+110, &h->gantry_tilt, 4); if(little) swawbip(buf+110, 4);
45 memcpy(buf+114, &h->gantry_rotation, 4); if(little) swawbip(buf+114, 4);
46 memcpy(buf+118, &h->bed_elevation, 4); if(little) swawbip(buf+118, 4);
47 memcpy(buf+122, &h->intrinsic_tilt, 4); if(little) swawbip(buf+122, 4);
48 memcpy(buf+126, &h->wobble_speed, 2); if(little) swabip(buf+126, 2);
49 memcpy(buf+128, &h->transm_source_type, 2); if(little) swabip(buf+128, 2);
50 memcpy(buf+130, &h->distance_scanned, 4); if(little) swawbip(buf+130, 4);
51 memcpy(buf+134, &h->transaxial_fov, 4); if(little) swawbip(buf+134, 4);
52 memcpy(buf+138, &h->angular_compression, 2); if(little) swabip(buf+138, 2);
53 memcpy(buf+140, &h->coin_samp_mode, 2); if(little) swabip(buf+140, 2);
54 memcpy(buf+142, &h->axial_samp_mode, 2); if(little) swabip(buf+142, 2);
55 memcpy(buf+144, &h->ecat_calibration_factor, 4); if(little) swawbip(buf+144, 4);
56 memcpy(buf+148, &h->calibration_units, 2); if(little) swabip(buf+148, 2);
57 memcpy(buf+150, &h->calibration_units_label, 2); if(little) swabip(buf+150, 2);
58 memcpy(buf+152, &h->compression_code, 2); if(little) swabip(buf+152, 2);
59 memcpy(buf+154, &h->study_type, 12);
60 memcpy(buf+166, &h->patient_id, 16);
61 memcpy(buf+182, &h->patient_name, 32);
62 memcpy(buf+214, &h->patient_sex, 1);
63 memcpy(buf+215, &h->patient_dexterity, 1);
64 memcpy(buf+216, &h->patient_age, 4); if(little) swawbip(buf+216, 4);
65 memcpy(buf+220, &h->patient_height, 4); if(little) swawbip(buf+220, 4);
66 memcpy(buf+224, &h->patient_weight, 4); if(little) swawbip(buf+224, 4);
67 memcpy(buf+228, &h->patient_birth_date, 4); if(little) swawbip(buf+228, 4);
68 memcpy(buf+232, &h->physician_name, 32);
69 memcpy(buf+264, &h->operator_name, 32);
70 memcpy(buf+296, &h->study_description, 32);
71 memcpy(buf+328, &h->acquisition_type, 2); if(little) swabip(buf+328, 2);
72 memcpy(buf+330, &h->patient_orientation, 2); if(little) swabip(buf+330, 2);
73 memcpy(buf+332, &h->facility_name, 20);
74 memcpy(buf+352, &h->num_planes, 2); if(little) swabip(buf+352, 2);
75 memcpy(buf+354, &h->num_frames, 2); if(little) swabip(buf+354, 2);
76 memcpy(buf+356, &h->num_gates, 2); if(little) swabip(buf+356, 2);
77 memcpy(buf+358, &h->num_bed_pos, 2); if(little) swabip(buf+358, 2);
78 memcpy(buf+360, &h->init_bed_position, 4); if(little) swawbip(buf+360, 4);
79 memcpy(buf+364, h->bed_position, 15*4); if(little) swawbip(buf+364, 15*4);
80 memcpy(buf+424, &h->plane_separation, 4); if(little) swawbip(buf+424, 4);
81 memcpy(buf+428, &h->lwr_sctr_thres, 2); if(little) swabip(buf+428, 2);
82 memcpy(buf+430, &h->lwr_true_thres, 2); if(little) swabip(buf+430, 2);
83 memcpy(buf+432, &h->upr_true_thres, 2); if(little) swabip(buf+432, 2);
84 memcpy(buf+434, &h->user_process_code, 10);
85 memcpy(buf+444, &h->acquisition_mode, 2); if(little) swabip(buf+444, 2);
86 memcpy(buf+446, &h->bin_size, 4); if(little) swawbip(buf+446, 4);
87 memcpy(buf+450, &h->branching_fraction, 4); if(little) swawbip(buf+450, 4);
88 memcpy(buf+454, &h->dose_start_time, 4); if(little) swawbip(buf+454, 4);
89 memcpy(buf+458, &h->dosage, 4); if(little) swawbip(buf+458, 4);
90 memcpy(buf+462, &h->well_counter_corr_factor, 4); if(little) swawbip(buf+462, 4);
91 memcpy(buf+466, &h->data_units, 32);
92 memcpy(buf+498, &h->septa_state, 2); if(little) swabip(buf+498, 2);
93 memcpy(buf+500, &h->fill_cti, 12);
94
95 /* Write main header */
96 fseek(fp, 0*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=0*MatBLKSIZE) return(4);
97 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
98
99 return(0);
100}

Referenced by ecat7Create(), ecat7WriteHeaders(), and imgWriteEcat7Frame().

◆ ecat7WriteMatrixdata()

int ecat7WriteMatrixdata ( FILE * fp,
int start_block,
char * data,
long long pxl_nr,
int pxl_size )
extern

Write ECAT 7.x 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.

Parameters
fpPointer to an opened ECAT file
start_blockBlock number where matrix data is written
dataPointer to matrix data
pxl_nrNumber of pixels
pxl_sizeSize of data for one pixel in bytes
Returns
>0 in case of an error.

Definition at line 974 of file ecat7w.c.

974 {
975 unsigned char buf[MatBLKSIZE];
976 char *dptr;
977 int little;
978 long long i, dataSize, byteNr, blkNr;
979
980 if(ECAT7_TEST) printf("ecat7WriteMatrixdata(fp, %d, data, %lld, %d)\n",
981 start_block, pxl_nr, pxl_size);
982 if(fp==NULL || start_block<1 || data==NULL || pxl_nr<1 || pxl_size<1) return(1);
983 little=little_endian(); memset(buf, 0, MatBLKSIZE);
984 dataSize=pxl_nr*pxl_size;
985 /* block nr taken by all pixels */
986 blkNr=(dataSize+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) return(1);
987 if(ECAT7_TEST>2) printf(" blkNr=%lld\n", blkNr);
988 /* Search the place for writing */
989 long long pos=(start_block-1)*(long long)MatBLKSIZE;
990 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(2);
991 /* Save blocks one at a time */
992 for(i=0, dptr=data; i<blkNr && dataSize>0; i++) {
993 byteNr=(dataSize<MatBLKSIZE)?dataSize:MatBLKSIZE;
994 memcpy(buf, dptr, byteNr);
995 /* Change matrix byte order in little endian platforms */
996 if(little) {
997 if(pxl_size==2) swabip(buf, byteNr);
998 else if(pxl_size==4) swawbip(buf, byteNr);
999 }
1000 /* Write block */
1001 if(fwrite(buf, 1, MatBLKSIZE, fp)!=MatBLKSIZE) return(3);
1002 /* Prepare for the next block */
1003 dptr+=byteNr; dataSize-=byteNr;
1004 } /* next block */
1005 return(0);
1006}

Referenced by ecat7Write2DScanMatrix(), ecat7WriteImageMatrix(), ecat7WritePolarmapMatrix(), and ecat7WriteScanMatrix().

◆ ecat7WriteNormheader()

int ecat7WriteNormheader ( FILE * fp,
int blk,
ECAT7_normheader * h )
extern

Write ECAT 7.x 3D normalization header

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 normalization header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 330 of file ecat7w.c.

330 {
331 unsigned char buf[MatBLKSIZE];
332 int little; /* 1 if current platform is little endian (i386), else 0 */
333
334 if(ECAT7_TEST) printf("ecat7WriteNormheader()\n");
335 if(fp==NULL || blk<2 || h==NULL) return(1);
336 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
337 /* Clear buf */
338 memset(buf, 0, MatBLKSIZE);
342
343 /* Copy the header fields and swap if necessary */
344 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
345 memcpy(buf+2, &h->num_r_elements, 2); if(little) swabip(buf+2, 2);
346 memcpy(buf+4, &h->num_transaxial_crystals, 2); if(little) swabip(buf+4, 2);
347 memcpy(buf+6, &h->num_crystal_rings, 2); if(little) swabip(buf+6, 2);
348 memcpy(buf+8, &h->crystals_per_ring, 2); if(little) swabip(buf+8, 2);
349 memcpy(buf+10, &h->num_geo_corr_planes, 2); if(little) swabip(buf+10, 2);
350 memcpy(buf+12, &h->uld, 2); if(little) swabip(buf+12, 2);
351 memcpy(buf+14, &h->lld, 2); if(little) swabip(buf+14, 2);
352 memcpy(buf+16, &h->scatter_energy, 2); if(little) swabip(buf+16, 2);
353 memcpy(buf+18, &h->norm_quality_factor, 4); if(little) swawbip(buf+18, 4);
354 memcpy(buf+22, &h->norm_quality_factor_code, 2); if(little) swabip(buf+22, 2);
355 memcpy(buf+24, h->ring_dtcor1, 32*4); if(little) swawbip(buf+24, 32*4);
356 memcpy(buf+152, h->ring_dtcor2, 32*4); if(little) swawbip(buf+152, 32*4);
357 memcpy(buf+280, h->crystal_dtcor, 8*4); if(little) swawbip(buf+280, 8*4);
358 memcpy(buf+312, &h->span, 2); if(little) swabip(buf+312, 2);
359 memcpy(buf+314, &h->max_ring_diff, 2); if(little) swabip(buf+314, 2);
360 memcpy(buf+316, h->fill_cti, 48*2); if(little) swabip(buf+316, 48*2);
361 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
362
363 /* Write header */
364 long long pos=(blk-1)*(long long)MatBLKSIZE;
365 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
366 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
367
368 return(0);
369}

◆ ecat7WritePolarmapMatrix()

int ecat7WritePolarmapMatrix ( FILE * fp,
int matrix_id,
ECAT7_polmapheader * h,
float * fdata )
extern

Write ECAT 7.x polarmap matrix header and data

Parameters
fpoutput file pointer
matrix_idcoded matrix information
hEcat7 polar map header
fdatafloat data
Returns
0 if ok.

Definition at line 888 of file ecat7w.c.

888 {
889 int ret;
890 long long i, nxtblk, blkNr, data_size, pxlNr;
891 float *fptr, fmin, fmax, g, f;
892 char *mdata, *mptr;
893 short int *sptr;
894
895
896 if(ECAT7_TEST) printf("ecat7WritePolarmapMatrix(fp, %d, h, data)\n", matrix_id);
897 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
898 sprintf(ecat7errmsg, "invalid function parameter.\n");
899 return(1);
900 }
901 if(h->data_type!=ECAT7_SUNI2) {
902 sprintf(ecat7errmsg, "invalid data_type.\n");
903 return(2);
904 }
905 /* nr of pixels */
906 for(i=pxlNr=0; i<h->num_rings; i++) pxlNr+=h->sectors_per_ring[i];
907 if(pxlNr<1) {
908 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
909 return(3);
910 }
911 /* How much memory is needed for ALL pixels */
912 data_size=pxlNr*ecat7pxlbytes(h->data_type);
913 /* block nr taken by all pixels */
914 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
915 sprintf(ecat7errmsg, "invalid block number.\n");
916 return(4);
917 }
918 /* Allocate memory for matrix data */
919 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
920 sprintf(ecat7errmsg, "out of memory.\n");
921 return(5);
922 }
923 /* Search for min and max for calculation of scale factor */
924 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
925 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
926 if(g>0) f=32766./g; else f=1.0;
927 /* Check if pixels values can be left as such with scale_factor = 1 */
928 fptr=fdata;
929 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
930 /* Scale matrix data to shorts */
931 h->scale_factor=1.0/f;
932 sptr=(short int*)mdata; fptr=fdata;
933 for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
934 /* Set header short min & max */
935 h->image_min=(short int)temp_roundf(f*fmin);
936 h->image_max=(short int)temp_roundf(f*fmax);
937 /* Get block number for matrix header and data */
938 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr); if(nxtblk<1) {
939 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
940 free(mdata); return(8);
941 }
942 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
943 /* Write header */
944 ret=ecat7WritePolmapheader(fp, nxtblk, h); if(ret) {
945 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
946 free(mdata); return(10);
947 }
948 /* Write matrix data */
949 mptr=mdata;
950 ret=ecat7WriteMatrixdata(fp, nxtblk+1, mptr, pxlNr, ecat7pxlbytes(h->data_type));
951 free(mdata);
952 if(ret) {
953 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
954 return(13);
955 }
956 return(0);
957}
int ecat7WritePolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h)
Definition ecat7w.c:271

Referenced by imgWriteEcat7Frame(), and imgWritePolarmap().

◆ ecat7WritePolmapheader()

int ecat7WritePolmapheader ( FILE * fp,
int blk,
ECAT7_polmapheader * h )
extern

Write ECAT 7.x polar map header

Parameters
fpoutput file pointer
blkheader block number, blk >= 2
hEcat7 polar map header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 271 of file ecat7w.c.

271 {
272 unsigned char buf[MatBLKSIZE];
273 int little; /* 1 if current platform is little endian (i386), else 0 */
274
275 if(ECAT7_TEST) printf("ecat7WritePolmapheader()\n");
276 if(fp==NULL || blk<2 || h==NULL) return(1);
277 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
278 /* Clear buf */
279 memset(buf, 0, MatBLKSIZE);
283
284 /* Copy the header fields and swap if necessary */
285 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
286 memcpy(buf+2, &h->polar_map_type, 2); if(little) swabip(buf+2, 2);
287 memcpy(buf+4, &h->num_rings, 2); if(little) swabip(buf+4, 2);
288 memcpy(buf+6, h->sectors_per_ring, 32*2); if(little) swabip(buf+6, 32*2);
289 memcpy(buf+70, h->ring_position, 32*4); if(little) swawbip(buf+70, 32*4);
290 memcpy(buf+198, h->ring_angle, 32*2); if(little) swabip(buf+198, 32*2);
291 memcpy(buf+262, &h->start_angle, 2); if(little) swabip(buf+262, 2);
292 memcpy(buf+264, h->long_axis_left, 3*2); if(little) swabip(buf+264, 3*2);
293 memcpy(buf+270, h->long_axis_right, 3*2); if(little) swabip(buf+270, 3*2);
294 memcpy(buf+276, &h->position_data, 2); if(little) swabip(buf+276, 2);
295 memcpy(buf+278, &h->image_min, 2); if(little) swabip(buf+278, 2);
296 memcpy(buf+280, &h->image_max, 2); if(little) swabip(buf+280, 2);
297 memcpy(buf+282, &h->scale_factor, 4); if(little) swawbip(buf+282, 4);
298 memcpy(buf+286, &h->pixel_size, 4); if(little) swawbip(buf+286, 4);
299 memcpy(buf+290, &h->frame_duration, 4); if(little) swawbip(buf+290, 4);
300 memcpy(buf+294, &h->frame_start_time, 4); if(little) swawbip(buf+294, 4);
301 memcpy(buf+298, &h->processing_code, 2); if(little) swabip(buf+298, 2);
302 memcpy(buf+300, &h->quant_units, 2); if(little) swabip(buf+300, 2);
303 memcpy(buf+302, h->annotation, 40);
304 memcpy(buf+342, &h->gate_duration, 4); if(little) swawbip(buf+342, 4);
305 memcpy(buf+346, &h->r_wave_offset, 4); if(little) swawbip(buf+346, 4);
306 memcpy(buf+350, &h->num_accepted_beats, 4); if(little) swawbip(buf+350, 4);
307 memcpy(buf+354, h->polar_map_protocol, 20);
308 memcpy(buf+374, h->database_name, 30);
309 memcpy(buf+404, h->fill_cti, 27*2); if(little) swabip(buf+404, 27*2);
310
311 /* Write header */
312 long long pos=(blk-1)*(long long)MatBLKSIZE;
313 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
314 if(fwrite(buf, 1, 1*MatBLKSIZE, fp) != 1*MatBLKSIZE) return(5);
315
316 return(0);
317}

Referenced by ecat7WritePolarmapMatrix().

◆ ecat7WriteScanheader()

int ecat7WriteScanheader ( FILE * fp,
int blk,
ECAT7_scanheader * h )
extern

Write ECAT 7.x 3D scan header (512 bytes) Changes data type to big endian.

Parameters
fppointer to output file
blkblock number, blk >= 2
hEcat7 scan header
Returns
0 in case of success, 1 == invalid parameters, 4 == file pointer is at wrong position, 5 == writing of MatBLKSIZE bytes was not success

Definition at line 383 of file ecat7w.c.

383 {
384 unsigned char buf[2*MatBLKSIZE];
385 int little; /* 1 if current platform is little endian (i386), else 0 */
386
387 if(ECAT7_TEST) printf("ecat7WriteScanheader()\n");
388 if(fp==NULL || blk<2 || h==NULL) return(1);
389 little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
390 /* Clear buf */
391 memset(buf, 0, 2*MatBLKSIZE);
395
396 /* Copy the header fields and swap if necessary */
397 memcpy(buf+0, &h->data_type, 2); if(little) swabip(buf+0, 2);
398 memcpy(buf+2, &h->num_dimensions, 2); if(little) swabip(buf+2, 2);
399 memcpy(buf+4, &h->num_r_elements, 2); if(little) swabip(buf+4, 2);
400 memcpy(buf+6, &h->num_angles, 2); if(little) swabip(buf+6, 2);
401 memcpy(buf+8, &h->corrections_applied, 2); if(little) swabip(buf+8, 2);
402 memcpy(buf+10, h->num_z_elements, 64*2); if(little) swabip(buf+10, 64*2);
403 memcpy(buf+138, &h->ring_difference, 2); if(little) swabip(buf+138, 2);
404 memcpy(buf+140, &h->storage_order, 2); if(little) swabip(buf+140, 2);
405 memcpy(buf+142, &h->axial_compression, 2); if(little) swabip(buf+142, 2);
406 memcpy(buf+144, &h->x_resolution, 4); if(little) swawbip(buf+144, 4);
407 memcpy(buf+148, &h->v_resolution, 4); if(little) swawbip(buf+148, 4);
408 memcpy(buf+152, &h->z_resolution, 4); if(little) swawbip(buf+152, 4);
409 memcpy(buf+156, &h->w_resolution, 4); if(little) swawbip(buf+156, 4);
410 memcpy(buf+160, h->fill_gate, 6*2); if(little) swabip(buf+160, 6*2);
411 memcpy(buf+172, &h->gate_duration, 4); if(little) swawbip(buf+172, 4);
412 memcpy(buf+176, &h->r_wave_offset, 4); if(little) swawbip(buf+176, 4);
413 memcpy(buf+180, &h->num_accepted_beats, 4); if(little) swawbip(buf+180, 4);
414 memcpy(buf+184, &h->scale_factor, 4); if(little) swawbip(buf+184, 4);
415 memcpy(buf+188, &h->scan_min, 2); if(little) swabip(buf+188, 2);
416 memcpy(buf+190, &h->scan_max, 2); if(little) swabip(buf+190, 2);
417 memcpy(buf+192, &h->prompts, 4); if(little) swawbip(buf+192, 4);
418 memcpy(buf+196, &h->delayed, 4); if(little) swawbip(buf+196, 4);
419 memcpy(buf+200, &h->multiples, 4); if(little) swawbip(buf+200, 4);
420 memcpy(buf+204, &h->net_trues, 4); if(little) swawbip(buf+204, 4);
421 memcpy(buf+208, &h->tot_avg_cor, 4); if(little) swawbip(buf+208, 4);
422 memcpy(buf+212, &h->tot_avg_uncor, 4); if(little) swawbip(buf+212, 4);
423 memcpy(buf+216, &h->total_coin_rate, 4); if(little) swawbip(buf+216, 4);
424 memcpy(buf+220, &h->frame_start_time, 4); if(little) swawbip(buf+220, 4);
425 memcpy(buf+224, &h->frame_duration, 4); if(little) swawbip(buf+224, 4);
426 memcpy(buf+228, &h->deadtime_correction_factor, 4); if(little) swawbip(buf+228, 4);
427 memcpy(buf+232, h->fill_cti, 90*2); if(little) swabip(buf+232, 90*2);
428 memcpy(buf+412, h->fill_user, 50*2); if(little) swabip(buf+412, 50*2);
429 memcpy(buf+512, h->uncor_singles, 128*4); if(little) swawbip(buf+512, 128*4);
430
431 /* Write 3D scan header */
432 long long pos=(blk-1)*(long long)MatBLKSIZE;
433 fseeko(fp, pos, SEEK_SET); if(ftello(fp)!=pos) return(4);
434 if(fwrite(buf, 1, 2*MatBLKSIZE, fp) != 2*MatBLKSIZE) return(5);
435
436 return(0);
437}

Referenced by ecat7ReadSubheaderToIFT(), ecat7WriteScanMatrix(), and ecat7WriteSubheaderFromIFT().

◆ ecat7WriteScanMatrix()

int ecat7WriteScanMatrix ( FILE * fp,
int matrix_id,
ECAT7_scanheader * h,
float * fdata )
extern

Write ECAT 7.x 3D sinogram matrix header and data

Parameters
fpoutput file pointer
matrix_idcoded matrix id
hEcat7 scan header
fdatafloat data
Returns
0 if ok.

Definition at line 802 of file ecat7w.c.

802 {
803 int ret;
804 long long i, nxtblk, blkNr, data_size, pxlNr, dimz;
805 float *fptr, fmin, fmax, g, f;
806 char *mdata, *mptr;
807 short int *sptr;
808
809
810 if(ECAT7_TEST) printf("ecat7WriteScanMatrix(fp, %d, h, data)\n", matrix_id);
811 if(fp==NULL || matrix_id<1 || h==NULL || fdata==NULL) {
812 sprintf(ecat7errmsg, "invalid function parameter.\n");
813 return(1);
814 }
815 if(h->data_type!=ECAT7_SUNI2) {
816 sprintf(ecat7errmsg, "invalid data_type.\n");
817 return(2);
818 }
819 /* nr of pixels */
820 pxlNr=h->num_r_elements*h->num_angles;
821 for(i=dimz=0; i<64; i++) dimz+=h->num_z_elements[i];
822 pxlNr*=dimz;
823 if(pxlNr<1) {
824 sprintf(ecat7errmsg, "invalid matrix dimension.\n");
825 return(3);
826 }
827 /* How much memory is needed for ALL pixels */
828 data_size=pxlNr*ecat7pxlbytes(h->data_type);
829 /* block nr taken by all pixels */
830 blkNr=(data_size+MatBLKSIZE-1)/MatBLKSIZE; if(blkNr<1) {
831 sprintf(ecat7errmsg, "invalid block number.\n");
832 return(4);
833 }
834 /* Allocate memory for matrix data */
835 mdata=(char*)calloc(blkNr, MatBLKSIZE); if(mdata==NULL) {
836 sprintf(ecat7errmsg, "out of memory.\n");
837 return(5);
838 }
839 /* Search for min and max for calculation of scale factor */
840 fMinMaxFin(fdata, pxlNr, &fmin, &fmax);
841 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
842 if(g>0) f=32766./g; else f=1.0;
843 /* Check if pixels values can be left as such with scale_factor = 1 */
844 fptr=fdata;
845 if(f>=1.0 && ecat7_is_scaling_needed(g, fptr, pxlNr)==0) f=1.0;
846 /* Scale matrix data to shorts */
847 h->scale_factor=1.0/f;
848 sptr=(short int*)mdata; fptr=fdata;
849 for(i=0; i<pxlNr; i++, sptr++, fptr++) *sptr=(short int)temp_roundf(f*(*fptr));
850 /* Set header short min & max */
851 h->scan_min=(short int)temp_roundf(f*fmin);
852 h->scan_max=(short int)temp_roundf(f*fmax);
853 /* Get block number for matrix header and data */
854 /* Note that one extra block (blkNr+1) is needed for 3D scan header */
855 nxtblk=ecat7EnterMatrix(fp, matrix_id, blkNr+1); if(nxtblk<1) {
856 sprintf(ecat7errmsg, "cannot determine matrix block (%lld).\n", -nxtblk);
857 free(mdata); return(8);
858 }
859 if(ECAT7_TEST>2) printf(" block=%lld fmin=%g fmax=%g\n", nxtblk, fmin, fmax);
860 /* Write header */
861 ret=ecat7WriteScanheader(fp, nxtblk, h); if(ret) {
862 sprintf(ecat7errmsg, "cannot write subheader (%d).\n", ret);
863 free(mdata); return(10);
864 }
865 /* Write matrix data */
866 /* Note that 3D scan header takes TWO blocks */
867 mptr=mdata;
868 ret=ecat7WriteMatrixdata(fp, nxtblk+2, mptr, pxlNr, ecat7pxlbytes(h->data_type));
869 free(mdata);
870 if(ret) {
871 sprintf(ecat7errmsg, "cannot write matrix data (%d).\n", ret);
872 return(13);
873 }
874 return(0);
875}

Referenced by imgWriteEcat7(), and imgWriteEcat7Frame().

◆ ecat7WriteSubheaderFromIFT()

int ecat7WriteSubheaderFromIFT ( FILE * fp,
ECAT7_mainheader * h,
int strtblk,
IFT * ift,
int verbose )
extern

Write ECAT 7 subheader from IFT struct into ECAT 7 file.

Returns
Returns STATUS_OK when succesful.
Parameters
fpFile pointer to opened ECAT7 file
hECAT7 mainheader
strtblkSubheader location
iftHeader data
verboseVerbose level

Definition at line 583 of file ecat7ift.c.

594 {
595 ECAT7_imageheader image_header;
596 ECAT7_scanheader scan_header;
597 ECAT7_2Dscanheader scan2D_header;
598 ECAT7_2Dnormheader norm2D_header;
599 ECAT7_normheader norm_header;
600 ECAT7_attenheader atten_header;
601 ECAT7_polmapheader polmap_header;
602 int ii, ret;
603
604 if(verbose>0) printf("ecat7WriteSubheaderFromIFT(fp, mh, %d, ift)\n", strtblk);
605 /* Check input */
606 if(fp==NULL || h==NULL || strtblk<3 || ift==NULL) return STATUS_FAULT;
607
608 /* Read subheader, set its contents from IFT, write subheader back */
609 switch(h->file_type) {
610 case ECAT7_ATTEN:
611 ret=ecat7ReadAttenheader(fp, strtblk, &atten_header);
612 if(ret!=0) return STATUS_NOSUBHEADER;
613 return STATUS_UNSUPPORTED;
614 break;
615 case ECAT7_3DNORM:
616 ret=ecat7ReadNormheader(fp, strtblk, &norm_header);
617 if(ret!=0) return STATUS_NOSUBHEADER;
618 return STATUS_UNSUPPORTED;
619 break;
620 case ECAT7_IMAGE8:
621 case ECAT7_IMAGE16:
622 case ECAT7_VOLUME8:
623 case ECAT7_VOLUME16:
624/*
625 ret=ecat7ImageheaderToIFT(&image_header, ift); if(ret!=STATUS_OK) return ret;
626*/
627 ret=ecat7ReadImageheader(fp, strtblk, &image_header);
628 if(ret!=0) return STATUS_NOSUBHEADER;
629 for(ii=ret=0; ii<ift->keyNr; ii++) {
630 if(verbose>7)
631 printf(" key := %s\n value := %s\n",
632 ift->item[ii].key, ift->item[ii].value);
633 ret=ecat7EditVHeader(&image_header, ift->item[ii].key, ift->item[ii].value, verbose-2);
634 if(ret!=0) {
635 if(verbose>0) fprintf(stderr, "Error with key '%s'\n", ift->item[ii].key);
636 break;
637 }
638 }
639 if(ret!=0) return STATUS_FAULT;
640 ret=ecat7WriteImageheader(fp, strtblk, &image_header);
641 if(ret!=0) return STATUS_NOSUBHEADER;
642 break;
643 case ECAT7_3DSCAN:
644 case ECAT7_3DSCAN8:
645 case ECAT7_3DSCANFIT:
646 ret=ecat7ReadScanheader(fp, strtblk, &scan_header);
647 if(ret!=0) return STATUS_NOSUBHEADER;
648 for(ii=ret=0; ii<ift->keyNr; ii++) {
649 if(verbose>7) printf(" key := %s\n value := %s\n", ift->item[ii].key, ift->item[ii].value);
650 ret=ecat7EditSHeader(&scan_header, ift->item[ii].key, ift->item[ii].value, verbose-2);
651 if(ret!=0) {
652 if(verbose>0) fprintf(stderr, "Error with key '%s'\n", ift->item[ii].key);
653 break;
654 }
655 }
656 if(ret!=0) return STATUS_FAULT;
657 ret=ecat7WriteScanheader(fp, strtblk, &scan_header);
658 if(ret!=0) return STATUS_NOSUBHEADER;
659 break;
660 case ECAT7_POLARMAP:
661 ret=ecat7ReadPolmapheader(fp, strtblk, &polmap_header);
662 if(ret!=0) return STATUS_NOSUBHEADER;
663 return STATUS_UNSUPPORTED;
664 break;
665 case ECAT7_2DSCAN:
666 ret=ecat7Read2DScanheader(fp, strtblk, &scan2D_header);
667 if(ret!=0) return STATUS_NOSUBHEADER;
668 return STATUS_UNSUPPORTED;
669 break;
670 case ECAT7_2DNORM:
671 ret=ecat7Read2DNormheader(fp, strtblk, &norm2D_header);
672 if(ret!=0) return STATUS_NOSUBHEADER;
673 return STATUS_UNSUPPORTED;
674 break;
675 default:
676 return STATUS_UNSUPPORTED;
677 }
678 return STATUS_OK;
679}
int ecat7EditSHeader(ECAT7_scanheader *h, char *field, char *value, int verbose)
Definition ecat7h.c:199
int ecat7EditVHeader(ECAT7_imageheader *h, char *field, char *value, int verbose)
Definition ecat7h.c:320

Referenced by ecat7WriteHeaders().

◆ ehdrAllocate()

int ehdrAllocate ( ECAT_HEADERS * ehdr,
int nr )
extern

Removes previous matrix contents but preserves the main header.

Returns
Returns STATUS_OK when succesful.
Parameters
ehdrPointer to list of ECAT headers
nrNr of headers to allocate

Definition at line 63 of file ecat7ift.c.

68 {
69 int i;
70
71 if(ehdr==NULL || nr<1) return STATUS_FAULT;
72 for(i=0; i<ehdr->nr; i++) {ematEmpty(&ehdr->m[i]);}
73 free(ehdr->m); ehdr->m=NULL; ehdr->nr=0;
74 ehdr->m=(ECAT_MATRIX*)malloc(nr*sizeof(ECAT_MATRIX));
75 if(ehdr->m==NULL) return STATUS_NOMEMORY;
76 for(i=0; i<nr; i++) ematInitiate(&ehdr->m[i]);
77 ehdr->nr=nr;
78 return STATUS_OK;
79}
void ematEmpty(ECAT_MATRIX *emat)
Definition ecat7ift.c:33
void ematInitiate(ECAT_MATRIX *emat)
Definition ecat7ift.c:12

Referenced by ecat7ReadHeaders(), and ecat7WriteHeaders().

◆ ehdrEmpty()

void ehdrEmpty ( ECAT_HEADERS * ehdr)
extern

Free memory allocated in ECAT_HEADERS

Parameters
ehdrPointer to header list struct

Definition at line 47 of file ecat7ift.c.

50 {
51 int i;
52
53 if(ehdr==NULL) return;
54 iftEmpty(&ehdr->mh);
55 for(i=0; i<ehdr->nr; i++) {ematEmpty(&ehdr->m[i]);}
56 free(ehdr->m); ehdr->m=NULL; ehdr->nr=0;
57}
void iftEmpty(IFT *ift)
Definition ift.c:60

Referenced by ecat7CopyHeadersNoQuant().

◆ ehdrInitiate()

void ehdrInitiate ( ECAT_HEADERS * ehdr)
extern

Initiate ECAT_HEADERS struct

Parameters
ehdrPointer to struct

Definition at line 21 of file ecat7ift.c.

24{
25 iftInit(&ehdr->mh);
26 ehdr->nr=0;
27 ehdr->m=(ECAT_MATRIX*)NULL;
28}
void iftInit(IFT *ift)
Definition ift.c:45

Referenced by ecat7CopyHeadersNoQuant().

◆ ematEmpty()

void ematEmpty ( ECAT_MATRIX * emat)
extern

Free memory allocated in ECAT_MATRIX

Parameters
ematPointer to ECAT matrix list

Definition at line 33 of file ecat7ift.c.

36 {
37 if(emat==NULL) return;
38 emat->mnum=0;
39 iftEmpty(&emat->sh);
40 if(emat->f!=NULL) free(emat->f);
41 emat->f=NULL;
42}

Referenced by ehdrAllocate(), and ehdrEmpty().

◆ ematInitiate()

void ematInitiate ( ECAT_MATRIX * emat)
extern

Initiate image data inside ECAT_MATRIX struct

Parameters
ematPointer to struct

Definition at line 12 of file ecat7ift.c.

15 {
16 emat->mnum=0;
17 iftInit(&emat->sh);
18 emat->f=(float*)NULL;
19}

Referenced by ehdrAllocate().

◆ f_kth_smallest()

float f_kth_smallest ( float * data,
long long int n,
long long int k )
extern

Returns the kth smallest value in data[0..n-1].

Array is partially sorted. Algorithm is based on the book Wirth N. Algorithms + data structures = programs. Englewood Cliffs, Prentice-Hall, 1976.

See also
fmedian
Returns
Returns the kth smallest value in data[0..n-1].
Parameters
dataPointer to data; array is partially sorted
nLength of data array
kkth smallest value will be returned

Definition at line 558 of file imgminmax.c.

565 {
566 long long int i, j, l, m;
567 float x, s;
568
569 l=0; m=n-1;
570 while(l<m) {
571 x=data[k]; i=l; j=m;
572 do {
573 while(data[i]<x) i++;
574 while(x<data[j]) j--;
575 if(i<=j) {s=data[i]; data[i]=data[j]; data[j]=s; i++; j--;}
576 } while(i<=j);
577 if(j<k) l=i;
578 if(k<i) m=j;
579 }
580 return(data[k]);
581}

Referenced by fmedian().

◆ float2parts()

void float2parts ( float * buf)
extern

Printfs separately the sign, mantissa, and exp part of a 32-bit float, which is pointed to by the argument. Code is not optimized; do not use this in routine operations!

Parameters
bufprinted float

Definition at line 277 of file ecat63p.c.

279 {
280 unsigned int u, exp, mantissa;
281 char sign;
282
283 memcpy(&u, buf, 4); if(u & 1L<<31) sign='-'; else sign='+';
284 exp=u<<1; exp=exp>>24; mantissa=u<<9; mantissa=mantissa>>9;
285 printf("%e = %c (%u/8388608 + 1)*2^(%u-127)\n", *buf, sign, mantissa, exp);
286}

◆ fmean()

float fmean ( float * data,
long long int n,
float * sd )
extern

Returns the mean in array data[0..n-1], and optionally calculates also the (sample) standard deviation of the mean.

See also
dmean, fmedian, mean, dmean_nan
Returns
Returns the mean in array data[0..n-1].
Parameters
dataPointer to data; data is not changed in any way.
nLength of data array.
sdPointer to variable where SD will be written; enter NULL if not needed.

Definition at line 618 of file imgminmax.c.

625 {
626 long long int i;
627 float sumsqr=0.0, sqrsum=0.0, avg;
628
629 if(n<1 || data==NULL) {if(sd!=NULL) *sd=0.0; return(0.0);}
630
631 for(i=0; i<n; i++) {sumsqr+=data[i]*data[i]; sqrsum+=data[i];}
632 avg=sqrsum/(float)n; if(sd==NULL) return(avg);
633 if(n==1) {
634 *sd=0.0;
635 } else {
636 sqrsum*=sqrsum;
637 *sd=sqrt( (sumsqr - sqrsum/(float)n) / (float)(n-1) );
638 }
639 return(avg);
640}

Referenced by imgBorderAverageTAC().

◆ fmedian()

float fmedian ( float * data,
long long int n )
extern

Returns the median in array data[0..n-1].

Array is partially sorted. Algorithm is based on the book Wirth N. Algorithms + data structures = programs. Englewood Cliffs, Prentice-Hall, 1976.

See also
fMinMax, imgAvg, dmedian
Returns
Returns the median in array data[0..n-1].
Parameters
dataPointer to data; array is partially sorted
nLength of data array

Definition at line 593 of file imgminmax.c.

598 {
599 long long int k;
600 float d1, d2;
601
602 if(n<1) return(0.0);
603 if(n%2) {
604 k=(n-1)/2; return(f_kth_smallest(data, n, k));
605 } else {
606 k=n/2; d1=f_kth_smallest(data, n, k-1); d2=f_kth_smallest(data, n, k);
607 return(0.5*(d1+d2));
608 }
609}
float f_kth_smallest(float *data, long long int n, long long int k)
Definition imgminmax.c:558

Referenced by imgBorderAverageTAC(), med21(), and med9().

◆ fMinMaxFin()

void fMinMaxFin ( float * data,
long long int n,
float * fmin,
float * fmax )
extern

Finds the minimum and maximum value in a float array.

Only finite values are considered.

See also
imgMinMax, imgAbsMax, imgAvg
Parameters
dataPointer to float array of size n.
nArray length.
fminPointer to float value for minimum; enter NULL if not needed.
fmaxPointer to float value for maximum; enter NULL if not needed.

Definition at line 649 of file imgminmax.c.

658 {
659 if(fmin!=NULL) *fmin=nanf("");
660 if(fmax!=NULL) *fmax=nanf("");
661
662 long long int i;
663 for(i=0; i<n; i++) if(isfinite(data[i])) break;
664 if(i==n) return; // no finite values found
665 float mi, ma;
666 mi=ma=data[i++];
667 for(; i<n; i++) if(isfinite(data[i])) {
668 if(data[i]>ma) ma=data[i];
669 else if(data[i]<mi) mi=data[i];
670 }
671 if(fmin!=NULL) *fmin=mi;
672 if(fmax!=NULL) *fmax=ma;
673 return;
674}

Referenced by ecat63WriteImageMatrix(), ecat63WriteScanMatrix(), ecat7Write2DScanMatrix(), ecat7WriteImageMatrix(), ecat7WritePolarmapMatrix(), ecat7WriteScanMatrix(), mrp(), and trmrp().

◆ img2sif()

int img2sif ( IMG * img,
SIF * sif,
int copy_header,
int copy_frames,
int copy_counts,
int verbose )
extern

Set SIF contents based on data in IMG.

Returns
Returns 0 if successful.
Parameters
imgPointer to IMG struct from which content is copied to SIF.
sifPointer to SIF. Must be initiated with sifInit(), but SIF is allocated here if necessary.
copy_headerSelect whether header contents are copied (1) or not copied (0) to SIF.
copy_framesSelect whether frame times are copied (1) or not copied (0) to SIF.
copy_countsSelect whether counts are copied (1) or not copied (0) to SIF, or created if they do not exist (2).
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 71 of file img_sif.c.

85 {
86 if(verbose>0)
87 printf("img2sif(img, sif, %d, %d, %d, ...)\n", copy_header, copy_frames, copy_counts);
88
89 /* Check the arguments */
90 if(img==NULL || sif==NULL) return(1);
91 if(img->dimt<1) return(1);
92
93 /* Verify that IMG contains frame times */
94 if(!imgExistentTimes(img)) {
95 if(verbose>0) printf(" image does not contain frame times.\n");
96 /* If not, then frame times cannot be copied */
97 copy_frames=0;
98 /* and counts can not be created */
99 if(copy_counts==2) copy_counts=1;
100 }
101
102 /* Check if count data needs to be created */
103 if(copy_counts==2 && imgExistentCounts(img)!=0)
104 copy_counts=1;
105
106 /* Verify that IMG contains isotope information */
107 if(img->isotopeHalflife<=0.0) {
108 if(verbose>0) printf(" image does not contain isotope halflife.\n");
109 /* not, then count data can not be created */
110 if(copy_counts==2) copy_counts=1;
111 }
112
113 /* Allocate memory for SIF if necessary */
114 if((copy_frames || copy_counts) && sif->frameNr!=img->dimt) {
115 if(sifSetmem(sif, img->dimt)!=0) return(3);
116 }
117
118 /* copy SIF header */
119 if(copy_header) {
120 if(verbose>1) printf(" copying header fields.\n");
121 sif->scantime=img->scanStart;
122 sif->colNr=4;
123 sif->version=1;
124 strcpy(sif->isotope_name, imgIsotope(img));
125 if(strlen(img->studyNr)>0 && strcmp(img->studyNr, ".")!=0)
126 strlcpy(sif->studynr, img->studyNr, MAX_STUDYNR_LEN+1);
127 else
128 strcpy(sif->studynr, "");
129 }
130
131 /* copy frame times */
132 if(copy_frames) {
133 if(verbose>1) printf(" copying frame times.\n");
134 for(int fi=0; fi<img->dimt; fi++) {
135 sif->x1[fi]=img->start[fi]; sif->x2[fi]=img->end[fi];
136 }
137 }
138
139 /* copy or create counts, if required */
140 if(copy_counts==2) {
141 if(verbose>1) printf(" creating count data.\n");
142 /* Calculate average of pixel values */
143 long long pxlNr=0;
144 for(int fi=0; fi<img->dimt; fi++) {
145 double v=0.0;
146 for(int k=0; k<img->dimz; k++)
147 for(int j=0; j<img->dimy; j++)
148 for(int i=0; i<img->dimx; i++) if(isfinite(img->m[k][j][i][fi])) {
149 v+=img->m[k][j][i][fi];
150 pxlNr++;
151 }
152 if(pxlNr>0) v/=(double)pxlNr;
153 sif->trues[fi]=v;
154 }
155 /* Multiply by frame durations, unless we have raw data */
156 if(img->type!=IMG_TYPE_RAW)
157 for(int fi=0; fi<img->dimt; fi++)
158 sif->trues[fi]*=(img->end[fi]-img->start[fi]);
159 /* Remove decay correction, unless we have raw data */
160 if(img->type!=IMG_TYPE_RAW
162 double lambda, cf, dur;
163 lambda=-hl2lambda(img->isotopeHalflife);
164 for(int fi=0; fi<img->dimt; fi++) {
165 dur=img->end[fi]-img->start[fi];
166 cf=hlLambda2factor(lambda, img->start[fi], dur);
167 if(cf>0.0) sif->trues[fi]*=cf;
168 }
169 }
170 /* Scale values to a realistic level */
171 double v=sif->trues[0];
172 for(int fi=1; fi<sif->frameNr; fi++) if(sif->trues[fi]>v) v=sif->trues[fi];
173 v=2.0E+07/v;
174 for(int fi=0; fi<sif->frameNr; fi++) sif->trues[fi]*=v;
175 /* Prompts are set to Trues and Randoms are set to zero */
176 for(int fi=0; fi<sif->frameNr; fi++) {
177 sif->prompts[fi]=sif->trues[fi];
178 sif->randoms[fi]=0.0;
179 if(sif->trues[fi]<1.0) sif->trues[fi]=1.0;
180 sif->weights[fi]=img->weight[fi];
181 }
182 } else if(copy_counts!=0) {
183 if(verbose>1) printf(" copying count data.\n");
184 for(int fi=0; fi<img->dimt; fi++) {
185 sif->prompts[fi]=img->prompts[fi];
186 sif->randoms[fi]=img->randoms[fi];
187 sif->trues[fi]=sif->prompts[fi]-sif->randoms[fi];
188 if(sif->trues[fi]<1.0) sif->trues[fi]=1.0;
189 sif->weights[fi]=img->weight[fi];
190 }
191 }
192
193 return(0);
194}
double hl2lambda(double halflife)
Definition halflife.c:84
double hlLambda2factor(double lambda, double frametime, double framedur)
Definition halflife.c:98
int imgExistentTimes(IMG *img)
Definition img.c:613
int imgExistentCounts(IMG *img)
Definition img.c:630
int sifSetmem(SIF *data, int frameNr)
Definition sif.c:56
float * weight
double * x1
double * prompts
int frameNr
double * x2
int version
char studynr[MAX_STUDYNR_LEN+1]
time_t scantime
char isotope_name[8]
double * weights
int colNr
double * randoms
double * trues

Referenced by imgWriteAnalyze(), and imgWriteNifti().

◆ img2svol()

int img2svol ( IMG * img,
SVOL * svol,
int frame )
extern

Copy one time frame (1..dimt) from 4D image to 3D short int volume. Svol can be but need not to be allocated.

Parameters
imgimage structure
svolshort volume structure
frameframe number [1..number of frames]
Returns
0 if ok, 1 invalid image status, 2 invalid input

Definition at line 305 of file vol.c.

305 {
306 int ret;
307 unsigned short int zi, yi, xi, fi;
308 float fmin, fmax, g;
309
310 if(VOL_TEST) printf("img2svol(img, %d, svol)\n", frame);
311 /* Check input */
312 if(svol==NULL) return(1);
313 svol->statmsg=_volStatusMessage[1];
314 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
315 if(frame<1 || img->dimt<frame) return(2);
316 if(svol->status==IMG_STATUS_UNINITIALIZED) return(1);
317
318 /* Allocate memory (if needed) for volume */
319 ret=svolAllocate(svol, img->dimz, img->dimy, img->dimx);
320 if(ret) return(ret);
321
322 /* Copy data */
323 fi=frame-1;
324 svol->orientation=img->orientation;
325 svol->sizex=img->sizex; svol->sizey=img->sizey; svol->sizez=img->sizez;
326 ret=imgFrameMinMax(img, frame, &fmin, &fmax); if(ret) return(10+ret);
327 if(fabs(fmin)>fabs(fmax)) g=fabs(fmin); else g=fabs(fmax);
328 if(g!=0) g=32766./g; else g=1.0;
329 for(zi=0; zi<svol->dimz; zi++)
330 for(yi=0; yi<svol->dimy; yi++)
331 for(xi=0; xi<svol->dimx; xi++)
332 svol->v[zi][yi][xi]=(short int)temp_roundf(g*img->m[zi][yi][xi][fi]);
333 svol->scale_factor=1.0/g;
334
335 return(0);
336}
int imgFrameMinMax(IMG *img, int frame, float *minvalue, float *maxvalue)
Definition imgminmax.c:171
int orientation
float sizey
unsigned short int dimx
unsigned short int dimz
int orientation
float sizez
unsigned short int dimy
float scale_factor
char status
char * statmsg
short int *** v
float sizex
char * _volStatusMessage[]
Definition vol.c:13
int VOL_TEST
Definition vol.c:6
int svolAllocate(SVOL *svol, int planes, int rows, int columns)
Definition vol.c:204

◆ img2vol()

int img2vol ( IMG * img,
VOL * vol,
int frame )
extern

Copy one time frame (1..dimt) from 4D image to 3D volume. Vol can be but need not to be allocated.

Parameters
imgimage structure
volvolume structure
frameframe number [1..number of frames]
Returns
0 if ok, 1 invalid image status, 2 invalid input

Definition at line 267 of file vol.c.

267 {
268 int ret;
269 unsigned short int zi, yi, xi, fi;
270
271 if(VOL_TEST) printf("img2vol(img, %d, vol)\n", frame);
272 /* Check input */
273 if(vol==NULL) return(1);
275 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
276 if(frame<1 || img->dimt<frame) return(2);
277 if(vol->status==IMG_STATUS_UNINITIALIZED) return(1);
278
279 /* Allocate memory (if needed) for volume */
280 ret=volAllocate(vol, img->dimz, img->dimy, img->dimx);
281 if(ret) return(ret);
282
283 /* Copy data */
284 fi=frame-1;
285 vol->orientation=img->orientation;
286 vol->sizex=img->sizex; vol->sizey=img->sizey; vol->sizez=img->sizez;
287 for(zi=0; zi<vol->dimz; zi++)
288 for(yi=0; yi<vol->dimy; yi++)
289 for(xi=0; xi<vol->dimx; xi++)
290 vol->v[zi][yi][xi]=img->m[zi][yi][xi][fi];
291
292 return(0);
293}
char status
unsigned short int dimx
unsigned short int dimy
int orientation
unsigned short int dimz
float sizex
char * statmsg
float *** v
float sizez
float sizey
int volAllocate(VOL *vol, int planes, int rows, int columns)
Definition vol.c:139

◆ imgAbsMax()

int imgAbsMax ( IMG * img,
float * maxvalue )
extern

Searches the max absolute pixel value in the IMG data.

Sets maxvalue to the absolute max value with sign.

See also
imgFrameMinMax, imgMinMax, imgMax, imgSmoothMax
Returns
0 if ok, 1 invalid image status, 2 invalid output pointer, 3 invalid image dimensions.
Parameters
imgPointer to IMG structure.
maxvaluePointer to output.

Definition at line 44 of file imgminmax.c.

49 {
50 if(img->status<IMG_STATUS_OCCUPIED) return(1);
51 if(maxvalue==NULL) return(2); else *maxvalue=0.0;
52 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(3);
53 float f=nanf("");
54 for(int pi=0; pi<img->dimz; pi++)
55 for(int yi=0; yi<img->dimy; yi++)
56 for(int xi=0; xi<img->dimx; xi++)
57 for(int fi=0; fi<img->dimt; fi++) {
58 if(!isfinite(f) || fabs(img->m[pi][yi][xi][fi])>fabs(f)) f=img->m[pi][yi][xi][fi];
59 }
60 *maxvalue=f;
61 return(0);
62}

◆ imgAllocate()

int imgAllocate ( IMG * image,
int planes,
int rows,
int columns,
int frames )
extern

Allocates memory for img data. Old contents are not saved.

See also
imgAllocateWithHeader, imgDup, imgEmpty, imgInit
Returns
0 if ok, 1 image is not initialized, 2 invalid input dimension(s), 3 failed to allocate header, 4 - 8 failed to allocate image data
Parameters
imagePointer to initialized image struct; old contents are deleted.
planesNr of image planes (dim z) to allocate.
rowsNr of image rows (dim y) to allocate.
columnsNr of image columns (dim x) to allocate.
framesNr of image time frames (dim t) to allocate.

Definition at line 194 of file img.c.

205 {
206 if(IMG_TEST) printf("imgAllocate(*image, %d, %d, %d, %d)\n", planes, rows, columns, frames);
207 /* Check arguments */
208 if(image==NULL) return(1);
209 imgSetStatus(image, STATUS_FAULT);
210 if(image->status==IMG_STATUS_UNINITIALIZED) return(1);
211 if(planes<1 || rows<1 || columns<1 || frames<1) return(2);
212 if(image->status>=IMG_STATUS_OCCUPIED) imgEmpty(image);
213 /* Allocate memory for header data */
214 imgSetStatus(image, STATUS_NOMEMORY);
215 image->_header=(float*)calloc(8*frames, sizeof(float));
216 if(image->_header==NULL) return(3);
217 image->planeNumber=(int*)calloc(planes, sizeof(int));
218 if(image->planeNumber==NULL) {free(image->_header); return(4);}
219 /* Allocate memory for image data */
220 image->_pln=(float****)calloc((size_t)planes, sizeof(float***));
221 if(image->_pln==NULL) {
222 free(image->_header); free(image->planeNumber);
223 return(5);
224 }
225 image->_row=(float***)calloc((size_t)planes*rows, sizeof(float**));
226 if(image->_row==NULL) {
227 free(image->_header); free(image->planeNumber);
228 free(image->_pln); return(6);
229 }
230 image->_col=(float**)calloc((size_t)planes*rows*columns, sizeof(float*));
231 if(image->_col==NULL) {
232 free(image->_header); free(image->planeNumber);
233 free(image->_pln); free(image->_row); return(7);
234 }
235 image->_pxl=(float*)calloc((size_t)planes*rows*columns*frames, sizeof(float));
236 if(image->_pxl==NULL) {
237 free(image->_header); free(image->planeNumber);
238 free(image->_pln); free(image->_row); free(image->_col); return(8);
239 }
240 /* Set data pointers */
241 float ***rptr, **cptr, *pptr;
242 rptr=image->_row; cptr=image->_col; pptr=image->_pxl;
243 for(unsigned short int zi=0; zi<planes; zi++) {
244 image->_pln[zi]=rptr;
245 for(unsigned short int ri=0; ri<rows; ri++) {
246 *rptr++=cptr;
247 for(unsigned short int ci=0; ci<columns; ci++) {
248 *cptr++=pptr; pptr+=frames;
249 }
250 }
251 }
252 image->m=image->_pln;
253 image->plane=image->_pln;
254 image->column=image->_col;
255 image->row=image->_row;
256 image->pixel=image->_pxl;
257 /* Set header pointers */
258 image->start= image->_header+0*frames;
259 image->end= image->_header+1*frames;
260 image->mid= image->_header+2*frames;
261 image->weight= image->_header+3*frames;
262 image->sd= image->_header+4*frames;
263 image->prompts= image->_header+5*frames;
264 image->randoms= image->_header+6*frames;
265 image->decayCorrFactor=image->_header+7*frames;
266 /* Ok */
267 image->dimz=planes; image->dimy=rows; image->dimx=columns; image->dimt=frames;
268 imgSetStatus(image, STATUS_OK);
270 return(0);
271}
float * pixel
float * sd
float *** row
float **** plane
float ** column

Referenced by ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), img2cube(), img_k1_using_ki(), imgAllocateWithHeader(), imgAUMC(), imgExtractRange(), imgFBP(), imgGetFrameDiff(), imgGetFrameDyn(), imgGetMaxFrame(), imgGetMaxTime(), imgMicropetCTToEcat7(), imgMicropetPETToEcat7(), imgMRP(), imgMRT(), imgOutlierFilter(), imgReadAnalyze(), imgReadAnalyzeFirstFrame(), imgReadEcat63FirstFrame(), imgReadEcat7(), imgReadEcat7FirstFrame(), imgReadFrame(), imgReadMicropetFirstFrame(), imgReadNifti(), imgReadNiftiFirstFrame(), imgReprojection(), imgStructuringElement(), imgThresholdingLowHigh(), and imgThresholdMaskCount().

◆ imgAllocateWithHeader()

int imgAllocateWithHeader ( IMG * image,
int planes,
int rows,
int columns,
int frames,
IMG * image_from )
extern

This functions just combines imgAllocate() and imgCopyhdr().

See also
imgAllocate, imgCopyhdr, imgDup
Returns
Returns 0 if successful, otherwise returns <>0.
Parameters
imagePointer to IMG struct which will be allocated here.
planesImage matrix dimensions; z.
rowsImage matrix dimensions; y.
columnsImage matrix dimensions; x.
framesImage matrix dimensions; t.
image_fromPointer to IMG struct where header contents will be copied from.

Definition at line 279 of file img.c.

292 {
293 int ret;
294 ret=imgAllocate(image, planes, rows, columns, frames); if(ret) return ret;
295 ret=imgCopyhdr(image_from, image); return ret;
296}
int imgCopyhdr(IMG *image1, IMG *image2)
Definition img.c:471

Referenced by img_logan(), img_patlak(), imgDup(), imgFlipAbove(), imgFlipRight(), imgFrameIntegral(), imgMeanZ(), imgNoiseTemplate(), imgPVCRRL(), imgPVCRVC(), imgsegmSimilar(), imgsegmThresholdMask(), imgShrink(), imgSwell(), and imgTimeIntegral().

◆ imgAvg()

int imgAvg ( IMG * img,
IMG_RANGE * r,
float * avg )
extern

Calculates average voxel value inside specified image range.

See also
imgMinMax, imgMax, fmedian, imgTimeIntegral
Returns
Returns 0 when successful.
Parameters
imgPointer to IMG image structure
rPointer to range inside IMG; enter NULL if whole IMG is used
avgTarget for mean value

Definition at line 503 of file imgminmax.c.

510 {
511 int zi, yi, xi, fi;
512 long long n=0;
513
514 if(img->status<IMG_STATUS_OCCUPIED) return(1);
515 if(r!=NULL) {
516 if(r->z1<1 || r->y1<1 || r->x1<1 || r->f1<1) return(2);
517 if(r->z2<r->z1 || r->y2<r->y1 || r->x2<r->x1 || r->f2<r->f1) return(3);
518 if(r->z2>img->dimz || r->y2>img->dimy || r->x2>img->dimx || r->f2>img->dimt) return(4);
519 }
520 if(avg==NULL) return(5);
521
522 *avg=0.0;
523 if(r!=NULL) {
524 for(zi=r->z1-1; zi<r->z2; zi++) {
525 for(yi=r->y1-1; yi<r->y2; yi++) {
526 for(xi=r->x1-1; xi<r->x2; xi++) {
527 for(fi=r->f1-1; fi<r->f2; fi++) if(!isnan(img->m[zi][yi][xi][fi])) {
528 *avg+=img->m[zi][yi][xi][fi]; n++;
529 }
530 }
531 }
532 }
533 } else {
534 for(zi=0; zi<img->dimz; zi++) {
535 for(yi=0; yi<img->dimy; yi++) {
536 for(xi=0; xi<img->dimx; xi++) {
537 for(fi=0; fi<img->dimt; fi++) if(!isnan(img->m[zi][yi][xi][fi])) {
538 *avg+=img->m[zi][yi][xi][fi]; n++;
539 }
540 }
541 }
542 }
543 }
544 if(n>0) *avg/=(float)n;
545 return(0);
546}

◆ imgBranchingCorrection()

int imgBranchingCorrection ( IMG * image,
int mode,
int verbose,
char * status )
extern

Corrects image data for branching fraction (mode=1) or removes correction (mode=0). Removal is primarily based on branching factor stored in IMG structure, secondarily on isotope; after removal, branching factor is set to 1, and pixel values and calibration factor are multiplied with it. Correction is based on branching fractions in branch.h; pixel values and calibration factor are divided by it, and its value is stored in IMG structure.

Note
This function can not know if branching fraction correction is included in the data (as it usually is) or not.
Returns
Returns 0 if ok.
See also
imgDecayCorrection, imgSetDecayCorrFactors, imgIsotope
Parameters
imagePointer to IMG data
modeBranching fraction correction (1) or removal of correction (0)
verboseVerbose level; if zero, then nothing is printed into stdout or stderr
statusPointer to allocated string where error message will be written; NULL, if not needed.

Definition at line 132 of file imgdecayc.c.

141 {
142 int isotope;
143 float bf;
144 float cf;
145
146 if(verbose>0) printf("imgBranchingCorrection(*img, %d, %d, *status)\n",
147 mode, verbose);
148 /* Check for arguments */
149 if(status!=NULL) strcpy(status, "invalid input");
150 if(image->status!=IMG_STATUS_OCCUPIED) return(1);
151 if(image->isotopeHalflife<=0.0) {
152 if(verbose>0) printf("Error: unknown isotope.\n");
153 if(status!=NULL) strcpy(status, "unknown isotope");
154 return(2);
155 }
156
157 /* If branching factor not found in IMG, then get it based on half-life */
158 bf=image->branchingFraction;
159 if(bf<=0.0 || bf>=1.0) {
160 isotope=hlIsotopeFromHalflife(image->isotopeHalflife/60.0);
161 if(verbose>2) printf("isotope := %d\n", isotope);
162 bf=branchingFraction(isotope);
163 }
164 if(bf<=0.0 || bf>=1.0) {
165 if(verbose>0) printf("Error: branching fraction unknown for the isotope.\n");
166 if(status!=NULL) strcpy(status, "branching fraction unknown for the isotope");
167 return(3);
168 }
169
170 /* Multiply with BF to remove correction, and divide to correct */
171 if(mode==0) cf=bf; else cf=1.0/bf;
172 /* Process pixel values */
173 if(verbose>1) printf("multiplying data by %g\n", cf);
174 for(int fi=0; fi<image->dimt; fi++) {
175 for(int pi=0; pi<image->dimz; pi++)
176 for(int i=0; i<image->dimy; i++)
177 for(int j=0; j<image->dimx; j++)
178 image->m[pi][i][j][fi]*=cf;
179 }
180
181 /* Fix header contents, too */
182 if(image->calibrationFactor>0.0) image->calibrationFactor*=cf;
183 if(mode==0) image->branchingFraction=0.0;
184 else image->branchingFraction=bf;
185
186 if(status!=NULL) strcpy(status, "ok");
187 return(0);
188}
float branchingFraction(int isotope)
Definition branch.c:14
int hlIsotopeFromHalflife(double halflife)
Definition halflife.c:195
float branchingFraction
float calibrationFactor

◆ imgCopyhdr()

int imgCopyhdr ( IMG * image1,
IMG * image2 )
extern

Copy the header fields from one image struct to another.

Does not copy memory addresses or IMG sizes. Frame times, decay correction factors etc are copied, when possible. Plane numbers are copied, when possible.

See also
imgAllocateWithHeader, imgDup
Returns
0 if successful, 1 invalid input, 2 pointers are to the same image
Parameters
image1Pointer to input IMG data.
image2Pointer to output IMG data.

Definition at line 471 of file img.c.

476 {
477 if(IMG_TEST) printf("imgCopyhdr()\n");
478 /* check */
479 if(image1==NULL || image2==NULL) return(1);
480 if(image1==image2) return(2);
481 /* copy */
482 image2->type=image1->type;
483 image2->unit=image1->unit;
484 image2->calibrationFactor=image1->calibrationFactor;
485 strcpy(image2->studyNr, image1->studyNr);
486 strcpy(image2->patientName, image1->patientName);
487 strcpy(image2->patientID, image1->patientID);
488 strcpy(image2->userProcessCode, image1->userProcessCode);
489 strcpy(image2->studyDescription, image1->studyDescription);
490 image2->zoom=image1->zoom;
491 strcpy(image2->radiopharmaceutical, image1->radiopharmaceutical);
492 image2->isotopeHalflife=image1->isotopeHalflife;
493 image2->decayCorrection=image1->decayCorrection;
494 image2->branchingFraction=image1->branchingFraction;
495 image2->scanStart=image1->scanStart;
496 image2->axialFOV=image1->axialFOV;
497 image2->transaxialFOV=image1->transaxialFOV;
498 image2->sampleDistance=image1->sampleDistance;
499 image2->sizex=image1->sizex;
500 image2->sizey=image1->sizey;
501 image2->sizez=image1->sizez;
502 image2->gapx=image1->gapx;
503 image2->gapy=image1->gapy;
504 image2->gapz=image1->gapz;
505 image2->resolutionx=image1->resolutionx;
506 image2->resolutiony=image1->resolutiony;
507 image2->resolutionz=image1->resolutionz;
508 image2->_dataType=image1->_dataType;
509 image2->_fileFormat=image1->_fileFormat;
510 image2->orientation=image1->orientation;
511 image2->scanner=image1->scanner;
512 image2->modality=image1->modality;
513 for(int i=0; i<2; i++) image2->xform[i]=image1->xform[i];
514 for(int i=0; i<18; i++) image2->quatern[i]=image1->quatern[i];
515 for(int i=0; i<12; i++) image2->mt[i]=image1->mt[i];
516 if(iftdup(&image1->ift, &image2->ift, 0)!=0) return(8);
518 for(int i=0; i<MAX_POLARMAP_NUM_RINGS; i++) {
521 image2->polarmap_ring_angle[i]=image1->polarmap_ring_angle[i];
522 }
524 if(image1->dimz==image2->dimz) for(int i=0; i<image1->dimz; i++) {
525 image2->planeNumber[i]=image1->planeNumber[i];
526 }
527 if(image1->dimt==image2->dimt) for(int i=0; i<image1->dimt; i++) {
528 image2->start[i]=image1->start[i]; image2->end[i]=image1->end[i];
529 image2->mid[i]=image1->mid[i];
530 image2->weight[i]=image1->weight[i]; image2->sd[i]=image1->sd[i];
531 image2->prompts[i]=image1->prompts[i];
532 image2->randoms[i]=image1->randoms[i];
533 image2->decayCorrFactor[i]=image1->decayCorrFactor[i];
534 }
535 image2->isWeight=image1->isWeight;
536 return(0);
537}
int iftdup(IFT *ift1, IFT *ift2, int verbose)
Definition ift.c:235
#define MAX_POLARMAP_NUM_RINGS
int polarmap_num_rings
float resolutionx
float resolutiony
short int polarmap_start_angle
float gapx
IFT ift
int modality
int polarmap_sectors_per_ring[MAX_POLARMAP_NUM_RINGS]
float mt[12]
short int polarmap_ring_angle[MAX_POLARMAP_NUM_RINGS]
float gapy
float gapz
char isWeight
float polarmap_ring_position[MAX_POLARMAP_NUM_RINGS]
float resolutionz

Referenced by img2cube(), img_k1_using_ki(), imgAllocateWithHeader(), imgAUMC(), imgExtractRange(), imgGetFrameDiff(), imgGetFrameDyn(), imgGetMaxFrame(), imgGetMaxTime(), imgMRT(), imgThresholdingLowHigh(), and imgThresholdMaskCount().

◆ imgDecayCorrection()

int imgDecayCorrection ( IMG * image,
int mode )
extern

Corrects (mode=1) or removes correction (mode=0) for physical decay. Removal is based on existing decay correction factors, when possible.

Returns
0 if ok, 1 image status is not 'occupied', 2 decay already corrected/not corrected, 3 image frame times missing
See also
imgSetDecayCorrFactors, imgBranchingCorrection, imgIsotope
Parameters
imagePointer to IMG data.
mode0=Remove decay correction; 1=Correct for decay.

Definition at line 16 of file imgdecayc.c.

21 {
22 float lambda;
23 float cf, dur;
24
25 /* Check for arguments */
26 if(image->status!=IMG_STATUS_OCCUPIED) return(1);
27 if(image->isotopeHalflife<=0.0) return(1);
28 /* Existing/nonexisting decay correction is an error */
29 if(mode==1 && image->decayCorrection!=IMG_DC_NONCORRECTED) return(2);
30 if(mode==0 && image->decayCorrection!=IMG_DC_CORRECTED) return(2);
31
32 /* All time frames */
33 for(int fi=0; fi<image->dimt; fi++) {
34 dur=image->end[fi]-image->start[fi];
35 if(image->end[fi]>0.0) {
36 if(mode==0 && image->decayCorrFactor[fi]>1.000001) {
37 /* if decay correction is to be removed, and factor is known,
38 then use it */
39 cf=1.0/image->decayCorrFactor[fi];
40 } else {
41 lambda=hl2lambda(image->isotopeHalflife); if(lambda<0.0) return(1);
42 /* remove decay correction by giving negative lambda */
43 if(mode==0) lambda=-lambda;
44 if(fi==image->dimt-1 && image->end[fi]<=0.0) return(3);
45 cf=hlLambda2factor_float(lambda, image->start[fi], dur);
46 }
47 if(IMG_TEST) printf("applied_dc_factor[%d] := %g\n", fi+1, cf);
48 /* Set decay correction factor inside IMG for future */
49 if(mode==0) {
50 image->decayCorrFactor[fi]=1.0;
51 } else {
52 image->decayCorrFactor[fi]=cf;
53 }
54 /* All planes, all matrices */
55 for(int pi=0; pi<image->dimz; pi++)
56 for(int i=0; i<image->dimy; i++)
57 for(int j=0; j<image->dimx; j++)
58 image->m[pi][i][j][fi]*=cf;
59 if(mode==0) image->decayCorrection=IMG_DC_NONCORRECTED;
61 /* in some cases left unchanged! */
62 }
63 } /* next frame */
64 return(0);
65}
float hlLambda2factor_float(float lambda, float frametime, float framedur)
Definition halflife.c:118

◆ imgDup()

int imgDup ( IMG * img1,
IMG * img2 )
extern

Duplicate IMG struct. Any existing contents in img2 will be deleted.

See also
imgAllocate, imgAllocateWithHeader, imgExtractRange
Returns
Returns 0 if successful.
Parameters
img1Pointer to IMG struct which will be duplicated
img2Pointer to initiated IMG struct into which the duplicate will be made

Definition at line 304 of file img.c.

309 {
310 if(img1==NULL || img2==NULL) return(1);
311 /* Delete any old contents */
312 imgEmpty(img2);
313 /* Allocate memory and copy headers */
314 int ret=imgAllocateWithHeader(img2, img1->dimz, img1->dimy, img1->dimx, img1->dimt, img1);
315 if(ret!=0) return(10+ret);
316 /* Copy voxel contents */
317 unsigned long long int n=img1->dimx*img1->dimy*img1->dimz*img1->dimt;
318 for(unsigned long long int i=0; i<n; i++) img2->pixel[i]=img1->pixel[i];
319 return 0;
320}
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
Definition img.c:279

Referenced by imgFlipAbove(), imgFlipRight(), imgMaskDilate(), imgMaskErode(), and imgMeanZ().

◆ imgEcat63Supported()

int imgEcat63Supported ( ECAT63_mainheader * h)
extern

Check whether read functions in IMG library support this ECAT 6.3 file_type.

Parameters
hEcat 6.3 main header
Returns
1 if supported, 0 if not.

Definition at line 1155 of file img_e63.c.

1155 {
1156 if(h==NULL) return(0);
1157 if(h->file_type==IMAGE_DATA) return(1);
1158 if(h->file_type==RAW_DATA) return(1);
1159 if(h->file_type==ATTN_DATA) return(1);
1160 if(h->file_type==NORM_DATA) return(1);
1161 return(0);
1162}

Referenced by imgReadEcat63Header().

◆ imgEcat7Supported()

int imgEcat7Supported ( ECAT7_mainheader * h)
extern

Check whether read functions in IMG library support this ECAT 7.x file_type.

Parameters
hEcat7 main header
Returns
1 if supported, 0 if not.

Definition at line 1036 of file img_e7.c.

1036 {
1037 if(h==NULL) return(0);
1038 if(h->file_type==ECAT7_VOLUME8) return(1);
1039 if(h->file_type==ECAT7_VOLUME16) return(1);
1040 if(h->file_type==ECAT7_IMAGE8) return(1);
1041 if(h->file_type==ECAT7_IMAGE16) return(1);
1042 if(h->file_type==ECAT7_2DSCAN) return(1);
1043 if(h->file_type==ECAT7_3DSCAN) return(1);
1044 if(h->file_type==ECAT7_3DSCAN8) return(1);
1045 if(h->file_type==ECAT7_3DSCANFIT) return(1);
1046 if(h->file_type==ECAT7_POLARMAP) return(1);
1047 return(0);
1048}

Referenced by imgRead(), imgReadEcat7(), imgReadEcat7Frame(), and imgReadEcat7Header().

◆ imgEmpty()

void imgEmpty ( IMG * image)
extern

Free memory that is allocated for IMG.

See also
imgInit, imgAllocate, imgRead
Parameters
imagePointer to IMG struct

Definition at line 121 of file img.c.

124 {
125 if(IMG_TEST) printf("imgEmpty()\n");
126 if(image==NULL || image->status<IMG_STATUS_OCCUPIED) return;
127 /* Free up memory */
128 if(image->_pxl!=NULL) free(image->_pxl);
129 if(image->_col!=NULL) free(image->_col);
130 if(image->_row!=NULL) free(image->_row);
131 if(image->_pln!=NULL) free(image->_pln);
132 if(image->dimz>0) {free(image->planeNumber);}
133 if(image->dimt>0) free(image->_header);
134 /* Set variables */
135 imgSetStatus(image, STATUS_OK);
136 image->type=0;
137 image->unit=0;
138 image->calibrationFactor=0;
139 image->zoom=0.0;
140 image->radiopharmaceutical[0]=(char)0;
141 image->isotopeHalflife=0.0;
142 image->decayCorrection=(char)IMG_DC_UNKNOWN;
143 image->branchingFraction=0.0;
144 image->unit=0;
145 image->scanStart=0;
146 image->orientation=0;
147 image->axialFOV=image->transaxialFOV=image->sampleDistance=0.0;
148 image->studyNr[0]=image->patientName[0]=image->patientID[0]=(char)0;
149 image->userProcessCode[0]=image->studyDescription[0]=(char)0;
150 image->sizex=image->sizey=image->sizez=0;
151 image->gapx=image->gapy=image->gapz=0.0;
152 image->resolutionx=image->resolutiony=image->resolutionz=0.0;
153 image->_dataType=0;
154 image->_fileFormat=0;
155 image->scanner=0;
156 image->modality=0;
157 for(int i=0; i<2; i++) image->xform[i]=NIFTI_XFORM_UNKNOWN;
158 for(int i=0; i<18; i++) image->quatern[i]=0.0;
159 for(int i=0; i<12; i++) image->mt[i]=0.0;
160 iftEmpty(&image->ift);
161 image->polarmap_num_rings=0;
162 for(int i=0; i<MAX_POLARMAP_NUM_RINGS; i++) {
163 image->polarmap_sectors_per_ring[i]=0;
164 image->polarmap_ring_position[i]=0.0;
165 image->polarmap_ring_angle[i]=0;
166 }
167 image->polarmap_start_angle=0;
168 image->dimt=image->dimx=image->dimy=image->dimz=0;
169 image->m=(float****)NULL;
170 image->_header=(float*)NULL;
171 image->pixel=(float*)NULL;
172 image->column=(float**)NULL;
173 image->row=(float***)NULL;
174 image->plane=(float****)NULL;
175 image->planeNumber=(int*)NULL;
176 image->start=image->end=image->mid=(float*)NULL;
177 image->isWeight=0;
178 image->weight=image->sd=(float*)NULL;
179 image->decayCorrFactor=(float*)NULL;
180 /* Set status */
182 image->errstatus=STATUS_OK;
183}
int errstatus

Referenced by ecat63ReadPlaneToImg(), img2cube(), img_k1_using_ki(), img_logan(), img_patlak(), imgAllocate(), imgAnalyzeToEcat(), imgAUMC(), imgDup(), imgExtractRange(), imgFBP(), imgFlipAbove(), imgFlipRight(), imgFormatDetermine(), imgFrameIntegral(), imgGetFrameDiff(), imgGetFrameDyn(), imgGetMaxFrame(), imgGetMaxTime(), imgMaskDilate(), imgMaskErode(), imgMaskRegionLabeling(), imgMicropetCTToEcat7(), imgMicropetPETToEcat7(), imgMRP(), imgMRT(), imgNiftiToEcat(), imgOutlierFilter(), imgPVCRRL(), imgPVCRVC(), imgReadFrame(), imgReadMicropet(), imgReadMinMax(), imgReadModelingData(), imgReprojection(), imgsegmSimilar(), imgStructuringElement(), imgThresholding(), imgThresholdingLowHigh(), imgWriteAnalyzeFrame(), imgWriteEcat63Frame(), imgWriteEcat7Frame(), and imgWriteNiftiFrame().

◆ imgExistentCounts()

int imgExistentCounts ( IMG * img)
extern

Verify that IMG contains prompts and randoms.

See also
imgExistentTimes
Returns
Returns 0 if neither prompts or randoms can be found, 1 or 2 if prompts or randoms can be found, and 3 if both prompts and randoms are there.
Parameters
imgPointer to IMG struct

Definition at line 630 of file img.c.

633 {
634 int p=0, r=0;
635 float v1, v2;
636 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED || img->dimt<1) return 0;
637 /* If just one frame, then value > 0 is fine */
638 if(img->dimt==1) {
639 if(img->prompts[0]>0.00000001) p=1;
640 if(img->randoms[0]>0.00000001) r=2;
641 return(p+r);
642 }
643 /* Otherwise, check also that frames have different count level */
644 for(int fi=1; fi<img->dimt; fi++) {
645 v1=img->prompts[fi]-img->prompts[fi-1]; if(fabs(v1)>0.001) p=1;
646 v2=img->randoms[fi]-img->randoms[fi-1]; if(fabs(v2)>0.001) r=2;
647 if((p+r)>2) break;
648 }
649 return(p+r);
650}

Referenced by img2sif().

◆ imgExistentTimes()

int imgExistentTimes ( IMG * img)
extern

Verify that IMG contains frame times.

See also
imgExistentCounts, imgFramesCheck
Returns
Returns nonzero if frame times are there, and 0 if not.
Parameters
imgPointer to IMG struct.

Definition at line 613 of file img.c.

616 {
617 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED || img->dimt<1) return 0;
618 for(int fi=0; fi<img->dimt; fi++) if(img->end[fi]>0.00000001) return 1;
619 return 0;
620}

Referenced by img2sif(), imgAUMC(), imgFrameIntegral(), imgMRT(), imgNoiseTemplate(), and imgReadModelingData().

◆ imgExtractRange()

int imgExtractRange ( IMG * img1,
IMG_RANGE r,
IMG * img2 )
extern

Extract a smaller 4D image from inside an IMG.

Any existing data is overwritten.

See also
imgInit, imgEmpty, imgDup
Returns
0 if ok, 1 invalid input, 2 failed to allocate memory for target image
Parameters
img1Source image structure, 'occupied' (has allocated data).
rImage range structure.
img2Target image structure 'initialized' (has not allocated data).

Definition at line 548 of file img.c.

555 {
556 int zi, yi, xi, fi, zj, yj, xj, fj;
557
558 if(IMG_TEST) {
559 printf("imgExtractRange(*img1, r, *img2)\n");
560 printf(" z=[%d,%d] y=[%d,%d] x=[%d,%d] f=[%d,%d]\n",
561 r.z1, r.z2, r.y1, r.y2, r.x1, r.x2, r.f1, r.f2);
562 }
563 /* Check arguments */
564 if(img2==NULL) return(1); else imgSetStatus(img2, STATUS_FAULT);
565 if(img1->status!=IMG_STATUS_OCCUPIED) return(1);
566 if(img2->status==IMG_STATUS_UNINITIALIZED) return(1);
567 if(r.z1<1 || r.z2>img1->dimz || r.z1>r.z2) return(1);
568 if(r.y1<1 || r.y2>img1->dimy || r.y1>r.y2) return(1);
569 if(r.x1<1 || r.x2>img1->dimx || r.x1>r.x2) return(1);
570 if(r.f1<1 || r.f2>img1->dimt || r.f1>r.f2) return(1);
571
572 /* Allocate memory unless the same size was previously allocated */
573 imgSetStatus(img2, STATUS_NOMEMORY);
574 zi=r.z2-r.z1+1; yi=r.y2-r.y1+1; xi=r.x2-r.x1+1; fi=r.f2-r.f1+1;
575 if(img2->status>=IMG_STATUS_OCCUPIED)
576 if(img2->dimz!=zi || img2->dimy!=yi || img2->dimx!=xi || img2->dimt!=fi)
577 imgEmpty(img2);
578 if(img2->status!=IMG_STATUS_OCCUPIED) {
579 if(imgAllocate(img2, zi, yi, xi, fi)!=0) return(2);
580 }
581
582 /* Copy data */
583 imgCopyhdr(img1, img2);
584 for(fi=r.f1-1, fj=0; fi<r.f2; fi++, fj++) {
585 img2->start[fj]=img1->start[fi];
586 img2->end[fj]=img1->end[fi];
587 img2->mid[fj]=img1->mid[fi];
588 img2->weight[fj]=img1->weight[fi];
589 img2->sd[fj]=img1->sd[fi];
590 img2->prompts[fj]=img1->prompts[fi];
591 img2->randoms[fj]=img1->randoms[fi];
592 img2->decayCorrFactor[fj]=img1->decayCorrFactor[fi];
593 }
594 for(zi=r.z1-1, zj=0; zi<r.z2; zi++, zj++) {
595 img2->planeNumber[zj]=img1->planeNumber[zi];
596 }
597 for(zi=r.z1-1, zj=0; zi<r.z2; zi++, zj++)
598 for(yi=r.y1-1, yj=0; yi<r.y2; yi++, yj++)
599 for(xi=r.x1-1, xj=0; xi<r.x2; xi++, xj++)
600 for(fi=r.f1-1, fj=0; fi<r.f2; fi++, fj++)
601 img2->m[zj][yj][xj][fj]=img1->m[zi][yi][xi][fi];
602
603 imgSetStatus(img2, STATUS_OK);
604 return(0);
605}

◆ imgFormatDetermine()

int imgFormatDetermine ( const char * fname,
char * basename,
char * hdrfile,
char * imgfile,
char * siffile,
int * file_format,
int * scanner,
int * type,
int * modality,
int verbose )
extern

Determine the file format and type of an existing PET image data.

Note that this function only identifies those formats and types that were needed in TPC at the time of writing this function. Note also that this function does not care whether the format is fully or not at all supported by other library functions.

See also
imgRead, imgWrite, imgReadHeader
Returns
Returns 0 when no errors occurred, which does not mean that format was identified.
Parameters
fnameFull name of image file. In case of Analyze or microPET image, hdr or img file name, or basename without extension is accepted. Pathname is not accepted.
basenamePointer to allocated string where image file name without extensions is written (only for Analyze and microPET); enter NULL, if not needed.
hdrfilePointer to allocated string where header file name without extensions is written (only for Analyze and microPET); enter NULL, if not needed.
imgfilePointer to allocated string where image data file name without extensions is written (only for Analyze and microPET); enter NULL, if not needed.
siffilePointer to allocated string where SIF file name without extensions is written (only for Analyze), if available; enter NULL, if not needed.
file_formatPointer to int where image format ID is written; 0=unknown, for other formats see definitions in img.h
scannerPointer to int where scanner ID is written; 0=unknown, for other formats see definitions in img.h
typePointer to int where image type is written; 0=unknown, 1=image, 2=sinogram, 3=polarmap, please check definitions in img.h
modalityPointer to int where modality is written; 0=unknown, 1=PET, 2=MRI, 3=CT, ..., please check definitions in img.h
verboseVerbose level; if zero, then nothing is printed into stdout or stderr

Definition at line 536 of file imgfile.c.

566 {
567 char *cptr, temp[FILENAME_MAX];
568 int ret, fformat=IMG_UNKNOWN;
569 NIFTI_DSR nifti_dsr;
570 IMG img;
571
572 if(verbose>0) {printf("imgFormatDetermine(\"%s\", ...)\n", fname); fflush(stdout);}
573 /* Initiate results */
574 if(basename!=NULL) strcpy(basename, "");
575 if(hdrfile!=NULL) strcpy(hdrfile, "");
576 if(imgfile!=NULL) strcpy(imgfile, "");
577 if(siffile!=NULL) strcpy(siffile, "");
578 if(file_format!=NULL) *file_format=IMG_UNKNOWN;
579 if(scanner!=NULL) *scanner=SCANNER_UNKNOWN;
580 if(type!=NULL) *type=IMG_TYPE_UNKNOWN;
581 if(modality!=NULL) *modality=IMG_MODALITY_UNKNOWN;
582 if(fname==NULL) return STATUS_FAULT;
583 if(strlen(fname)<1) return STATUS_NOFILE;
584
585 /* Check the image data exists and is accessible */
586 strcpy(temp, fname);
587 if(access(temp, 0) == -1) {
588 if(verbose>1) printf(" file is not directly accessible.\n");
589 /* Try to add .nii to the name */
590 sprintf(temp, "%s.nii", fname);
591 if(access(temp, 0) == -1) {
592 if(verbose>1) printf(" file is not accessible with .nii extension.\n");
593 /* Try to add .img to the name */
594 sprintf(temp, "%s.img", fname);
595 if(access(temp, 0) == -1) {
596 if(verbose>1) printf(" file is not accessible with .img extension.\n");
597 /* Try to add .hdr to the name */
598 sprintf(temp, "%s.hdr", fname);
599 if(access(temp, 0) == -1) sprintf(temp, "%s.i.hdr", fname);
600 if(access(temp, 0) == -1) sprintf(temp, "%s.img.hdr", fname);
601 if(access(temp, 0) == -1) {
602 if(verbose>1) printf(" file is not accessible with .hdr extension.\n");
603 /* Try to add .dcm to the name */
604 sprintf(temp, "%s.dcm", fname);
605 if(access(temp, 0) == -1) {
606 if(verbose>1) printf(" file is not accessible with .dcm extension.\n");
607 return STATUS_NOFILE;
608 }
609 }
610 }
611 }
612 }
613 if(verbose>1) {printf("'%s' is accessible.\n", temp); fflush(stdout);}
614
615 /* DICOM is identified from the file name extension, and not processed any further */
616 cptr=strrchr(temp, '.');
617 if(cptr!=NULL && strcasecmp(cptr, ".DCM")==0) {
618 fformat=IMG_DICOM; if(file_format!=NULL) *file_format=fformat;
619 if(verbose>1) printf("file was identified to be in DICOM format.\n");
620 return STATUS_OK;
621 }
622
623 /* Try to read it as ECAT file first, because images which consist of
624 more than one file may reside in the same folder with
625 other formats */
626 imgInit(&img);
627 /* Is this an ECAT7 file */
628 ret=imgReadEcat7Header(fname, &img);
629 if(ret==STATUS_OK) {
630 fformat=img._fileFormat; if(file_format!=NULL) *file_format=fformat;
631 if(verbose>1) printf("file was identified to be in ECAT7 format.\n");
632 } else if(ret==STATUS_VARMATSIZE) {
633 fformat=img._fileFormat; if(file_format!=NULL) *file_format=fformat;
634 if(verbose>1) printf("file is ECAT7 but matrix sizes are different\n.");
635 } else if(ret==STATUS_UNKNOWNFORMAT || ret==STATUS_NOFILE) {
636 /* If main header was read but format was not identified as Ecat7,
637 it might be in Ecat6 format */
638 ret=imgReadEcat63Header(fname, &img);
639 /* if necessary, try also with .img added */
640 if(ret!=STATUS_OK && ret!=STATUS_VARMATSIZE && ret!=STATUS_MISSINGMATRIX) {
641 sprintf(temp, "%s.img", fname); ret=imgReadEcat63Header(temp, &img);}
642 if(ret==STATUS_OK) {
643 /* Is this an ECAT6 file; however this is rather uncertain step, because
644 ECAT6 files don't contain any magic number */
645 fformat=img._fileFormat; if(file_format!=NULL) *file_format=fformat;
646 if(verbose>1) printf("file was identified to be in ECAT6 format.\n");
647 } else if(ret==STATUS_VARMATSIZE || ret==STATUS_MISSINGMATRIX) {
648 fformat=img._fileFormat; if(file_format!=NULL) *file_format=fformat;
649 if(verbose>1) printf("file is ECAT63 but matrix sizes are different\n.");
650 }
651 }
652
653 /* If format was not yet identified, then try to read it as NIfTI;
654 this must be done before trying Analyze, because dual format NIfTI
655 is compatible with Analyze format */
656 if(fformat==IMG_UNKNOWN &&
657 niftiExists(fname, hdrfile, imgfile, siffile, &nifti_dsr, verbose-2, NULL)>0)
658 {
659 if(verbose>1) printf("file was identified to be in NIfTI format.\n");
660 /* Read NIfTI header information into IMG struct */
661 ret=imgGetNiftiHeader(&img, &nifti_dsr, verbose-2);
662 if(ret==STATUS_OK) {
663 fformat=img._fileFormat; if(file_format!=NULL) *file_format=fformat;
664 }
665 }
666
667 /* If format was not yet identified, then try to read it as microPET */
668 if(fformat==IMG_UNKNOWN && upetExists(fname, hdrfile, imgfile, verbose-1)==2) {
669 fformat=IMG_MICROPET; if(file_format!=NULL) *file_format=fformat;
670 if(verbose>1) printf("file was identified to be in microPET format\n.");
671 /* Read header information from file */
672 ret=imgReadMicropetHeader(fname, &img);
673 if(ret==STATUS_OK) {
674 fformat=img._fileFormat; if(file_format!=NULL) *file_format=fformat;
675 }
676 }
677
678 /* If format was not yet identified, then try to read it as Analyze */
679 if(fformat==IMG_UNKNOWN && anaDatabaseExists(fname, hdrfile, imgfile, siffile)>0) {
680 if(verbose>1) printf("file was identified to be in Analyze format.\n");
681 fformat=IMG_ANA; if(file_format!=NULL) *file_format=fformat;
682 /* Read Analyze header information */
683 ret=imgReadAnalyzeHeader(hdrfile, &img);
684 if(ret==STATUS_OK) {
685 fformat=img._fileFormat; if(file_format!=NULL) *file_format=fformat;
686 }
687 }
688
689 /* If format was not yet identified, check if it is DICOM (without .dcm extension
690 that was checked previously) */
691 if(dcmVerifyMagic(fname, NULL)) {
692 fformat=IMG_DICOM; if(file_format!=NULL) *file_format=fformat;
693 if(verbose>1) printf("file was identified to be in DICOM format.\n");
694 return STATUS_OK;
695 }
696
697 /* If format was not yet identified, check if it is Interfile */
698 if(fformat==IMG_UNKNOWN && interfileExists(fname, hdrfile, imgfile, verbose-1)!=0) {
699 fformat=IMG_INTERFILE; if(file_format!=NULL) *file_format=fformat;
700 if(verbose>1) printf("file was identified to be in Interfile format\n.");
701 }
702
703 /* Fill other information */
704 if(scanner!=NULL) *scanner=img.scanner;
705 if(type!=NULL) *type=img.type;
706 if(modality!=NULL) *modality=img.modality;
707
708 /* Quit */
709 imgEmpty(&img);
710 if(verbose>1) printf("fformat := %d\n", fformat);
711 return STATUS_OK;
712}
void imgInit(IMG *image)
Definition img.c:60
int imgReadAnalyzeHeader(const char *dbname, IMG *img)
Definition img_ana.c:360
int imgReadEcat63Header(const char *fname, IMG *img)
Definition img_e63.c:1318
int imgReadEcat7Header(const char *fname, IMG *img)
Definition img_e7.c:860
int imgGetNiftiHeader(IMG *img, NIFTI_DSR *dsr, int verbose)
Definition img_nii.c:218
int imgReadMicropetHeader(const char *dbname, IMG *img)
Definition img_upet.c:767
int interfileExists(const char *fname, char *hdrfile, char *imgfile, int verbose)
Definition interfile.c:193
#define IMG_INTERFILE
#define IMG_TYPE_UNKNOWN
#define IMG_UNKNOWN
#define IMG_DICOM
int niftiExists(const char *dbname, char *hdrfile, char *imgile, char *siffile, NIFTI_DSR *header, int verbose, char *status)
Definition nifti.c:160
#define IMG_ANA
#define IMG_MICROPET
int upetExists(const char *upetname, char *hdrfile, char *imgfile, int verbose)
Definition micropet.c:86
#define SCANNER_UNKNOWN
#define IMG_MODALITY_UNKNOWN

Referenced by imgReadHeader().

◆ imgFormatFromFName()

void imgFormatFromFName ( IMG * img,
const char * fname )
extern

Determine IMG _fileFormat from file name extension, if not already defined. Default is ECAT 7 image volume, if nothing else can be guessed.

Note that NIfTI dual file format, Analyze, and microPET files can not be separated by file naming, thus all of these formats will be identified as Analyze by this function (default may be changed to NIfTI in future).

See also
imgRead, imgWrite
Parameters
imgTarget image structure where file format is saved; should have IMG_UNKNOWN as file type.
fnameName of file that is used to determine format.

Definition at line 483 of file imgfile.c.

488 {
489 char *cptr=NULL, *cptr2=NULL, temp[FILENAME_MAX];
490
491 if(IMG_TEST>2) printf("imgFormatFromFName(img, %s)\n", fname);
492 if(img->_fileFormat!=IMG_UNKNOWN && img->_fileFormat>0) {
493 if(IMG_TEST>3) printf(" _fileFormat := %d, not changed\n", img->_fileFormat);
494 return;
495 }
496 img->_fileFormat=IMG_E7; /* default */
497 /* get extensions */
498 strcpy(temp, fname); cptr=strrchr(temp, '.');
499 if(cptr!=NULL) {
500 *cptr=(char)0; cptr++;
501 cptr2=strrchr(temp, '.'); if(cptr2!=NULL) {*cptr2=(char)0; cptr2++;}
502 }
503 if(cptr2!=NULL) {
504 if(strcasecmp(cptr2, "i.hdr")==0) { img->_fileFormat=IMG_INTERFILE; return;}
505 if(strcasecmp(cptr2, "i.img")==0) { img->_fileFormat=IMG_INTERFILE; return;}
506 }
507 if(cptr!=NULL) {
508 if(strcasecmp(cptr, "hdr")==0) { img->_fileFormat=IMG_ANA; return;}
509 if(strcasecmp(cptr, "polmap")==0) { img->_fileFormat=IMG_POLARMAP; return;}
510 if(strcasecmp(cptr, "img")==0 ||
511 strcasecmp(cptr, "scn")==0 ||
512 strcasecmp(cptr, "nrm")==0 ||
513 strcasecmp(cptr, "atn")==0) {
514 img->_fileFormat=IMG_E63; return;
515 }
516 if(strcasecmp(cptr, "dcm")==0) { img->_fileFormat=IMG_DICOM; return;}
517 if(strcasecmp(cptr, "i")==0) { img->_fileFormat=IMG_INTERFILE; return;}
518 if(strcasecmp(cptr, "nii")==0) { img->_fileFormat=IMG_NIFTI_1S; return;}
519 } else { /* no extension at all */
520 img->_fileFormat=IMG_ANA;
521 }
522}
#define IMG_E7
#define IMG_NIFTI_1S
#define IMG_POLARMAP

Referenced by imgWrite(), and imgWriteFrame().

◆ imgFrameMinMax()

int imgFrameMinMax ( IMG * img,
int frame,
float * minvalue,
float * maxvalue )
extern

Searches the min and max pixel value in one frame (1..dimt) of the IMG data.

Returns
0 if ok, 1 invalid image status, 2 invalid output pointer, 3 invalid image dimensions.
See also
imgMinMax, imgRangeMinMax, imgReadMinMax, imgGetMaxFrame
Parameters
imgPointer to IMG data.
frameFrame number [1..number of frames].
minvaluePointer to float value where minimum is written.
maxvaluePointer to float value where maximum is written.

Definition at line 171 of file imgminmax.c.

180 {
181 if(img->status<IMG_STATUS_OCCUPIED) return(1);
182 if(minvalue==NULL || maxvalue==NULL) return(2);
183 *minvalue=*maxvalue=0.0;
184 int fi=frame-1;
185 if(img->dimt<frame || img->dimz<1 || img->dimy<1 || img->dimx<1) return(3);
186 if(frame<1) return(4);
187
188 float mi, ma;
189 mi=ma=nanf("");
190 for(int pi=0; pi<img->dimz; pi++)
191 for(int yi=0; yi<img->dimy; yi++)
192 for(int xi=0; xi<img->dimx; xi++) {
193 if(!isfinite(ma) || img->m[pi][yi][xi][fi]>ma) ma=img->m[pi][yi][xi][fi];
194 if(!isfinite(mi) || img->m[pi][yi][xi][fi]<mi) mi=img->m[pi][yi][xi][fi];
195 }
196 *minvalue=mi; *maxvalue=ma;
197 if(!isfinite(mi) || !isfinite(ma)) return(5);
198 return(0);
199}

Referenced by img2svol().

◆ imgGetAnalyzeHeader()

int imgGetAnalyzeHeader ( IMG * img,
ANALYZE_DSR * h )
extern

Copy Analyze 7.5 header information into IMG.

Parameters
imgimage structure
hAnalyze header structure
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 427 of file img_ana.c.

428{
429 int dimNr, dimx, dimy, dimz=1, dimt=1;
430
431 if(IMG_TEST) printf("\nimgGetAnalyzeHeader(*img, *dsr)\n");
432
433 /* Check the input */
434
435 if(img==NULL) return STATUS_FAULT;
437 return STATUS_FAULT;
438 imgSetStatus(img, STATUS_FAULT);
439 if(h==NULL) return STATUS_FAULT;
440
441 imgSetStatus(img, STATUS_INVALIDHEADER);
442
443 /* Get the image dimensions from header */
444 dimNr=h->dime.dim[0];
445 if(dimNr<2) return STATUS_INVALIDHEADER;
446 dimx=h->dime.dim[1]; dimy=h->dime.dim[2];
447 if(dimNr>2) {dimz=h->dime.dim[3]; if(dimNr>3) dimt=h->dime.dim[4];}
448 long long pxlNr=dimx*dimy*dimz;
449 if(pxlNr<1) return STATUS_INVALIDHEADER;
450 img->dimx=dimx; img->dimy=dimy; img->dimz=dimz; img->dimt=dimt;
451
452 /* Copy information from Analyze header */
453 img->type=IMG_TYPE_IMAGE;
455 if(strcmp(img->studyNr, ".")==0) strcpy(img->studyNr, "");
456 strcpy(img->patientName, h->hist.patient_id);
457 img->sizex=h->dime.pixdim[1];
458 img->sizey=h->dime.pixdim[2];
459 img->sizez=h->dime.pixdim[3];
460 /*if(h->dime.funused2>1.E-5) img->zoom=h->dime.funused2;*/
461 if(h->dime.funused3>1.E-5) img->isotopeHalflife=h->dime.funused3;
462 if(h->little) img->_fileFormat=IMG_ANA_L; else img->_fileFormat=IMG_ANA;
463
464 /* Decay correction */
465 if(strstr(h->hist.descrip, "Decay corrected.")!=NULL)
467 else if(strstr(h->hist.descrip, "No decay correction.")!=NULL)
469 else
470 img->decayCorrection=IMG_DC_CORRECTED; // just assumed so
471
472 imgSetStatus(img, STATUS_OK);
473 return STATUS_OK;
474}
#define IMG_ANA_L

Referenced by imgReadAnalyzeHeader().

◆ imgGetEcat63Fileformat()

int imgGetEcat63Fileformat ( ECAT63_mainheader * h)
extern

Return the IMG fileformat based on ECAT 6.3 file_type.

Parameters
hEcat 6.3 main header
Returns
IMG._fileFormat value.

Definition at line 1288 of file img_e63.c.

1288 {
1289 int fileFormat=IMG_UNKNOWN;
1290 switch(h->file_type) {
1291 case IMAGE_DATA:
1292 case RAW_DATA:
1293 case ATTN_DATA:
1294 case NORM_DATA:
1295 fileFormat=IMG_E63; break;
1296 default:
1297 fileFormat=IMG_UNKNOWN; break;
1298 }
1299 return fileFormat;
1300}

Referenced by imgReadEcat63Header().

◆ imgGetEcat63MHeader()

void imgGetEcat63MHeader ( IMG * img,
ECAT63_mainheader * h )
extern

Copy ECAT 6.3 main header information into IMG

Parameters
imgtarget image structure
hsource Ecat 6.3 main header

Definition at line 1172 of file img_e63.c.

1173{
1174 if(IMG_TEST>0) printf("imgGetEcat63MHeader()\n");
1175 img->_dataType=h->data_type; /* again in subheaders*/
1176 /* For saving IMG data, only 2-byte VAX data types are allowed,
1177 so change it now */
1178 if(img->_dataType==VAX_I4 || img->_dataType==VAX_R4) img->_dataType=VAX_I2;
1179 img->scanner=h->system_type;
1183 if(img->scanStart==-1) {
1184 img->scanStart=0;
1185 if(IMG_TEST>0) printf("invalid scan_start_time in mainheader\n");
1186 }
1187 if(IMG_TEST>1) {
1188 char buf1[32], buf2[32];
1189 printf(" %s -> %s\n", ecat63ScanstarttimeInt(h, buf1),
1190 ctime_r_int(&img->scanStart, buf2));
1191 }
1192 img->axialFOV=10.0*h->axial_fov;
1193 img->transaxialFOV=10.0*h->transaxial_fov;
1195 strlcpy(img->patientName, h->patient_name, 32);
1196 strlcpy(img->patientID, h->patient_id, 16);
1197 img->sizez=10.0*h->plane_separation;
1198 switch(h->file_type) {
1199 case IMAGE_DATA: img->type=IMG_TYPE_IMAGE; break;
1200 case RAW_DATA:
1201 case ATTN_DATA:
1202 case NORM_DATA:
1203 default: img->type=IMG_TYPE_RAW;
1204 }
1206 strncpy(img->userProcessCode, h->user_process_code, 10);
1207 img->userProcessCode[10]=(char)0;
1208 /* If valid study number is found in user_process_code, then take it */
1209 if(!img->studyNr[0] && studynr_validity_check(img->userProcessCode))
1211 /* Set calibration unit (this may have to be read from subheader later) */
1213}
char * ecat63ScanstarttimeInt(const ECAT63_mainheader *h, char *buf)
Convert scan_start_time in ECAT 6.3 main header into a null-terminated string of the form YYYY-MM-DD ...
Definition ecat63p.c:391

Referenced by imgReadEcat63Header().

◆ imgGetEcat7Fileformat()

int imgGetEcat7Fileformat ( ECAT7_mainheader * h)
extern

Return the IMG fileformat based on ECAT7 file_type.

Parameters
hEcat7 main header
Returns
IMG._fileFormat code value

Definition at line 827 of file img_e7.c.

827 {
828 int fileFormat=IMG_UNKNOWN;
829 switch(h->file_type) {
830 case ECAT7_IMAGE8:
831 case ECAT7_IMAGE16:
832 fileFormat=IMG_E7_2D; break;
833 case ECAT7_VOLUME8:
834 case ECAT7_VOLUME16:
835 fileFormat=IMG_E7; break;
836 case ECAT7_2DSCAN:
837 fileFormat=IMG_E7_2D; break;
838 case ECAT7_3DSCAN:
839 case ECAT7_3DSCAN8:
840 case ECAT7_3DSCANFIT:
841 fileFormat=IMG_E7; break;
842 case ECAT7_POLARMAP:
843 fileFormat=IMG_POLARMAP; break;
844 default:
845 fileFormat=IMG_UNKNOWN; break;
846 }
847 return fileFormat;
848}
#define IMG_E7_2D

Referenced by imgReadEcat7Header().

◆ imgGetEcat7MHeader()

void imgGetEcat7MHeader ( IMG * img,
ECAT7_mainheader * h )
extern

Copy ECAT 7 main header information into IMG

Parameters
imgtarget structure
hsource structure

Definition at line 742 of file img_e7.c.

743{
744 img->scanner=h->system_type;
745 imgUnitFromEcat7(img, h);
749 img->axialFOV=10.0*h->distance_scanned;
750 img->transaxialFOV=10.0*h->transaxial_fov;
752 strlcpy(img->patientName, h->patient_name, 32);
753 strncpy(img->patientID, h->patient_id, 16);
754 img->sizez=10.0*h->plane_separation;
755 switch(h->file_type) {
756 case ECAT7_IMAGE8:
757 case ECAT7_IMAGE16:
758 case ECAT7_VOLUME8:
759 case ECAT7_VOLUME16: img->type=IMG_TYPE_IMAGE; break;
760 case ECAT7_POLARMAP: img->type=IMG_TYPE_POLARMAP; break;
761 default: img->type=IMG_TYPE_RAW;
762 }
765 strncpy(img->userProcessCode, h->user_process_code, 10);
766 img->userProcessCode[10]=(char)0;
767 /* If valid study number is found in user_process_code, then take it */
771}
void imgUnitFromEcat7(IMG *img, ECAT7_mainheader *h)
Definition imgunits.c:149
#define IMG_TYPE_POLARMAP

Referenced by imgReadEcat7(), and imgReadEcat7Header().

◆ imgGetMaxFrame()

int imgGetMaxFrame ( IMG * img,
IMG * mimg,
int verbose )
extern

Search the frame with maximum pixel value for each image pixel separately.

See also
imgGetPeak, imgGetMaxTime
Returns
Returns 0, if ok.
Parameters
imgImage to search for max frames; not modified
mimgPointer to empty IMG struct in which the nr of frame with max pixel value will be written; 0 is written if max value is <= 0; any old contents are deleted.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 454 of file imgminmax.c.

463 {
464 if(verbose>0) printf("imgGetMaxFrame()\n");
465
466 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
467 if(mimg==NULL) return(2);
468 if(mimg->status==IMG_STATUS_OCCUPIED) imgEmpty(mimg);
469
470 /* Allocate memory for one frame */
471 int ret;
472 if(verbose>1) printf("allocating memory for %dx%dx%d pixels\n", img->dimz, img->dimy, img->dimx);
473 ret=imgAllocate(mimg, img->dimz, img->dimy, img->dimx, 1); if(ret) return(ret);
474 /* set image header information */
475 imgCopyhdr(img, mimg);
476 mimg->start[0]=img->start[0]; mimg->end[0]=img->end[img->dimt-1];
477 mimg->mid[0]=(mimg->start[0]+mimg->end[0])/2.0;
478
479 /* Go through every pixel */
480 int ti, zi, xi, yi;
481 double mv; int mi;
482 for(zi=0; zi<img->dimz; zi++) {
483 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++) {
484 ti=mi=0; mv=img->m[zi][yi][xi][ti];
485 for(ti=1; ti<img->dimt; ti++) {
486 if(img->m[zi][yi][xi][ti]<mv) continue;
487 mi=ti; mv=img->m[zi][yi][xi][ti];
488 }
489 if(mv>1.0E-008) mimg->m[zi][yi][xi][0]=1.0+mi;
490 else mimg->m[zi][yi][xi][0]=0.0;
491 }
492 }
493
494 return(0);
495}

◆ imgGetMaxTime()

int imgGetMaxTime ( IMG * img,
IMG * mimg,
const int w,
int verbose )
extern

Search the time of maximum value for each image pixel separately.

See also
imgGetPeak, imgGetMaxFrame
Returns
Returns 0, if ok.
Parameters
imgImage to search for max frames; not modified.
mimgPointer to empty IMG struct in which the max time (sec) will be written; any old contents are deleted.
wJust save the frame middle time (0), or compute value weighted average time of all frames (1), or, value weighted average time of 3 or 5 subsequent frames (2). Option (1) uses the equation for mean residence time (MRT) for PTACs in pharmacokinetics.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 345 of file imgminmax.c.

358 {
359 if(verbose>0) printf("imgGetMaxTime(*img, *mimg, %d)\n", w);
360
361 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
362 if(mimg==NULL) return(2);
363 if(mimg->status==IMG_STATUS_OCCUPIED) imgEmpty(mimg);
364
365 /* Allocate memory for one frame */
366 int ret;
367 if(verbose>1) printf("allocating memory for %dx%dx%d pixels\n", img->dimz, img->dimy, img->dimx);
368 ret=imgAllocate(mimg, img->dimz, img->dimy, img->dimx, 1);
369 if(ret) return(ret);
370 /* set image header information */
371 imgCopyhdr(img, mimg);
372 mimg->start[0]=img->start[0]; mimg->end[0]=img->end[img->dimt-1];
373 mimg->mid[0]=(mimg->start[0]+mimg->end[0])/2.0;
374 mimg->unit=CUNIT_UNKNOWN;
375
376 if(w==0) {
377 for(int zi=0; zi<img->dimz; zi++) {
378 for(int yi=0; yi<img->dimy; yi++) {
379 for(int xi=0; xi<img->dimx; xi++) {
380 /* Find the frame with max value */
381 int ti=0, mi=0;
382 double mv=img->m[zi][yi][xi][ti];
383 for(ti=1; ti<img->dimt; ti++) {
384 if(img->m[zi][yi][xi][ti]<mv) continue;
385 mi=ti; mv=img->m[zi][yi][xi][ti];
386 }
387 if(mv>0.0) mimg->m[zi][yi][xi][0]=img->mid[mi];
388 else mimg->m[zi][yi][xi][0]=0.0;
389 }
390 }
391 }
392 return(0);
393 }
394
395 if(w==1) { // Same as the equation for mean residence time (MRT) for PTACs in pharmacokinetics
396 for(int zi=0; zi<img->dimz; zi++) {
397 for(int yi=0; yi<img->dimy; yi++) {
398 for(int xi=0; xi<img->dimx; xi++) {
399 /* Compute the value weighted time */
400 double sumw=0.0, sumt=0.0;
401 for(int ti=0; ti<img->dimt; ti++) {
402 if(isnan(img->m[zi][yi][xi][ti])) continue;
403 float fdur=img->end[ti]-img->start[ti]; if(fdur<=0.0) fdur=1.0;
404 sumt+=img->m[zi][yi][xi][ti]*img->mid[ti]*fdur;
405 sumw+=img->m[zi][yi][xi][ti]*fdur;
406 }
407 sumt/=sumw;
408 if(sumt>0.0 && sumw>0.0) mimg->m[zi][yi][xi][0]=sumt;
409 else mimg->m[zi][yi][xi][0]=0.0;
410 }
411 }
412 }
413 return(0);
414 }
415
416 if(w>1) {
417 for(int zi=0; zi<img->dimz; zi++) {
418 for(int yi=0; yi<img->dimy; yi++) {
419 for(int xi=0; xi<img->dimx; xi++) {
420 /* Find the frame with max value */
421 int ti=0, mi=0;
422 double mv=img->m[zi][yi][xi][ti];
423 for(ti=1; ti<img->dimt; ti++) {
424 if(img->m[zi][yi][xi][ti]<mv) continue;
425 mi=ti; mv=img->m[zi][yi][xi][ti];
426 }
427 /* calculate weighted mean from subsequent frames, if possible */
428 if(mi<1 || mi>img->dimt-2) continue;
429 int i1, i2; i1=mi-1; i2=mi+1; if(i1>0 && i2<img->dimt-1) {i1--; i2++;}
430 double sumw=0.0, sumt=0.0;
431 for(int i=i1; i<=i2; i++) {
432 if(!(img->m[zi][yi][xi][i]>0.0)) continue;
433 sumt+=img->m[zi][yi][xi][i]*img->mid[i];
434 sumw+=img->m[zi][yi][xi][i];
435 }
436 sumt/=sumw;
437 if(sumt>0.0) mimg->m[zi][yi][xi][0]=sumt;
438 else mimg->m[zi][yi][xi][0]=0.0;
439 }
440 }
441 }
442 return(0);
443 }
444
445 return(0);
446}

◆ imgGetMicropetFrameHeader()

int imgGetMicropetFrameHeader ( FILE * fp,
IMG * img,
int frame_index,
int verbose )
extern

Read frame information from MicroPET header into one-frame-IMG.

Returns
Returns 0 when successful, otherwise >0.
Parameters
fpFile pointer to Concorde/MicroPET header.
imgPointer to IMG struct, allocated for one frame; frame information is written in frame 0.
frame_indexFrame index [0..tdim-1].
verboseVerbose level.

Definition at line 457 of file img_upet.c.

466 {
467 char tmp[MAX_MICROPET_LINE_LEN];
468 float f;
469
470
471 if(verbose>0) printf("%s(*fp, *img, %d)\n", __func__, frame_index);
472 if(fp==NULL) return 1;
473 if(img==NULL) return 2;
474 if(frame_index<0) return 3;
475
476 /* Search required frame from the beginning of header file */
477 rewind(fp);
478
479 /* Find correct frame index */
480 sprintf(tmp, "frame %d", frame_index);
481 if(verbose>1) printf(" reading '%s'\n", tmp);
482 if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 5;
483
484 /* frame start time */
485 if(verbose>1) printf(" reading 'frame_start'\n");
486 if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 11;
487 f=-1.0; (void)sscanf(tmp, "%f", &f); if(f<0.0) return 11;
488 img->start[0]=f;
489
490 /* frame duration; can be 0 at least in single-frame image */
491 if(verbose>1) printf(" reading 'frame_duration'\n");
492 if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 12;
493 f=-1.0; (void)sscanf(tmp, "%f", &f); if(f<0.0) return 12;
494 img->end[0]=img->start[0]+f;
495 img->mid[0]=0.5*(img->end[0]+img->start[0]);
496
497 /* scale factor (written in 'weight' since there is no better place) */
498 if(verbose>1) printf(" reading 'scale_factor'\n");
499 if(upetHeaderReadParameter(fp, "scale_factor", tmp)!=0) return 13;
500 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
501 img->weight[0]=f;
502
503 /* decay correction */
504 if(verbose>1) printf(" reading 'decay_correction'\n");
505 if(upetHeaderReadParameter(fp, "decay_correction", tmp)!=0) return 14;
506 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
507 img->decayCorrFactor[0]=f;
508
509 return 0;
510}
int upetHeaderReadParameter(FILE *fp, char *parameter, char *value)
Definition micropet.c:16
#define MAX_MICROPET_LINE_LEN

Referenced by imgMicropetPETToEcat7().

◆ imgGetMicropetHeader()

int imgGetMicropetHeader ( IMG * img)
extern

Copy microPET header information from IFT structure to IMG structure.

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
imgPointer to initiated IMG struct

Definition at line 583 of file img_upet.c.

586 {
587 int i, n;
588 float f;
589 char key[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
590#pragma clang diagnostic push
591#pragma clang diagnostic ignored "-Wmissing-field-initializers"
592 struct tm scanstart={0};
593#pragma clang diagnostic pop
594
595 if(MICROPET_TEST) printf("\n%s(*img)\n", __func__);
596
597 /* Check the input */
598 if(img==NULL) return STATUS_FAULT;
600 return STATUS_FAULT;
601 imgSetStatus(img, STATUS_FAULT);
602 if(img->ift.keyNr<10) return STATUS_FAULT;
603
604 imgSetStatus(img, STATUS_INVALIDHEADER);
605
606 /* Check image format */
607 i=iftGetIntValue(&img->ift, 0, "file_type", &n, 0);
608 if(i<0) return STATUS_INVALIDHEADER;
609 if(n!=5) {imgSetStatus(img, STATUS_UNSUPPORTED); return STATUS_UNSUPPORTED;}
610
611 i=iftGetIntValue(&img->ift, 0, "acquisition_mode", &n, 0);
612 if(i<0) return STATUS_INVALIDHEADER;
613 if(n!=2 && n!=3) { // CT (9) not yet supported
614 imgSetStatus(img, STATUS_UNSUPPORTED); return STATUS_UNSUPPORTED;}
615
616 i=iftGetIntValue(&img->ift, 0, "data_type", &n, 0);
617 if(i<0) return STATUS_INVALIDHEADER;
618 if(n!=4 && n!=2) {
619 imgSetStatus(img, STATUS_UNSUPPORTED); return STATUS_UNSUPPORTED;}
620
621 /* scanner model */
622 i=iftGetIntValue(&img->ift, 0, "model", &img->scanner, 0);
623 if(i<0) return STATUS_INVALIDHEADER;
624 if(img->scanner<0) return STATUS_INVALIDHEADER;
625
626 /* image dimensions */
627 i=iftGetIntValue(&img->ift, 0, "total_frames", &n, 0);
628 if(i<0) return STATUS_INVALIDHEADER;
629 img->dimt=n; if(img->dimt<1) return STATUS_INVALIDHEADER;
630 i=iftGetIntValue(&img->ift, 0, "x_dimension", &n, 0);
631 if(i<0) return STATUS_INVALIDHEADER;
632 img->dimx=n; if(img->dimx<1) return STATUS_INVALIDHEADER;
633 i=iftGetIntValue(&img->ift, 0, "y_dimension", &n, 0);
634 if(i<0) return STATUS_INVALIDHEADER;
635 img->dimy=n; if(img->dimy<1) return STATUS_INVALIDHEADER;
636 i=iftGetIntValue(&img->ift, 0, "z_dimension", &n, 0);
637 if(i<0) return STATUS_INVALIDHEADER;
638 img->dimz=n; if(img->dimz<1) return STATUS_INVALIDHEADER;
639
640 /* zoom */
641 i=iftGetFloatValue(&img->ift, 0, "zoom", &img->zoom, 0);
642 if(i<0) return STATUS_INVALIDHEADER;
643 if(img->zoom<0.0) return STATUS_INVALIDHEADER;
644
645 /* pixel size x */
646 i=iftGetFloatValue(&img->ift, 0, "pixel_size_x", &img->sizex, 0);
647 if(i>=0) {
648 if(img->sizex<0.0) return STATUS_INVALIDHEADER;
649 } else {
650 i=iftGetFloatValue(&img->ift, 0, "pixel_size", &img->sizex, 0);
651 if(i<0 || img->sizex<0.0) return STATUS_INVALIDHEADER;
652 img->sizex*=10.0;
653 }
654
655 /* pixel size y */
656 i=iftGetFloatValue(&img->ift, 0, "pixel_size_y", &img->sizey, 0);
657 if(i>=0) {
658 if(img->sizey<0.0) return STATUS_INVALIDHEADER;
659 } else {
660 i=iftGetFloatValue(&img->ift, 0, "pixel_size", &img->sizey, 0);
661 if(i<0 || img->sizey<0.0) return STATUS_INVALIDHEADER;
662 img->sizey*=10.0;
663 }
664
665 /* pixel size z, replaced by transaxial_bin_size, if available */
666 /* transaxial_bin_size */
667 i=iftGetFloatValue(&img->ift, 0, "pixel_size_z", &img->sizez, 0);
668 if(i>=0) {
669 if(img->sizez<0.0) return STATUS_INVALIDHEADER;
670 } else {
671 i=iftGetFloatValue(&img->ift, 0, "axial_plane_size", &img->sizez, 0);
672 if(i<0 || img->sizez<0.0) return STATUS_INVALIDHEADER;
673 img->sizez*=10.0;
674 }
675 i=iftGetFloatValue(&img->ift, 0, "transaxial_bin_size", &f, 0);
676 if(i>=0 && f>0.0) img->sizez=10.0*f;
677
678 /* isotope halflife */
679 i=iftGetFloatValue(&img->ift, 0, "isotope_half_life", &img->isotopeHalflife, 0);
680 if(i<0 || img->isotopeHalflife<0.0) return STATUS_INVALIDHEADER;
681
682 /* branching_fraction */
683 i=iftGetFloatValue(&img->ift, 0, "isotope_branching_fraction", &img->branchingFraction, 0);
684 if(i<0 || img->branchingFraction<0.0) return STATUS_INVALIDHEADER;
685
686 /* decay correction applied */
687 i=iftGetIntValue(&img->ift, 0, "decay_correction_applied", &n, 0);
688 if(i<0 || n<0.0) return STATUS_INVALIDHEADER;
691
692 /* calibration units */
693 i=iftGetIntValue(&img->ift, 0, "calibration_units", &n, 0);
694 if(i<0 || n<0.0) return STATUS_INVALIDHEADER;
695 switch(n) {
696 case 1: img->unit=CUNIT_NCI_PER_ML; break;
697 case 2: img->unit=CUNIT_BQ_PER_ML; break;
698 case 3: img->unit=CUNIT_HU; break;
699 case 0:
700 default: img->unit=CUNIT_UNKNOWN; break;
701 }
702
703 /* calibration factor */
704 i=iftGetFloatValue(&img->ift, 0, "calibration_factor", &img->calibrationFactor, 0);
705 if(i<0 || img->calibrationFactor<0.0) return STATUS_INVALIDHEADER;
707
708 /* FOV */
709 i=iftGetFloatValue(&img->ift, 0, "radial_fov", &img->transaxialFOV, 0);
710 if(i<0) return STATUS_INVALIDHEADER;
711 img->transaxialFOV*=10.0;
712
713 /* General */
715 img->type=IMG_TYPE_IMAGE;
716
717 /* Studynumber, if possible */
718 strcpy(key, "study"); n=1;
719 if((i=iftGet(&img->ift, key, 0))>=0)
720 n=studynr_from_fname2(img->ift.item[i].value, img->studyNr, 0);
721 if(n!=0) {
722 strcpy(key, "file_name");
723 if((i=iftGet(&img->ift, key, 0))>=0)
724 n=studynr_from_fname2(img->ift.item[i].value, img->studyNr, 0);
725 }
726 if(n!=0 && MICROPET_TEST>1) printf("Valid studyNr could not be read.\n");
727
728 /* Scan start */
729 strcpy(key, "scan_time");
730 if((i=iftGet(&img->ift, key, 0))<0) return STATUS_INVALIDHEADER;
731 n=sscanf(img->ift.item[i].value, "%s %s %d %d:%d:%d %d",
732 tmp2, tmp3, &scanstart.tm_mday,
733 &scanstart.tm_hour, &scanstart.tm_min, &scanstart.tm_sec, &i);
734 if(n==7) {
735 scanstart.tm_year=i-1900;
736 if(strcasecmp(tmp3, "Jan")==0) scanstart.tm_mon=0;
737 else if(strcasecmp(tmp3, "Feb")==0) scanstart.tm_mon=1;
738 else if(strcasecmp(tmp3, "Mar")==0) scanstart.tm_mon=2;
739 else if(strcasecmp(tmp3, "Apr")==0) scanstart.tm_mon=3;
740 else if(strcasecmp(tmp3, "May")==0) scanstart.tm_mon=4;
741 else if(strcasecmp(tmp3, "Jun")==0) scanstart.tm_mon=5;
742 else if(strcasecmp(tmp3, "Jul")==0) scanstart.tm_mon=6;
743 else if(strcasecmp(tmp3, "Aug")==0) scanstart.tm_mon=7;
744 else if(strcasecmp(tmp3, "Sep")==0) scanstart.tm_mon=8;
745 else if(strcasecmp(tmp3, "Oct")==0) scanstart.tm_mon=9;
746 else if(strcasecmp(tmp3, "Nov")==0) scanstart.tm_mon=10;
747 else if(strcasecmp(tmp3, "Dec")==0) scanstart.tm_mon=11;
748 scanstart.tm_isdst=-1;
749 img->scanStart=timegm(&scanstart); //mktime(&scanstart);
750 if(img->scanStart<0) img->scanStart=0;
751 } else return STATUS_INVALIDHEADER;
752
753
754 imgSetStatus(img, STATUS_OK);
755 return STATUS_OK;
756}
int iftGetFloatValue(IFT *ift, int si, const char *key, float *value, int verbose)
Definition iftsrch.c:228
int iftGet(IFT *ift, char *key, int verbose)
Definition iftsrch.c:15
int iftGetIntValue(IFT *ift, int si, const char *key, int *value, int verbose)
Definition iftsrch.c:309
int MICROPET_TEST
Definition micropet.c:6
int studynr_from_fname2(char *fname, char *studynr, int force)
Definition studynr.c:67

Referenced by imgReadMicropetHeader().

◆ imgGetMicropetMainHeader()

int imgGetMicropetMainHeader ( FILE * fp,
IMG * img,
float * calibration_factor,
int verbose )
extern

Read main header information from MicroPET header into one-frame-IMG.

Returns
Returns 0 when successful and >0 in case of an error.
Parameters
fpMicroPET header file pointer.
imgPointer to allocated IMG structure.
calibration_factorCalibration factor / Branching fraction.
verboseVerbose level.

Definition at line 300 of file img_upet.c.

309 {
310 char tmp[MAX_MICROPET_LINE_LEN];
311 int n;
312 float f;
313
314
315 if(verbose>0) printf("%s(*fp, *img, *f)\n", __func__);
316 if(fp==NULL) return 1;
317 if(img==NULL) return 2;
318
319 /* scanner model */
320 rewind(fp);
321 if(verbose>1) printf(" reading 'model'\n");
322 if(upetHeaderReadParameter(fp, "model", tmp)!=0) return 11;
323 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 11;
324 img->scanner=n;
325
326 /* zoom */
327 rewind(fp);
328 if(verbose>1) printf(" reading 'zoom'\n");
329 if(upetHeaderReadParameter(fp, "zoom", tmp)!=0) return 11;
330 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 11;
331 img->zoom=f;
332
333 /* If 'pixel_size' is found, use it as initial value for pixel x, y, and z size */
334 rewind(fp);
335 if(verbose>1) printf(" reading 'pixel_size'\n");
336 if(upetHeaderReadParameter(fp, "pixel_size", tmp)==0) {
337 f=-1; (void)sscanf(tmp, "%f", &f);
338 if(f>0.0) {
339 if(verbose>2) printf(" pixel_size := %g cm\n", f);
340 img->sizex=img->sizey=img->sizez=10.0*f;
341 }
342 }
343
344 /* pixel size x */
345 rewind(fp);
346 if(verbose>1) printf(" reading 'pixel_size_x'\n");
347 if(upetHeaderReadParameter(fp, "pixel_size_x", tmp)==0) {
348 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 12;
349 if(verbose>2) printf(" pixel_size_x := %g\n", f);
350 img->sizex=f;
351 }
352
353 /* pixel size y */
354 rewind(fp);
355 if(verbose>1) printf(" reading 'pixel_size_y'\n");
356 if(upetHeaderReadParameter(fp, "pixel_size_y", tmp)==0) {
357 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
358 if(verbose>2) printf(" pixel_size_y := %g\n", f);
359 img->sizey=f;
360 }
361
362 /* pixel size z; note that transaxial_bin_size may be better in case of plane gaps */
363 rewind(fp);
364 if(verbose>1) printf(" reading 'pixel_size_z'\n");
365 if(upetHeaderReadParameter(fp, "pixel_size_z", tmp)==0) {
366 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
367 if(verbose>2) printf(" pixel_size_z := %g\n", f);
368 img->sizez=f;
369 } else {
370 if(verbose>0) printf(" cannot find 'pixel_size_z'\n");
371 rewind(fp);
372 if(verbose>1) printf(" reading 'axial_plane_size'\n");
373 if(upetHeaderReadParameter(fp, "axial_plane_size", tmp)!=0) {
374 if(verbose>0) printf(" cannot find 'axial_plane_size'\n");
375 img->sizez=0.0;
376 } else {
377 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
378 if(verbose>2) printf(" axial_pixel_size := %g cm\n", f);
379 img->sizez=10.*f;
380 }
381 }
382 /* transaxial_bin_size; in case of plane gaps this could be better than pixel_size_z */
383 rewind(fp);
384 if(verbose>1) printf(" reading 'transaxial_bin_size'\n");
385 if(upetHeaderReadParameter(fp, "transaxial_bin_size", tmp)==0) {
386 f=-1; (void)sscanf(tmp, "%f", &f);
387 if(verbose>2) printf(" transaxial_pixel_size := %g cm\n", f);
388 //if(f>0) img->sizez=10.0*f;
389 }
390
391 /* isotope halflife */
392 rewind(fp);
393 if(verbose>1) printf(" reading 'isotope_half_life'\n");
394 if(upetHeaderReadParameter(fp, "isotope_half_life", tmp)==0) {
395 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 15;
396 img->isotopeHalflife=f;
397 }
398
399 /* branching_fraction */
400 rewind(fp);
401 if(verbose>1) printf(" reading 'isotope_branching_fraction'\n");
402 if(upetHeaderReadParameter(fp, "isotope_branching_fraction", tmp)==0) {
403 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 16;
404 img->branchingFraction=f;
405 }
406
407 /* decay correction applied */
408 rewind(fp);
409 if(verbose>1) printf(" reading 'decay_correction_applied'\n");
410 if(upetHeaderReadParameter(fp, "decay_correction_applied", tmp)==0) {
411 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 17;
414 }
415
416 /* calibration units */
417 rewind(fp);
418 if(verbose>1) printf(" reading 'calibration_units'\n");
419 if(upetHeaderReadParameter(fp, "calibration_units", tmp)==0) {
420 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 18;
421 switch(n) {
422 case 1: img->unit=CUNIT_NCI_PER_ML; break;
423 case 2: img->unit=CUNIT_BQ_PER_ML; break;
424 case 3: img->unit=CUNIT_HU; break;
425 case 0:
426 default: img->unit=CUNIT_UNKNOWN; break;
427 }
428 }
429
430 /* calibration factor */
431 rewind(fp);
432 if(verbose>1) printf(" reading 'calibration_factor'\n");
433 if(calibration_factor!=NULL &&
434 upetHeaderReadParameter(fp, "calibration_factor", tmp)==0)
435 {
436 f=-1; (void)sscanf(tmp, "%f", &f); if(f<=0.0) return 19;
437 *calibration_factor=f;
438 if(img->branchingFraction>0.0) *calibration_factor/=img->branchingFraction;
439 }
440
441 /* FOV */
442 rewind(fp);
443 if(verbose>1) printf(" reading 'radial_fov'\n");
444 if(upetHeaderReadParameter(fp, "radial_fov", tmp)==0) {
445 f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 20;
446 img->transaxialFOV=10.0*f;
447 }
448
449 return 0;
450}

Referenced by imgMicropetCTToEcat7(), and imgMicropetPETToEcat7().

◆ imgGetMicropetSIF()

int imgGetMicropetSIF ( FILE * fp,
SIF * sif )
extern

Read Scan Information from Concorde/MicroPET header file.

Returns
Returns 0 if successful.
Parameters
fpFile pointer to Concorde/MicroPET header file.
sifPointer to initiated but non-allocated SIF struct; Studynr should be filled afterwards.

Definition at line 517 of file img_upet.c.

522 {
523 char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
524 int n, i, ret;
525
526
527 if(fp==NULL) return 1;
528 if(sif==NULL) return 2;
529
530
531 /* Get frame number */
532 rewind(fp);
533 if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
534 n=-1; (void)sscanf(tmp, "%d", &n); if(n<1) return 11;
535
536 /* Allocate memory for SIF */
537 ret=sifSetmem(sif, n); if(ret!=0) return 4;
538 sif->frameNr=n;
539 sif->colNr=4;
540 sif->version=1;
541
542 /* Scan time */
543 upetScanStart(fp, &sif->scantime);
544
545 /* Isotope */
546 rewind(fp);
547 if(upetHeaderReadParameter(fp, "isotope", tmp)!=0) return 13;
548 strlcpy(sif->isotope_name, tmp, 8);
549
550 /* Frames */
551 for(i=0; i<sif->frameNr; i++) {
552 /* Find correct frame index */
553 sprintf(tmp, "frame %d", i);
554 if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 21;
555 /* frame start time */
556 if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 22;
557 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 22;
558 sif->x1[i]=n;
559 /* frame duration */
560 if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 23;
561 n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 23;
562 sif->x2[i]=sif->x1[i]+n;
563 /* prompts */
564 if(upetHeaderReadParameter(fp, "prompts", tmp)!=0) return 24;
565 n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 24;
566 sif->prompts[i]=n;
567 /* delays */
568 if(upetHeaderReadParameter(fp, "delays", tmp)!=0) return 25;
569 n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 25;
570 sif->randoms[i]=n;
571 /* trues */
572 sif->trues[i]=sif->prompts[i]-sif->randoms[i];
573 }
574 return 0;
575}
int upetScanStart(FILE *fp, time_t *scant)
Definition micropet.c:194

◆ imgGetNiftiHeader()

int imgGetNiftiHeader ( IMG * img,
NIFTI_DSR * dsr,
int verbose )
extern

Copy Nifti header information into IMG.

Returns
Returns IMG status, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
See also
imgSetNiftiHeader, imgReadNiftiHeader
Parameters
imgPointer to IMG struct
dsrPointer to Nifti header contents
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 218 of file img_nii.c.

225 {
226 if(verbose>0) {printf("imgGetNiftiHeader()\n"); fflush(stdout);}
227
228 /* Check the input */
229 if(img==NULL) return STATUS_FAULT;
231 return STATUS_FAULT;
232 imgSetStatus(img, STATUS_FAULT);
233 if(dsr==NULL) return STATUS_FAULT;
234
235 imgSetStatus(img, STATUS_INVALIDHEADER);
236
237 /* Get the image dimensions from header */
238 int dimNr=dsr->h.dim[0];
239 if(dimNr<2 || dimNr>4) {
240 if(verbose>0)
241 fprintf(stderr, "Error: Nifti image dimension %d is not supported\n", dimNr);
242 return STATUS_UNSUPPORTED;
243 }
244 int dimx, dimy, dimz=1, dimt=1;
245 dimx=dsr->h.dim[1]; dimy=dsr->h.dim[2];
246 if(dimNr>2) {dimz=dsr->h.dim[3]; if(dimNr>3) dimt=dsr->h.dim[4];}
247 long long pxlNr=dimx*dimy*dimz;
248 if(pxlNr<1) {
249 if(verbose>0) fprintf(stderr, "Error: invalid Nifti image dimensions.\n");
250 return STATUS_INVALIDHEADER;
251 }
252 img->dimx=dimx; img->dimy=dimy; img->dimz=dimz; img->dimt=dimt;
253
254 /* Copy information from header */
255 img->type=IMG_TYPE_IMAGE;
256 strcpy(img->studyNr, "");
257 strcpy(img->patientName, "");
258 /* NIfTI file format */
259 if(strcmp(dsr->h.magic, "ni1")==0) img->_fileFormat=IMG_NIFTI_1D;
260 else if(strcmp(dsr->h.magic, "n+1")==0) img->_fileFormat=IMG_NIFTI_1S;
261 else {
262 if(verbose>0) fprintf(stderr, "Error: invalid Nifti magic number.\n");
263 return STATUS_INVALIDHEADER;
264 }
265 /* NIfTI datatype is not needed, because currently saved as floats anyway */
266 //img->_dataType=dsr->h.datatype;
267 /* Pixel x,y,z sizes, converting units if necessary */
268 float f=1.0;
269 if(dsr->h.xyzt_units & NIFTI_UNITS_METER) f=1000.;
270 else if(dsr->h.xyzt_units & NIFTI_UNITS_MICRON) f=0.001;
271 else if(dsr->h.xyzt_units & NIFTI_UNITS_MM) f=1.0;
272 if(verbose>2) printf("pixel size conversion factor := %g\n", f);
273 for(int i=1; i<=3; i++) {
274 if(i==1) img->sizex=f*dsr->h.pixdim[i];
275 else if(i==2) img->sizey=f*dsr->h.pixdim[i];
276 else if(i==3) img->sizez=f*dsr->h.pixdim[i];
277 }
278 /* Orientation, quaternion, and transformation parameters */
279 img->xform[0]=dsr->h.qform_code;
280 img->xform[1]=dsr->h.sform_code;
281 img->quatern[0]=dsr->h.quatern_b;
282 img->quatern[1]=dsr->h.quatern_c;
283 img->quatern[2]=dsr->h.quatern_d;
284 img->quatern[3]=dsr->h.qoffset_x;
285 img->quatern[4]=dsr->h.qoffset_y;
286 img->quatern[5]=dsr->h.qoffset_z;
287 for(int i=0; i<4; i++) img->quatern[6+i]=dsr->h.srow_x[i];
288 for(int i=0; i<4; i++) img->quatern[10+i]=dsr->h.srow_y[i];
289 for(int i=0; i<4; i++) img->quatern[14+i]=dsr->h.srow_z[i];
290
291 /* Assumptions */
293
294 imgSetStatus(img, STATUS_OK);
295 return STATUS_OK;
296}
#define NIFTI_UNITS_METER
#define NIFTI_UNITS_MICRON
#define IMG_NIFTI_1D
#define NIFTI_UNITS_MM
short int qform_code
short int sform_code
short int dim[8]
NIFTI_1_HEADER h

Referenced by imgFormatDetermine(), imgReadNiftiHeader(), and imgWriteNiftiFrame().

◆ imgGetPeak()

int imgGetPeak ( IMG * img,
float beforeTime,
IMG_PIXEL * p,
int verbose )
extern

Searches the max pixel value in the IMG data, which occurs before specified time.

See also
imgGetMaxTime, imgGetMaxFrame
Returns
Returns 0 if successful.
Parameters
imgPointer to IMG struct
beforeTimeTime (sec) after which max value is not searched
pPointer to struct where max pixel position is written
verboseVerbose level; 0 if nothing is to be printed in stdout

Definition at line 294 of file imgminmax.c.

303 {
304 int zi, yi, xi, fi, mf;
305 float f;
306
307 if(verbose>0) printf("imgGetPeak(img, %g, p, %d)\n", beforeTime, verbose);
308 if(img->status<IMG_STATUS_OCCUPIED) return(1);
309 if(p==NULL) return(2);
310 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(3);
311 if(beforeTime<img->mid[0]) {
312 if(verbose>0) fprintf(stderr, "Error: invalid max search time setting.\n");
313 return(4);
314 }
315 f=nanf(""); mf=img->dimt; p->x=p->y=p->z=p->f=1;
316 for(zi=0; zi<img->dimz; zi++) {
317 for(yi=0; yi<img->dimy; yi++) {
318 for(xi=0; xi<img->dimx; xi++) {
319 for(fi=0; fi<img->dimt; fi++) if(img->mid[fi]<=beforeTime) {
320 if(!isfinite(img->m[zi][yi][xi][fi])) continue;
321 if(isfinite(f) && img->m[zi][yi][xi][fi]<f) // lower
322 continue;
323 if(isfinite(f) && img->m[zi][yi][xi][fi]==f) { // equal
324 // only use this if earlier than in prev max
325 if(fi>=mf) continue;
326 }
327 f=img->m[zi][yi][xi][fi];
328 p->x=xi+1; p->y=yi+1; p->z=zi+1; p->f=fi+1;
329 mf=fi;
330 }
331 }
332 }
333 }
334 if(!isfinite(f)) return(5);
335 if(verbose>2) printf("maxval := %g\n", f);
336 return(0);
337}

◆ imgInfo()

void imgInfo ( IMG * image)
extern

Prints img information to stdout; mainly for testing purposes.

Parameters
imagePointer to IMG data.

Definition at line 359 of file img.c.

362 {
363 char buf[64];
364
365 if(IMG_TEST) printf("imgInfo()\n");
366 if(image==NULL) {
367 fprintf(stdout, "image := NULL\n"); return;
368 } else if(image->status<=IMG_STATUS_UNINITIALIZED) {
369 fprintf(stdout, "image_status := not initialized\n"); return;
370 } else if(image->status==IMG_STATUS_INITIALIZED) {
371 fprintf(stdout, "image_status := initialized but empty\n"); /* return; */
372 } else if(image->status==IMG_STATUS_ERROR) {
373 fprintf(stdout, "image_status := error\n");
374 }
375 fprintf(stdout, "image_error_status := %s\n", image->statmsg);
376 fprintf(stdout, "image_type := %d\n", image->type);
377 fprintf(stdout, "saved_data_type := %d\n", image->_dataType);
378 fprintf(stdout, "file_format := %d\n", image->_fileFormat);
379 fprintf(stdout, "scanner := %d\n", image->scanner);
380 fprintf(stdout, "modality := %d\n", image->modality);
381
382 fprintf(stdout, "qform := %d\n", image->xform[0]);
383 fprintf(stdout, "sform := %d\n", image->xform[1]);
384 fprintf(stdout, "quatern_b := %g\n", image->quatern[0]);
385 fprintf(stdout, "quatern_c := %g\n", image->quatern[1]);
386 fprintf(stdout, "quatern_d := %g\n", image->quatern[2]);
387 fprintf(stdout, "quatern_x_shift := %g\n", image->quatern[3]);
388 fprintf(stdout, "quatern_y_shift := %g\n", image->quatern[4]);
389 fprintf(stdout, "quatern_z_shift := %g\n", image->quatern[5]);
390 for(int i=0; i<4; i++)
391 fprintf(stdout, "srow_x[%d] := %g\n", 1+i, image->quatern[6+i]);
392 for(int i=0; i<4; i++)
393 fprintf(stdout, "srow_y[%d] := %g\n", 1+i, image->quatern[10+i]);
394 for(int i=0; i<4; i++)
395 fprintf(stdout, "srow_z[%d] := %g\n", 1+i, image->quatern[14+i]);
396 for(int i=0; i<12; i++)
397 fprintf(stdout, "matrix_transformation[%d] := %g\n", 1+i, image->mt[i]);
398
399 fprintf(stdout, "ift.keyNr := %d\n", image->ift.keyNr);
400 fprintf(stdout, "identification_code := %.*s\n",
401 MAX_STUDYNR_LEN, image->studyNr);
402 fprintf(stdout, "data_unit := %s\n", imgUnit((int)image->unit));
403 fprintf(stdout, "image_zoom := %g\n", image->zoom);
404 fprintf(stdout, "radiopharmaceutical := %.32s\n", image->radiopharmaceutical);
405 fprintf(stdout, "isotope_halflife := %e [sec]\n", image->isotopeHalflife);
406 fprintf(stdout, "branching_fraction := %f\n", image->branchingFraction);
407 fprintf(stdout, "calibration_factor := %e\n", image->calibrationFactor);
408 if(!ctime_r_int(&image->scanStart, buf)) strcpy(buf, "1900-01-01 00:00:00");
409 fprintf(stdout, "scan_start_time := %s\n", buf);
410 fprintf(stdout, "patient_name := %s\n", image->patientName);
411 fprintf(stdout, "patient_id := %s\n", image->patientID);
412 fprintf(stdout, "patient_orientation := %d\n", image->orientation);
413 fprintf(stdout, "FOV_axial := %g [mm]\n", image->axialFOV);
414 fprintf(stdout, "FOV_transaxial := %g [mm]\n", image->transaxialFOV);
415 fprintf(stdout, "sample_distance := %g [mm]\n", image->sampleDistance);
416 fprintf(stdout, "pixel_size_x := %g [mm]\n", image->sizex);
417 fprintf(stdout, "pixel_size_y := %g [mm]\n", image->sizey);
418 fprintf(stdout, "pixel_size_z := %g [mm]\n", image->sizez);
419 fprintf(stdout, "dimension_x := %d\n", image->dimx);
420 fprintf(stdout, "dimension_y := %d\n", image->dimy);
421 fprintf(stdout, "dimension_z := %d\n", image->dimz);
422 fprintf(stdout, "dimension_t := %d\n", image->dimt);
423 /* Polar map */
424 fprintf(stdout, "polarmap_num_rings := %d\n", image->polarmap_num_rings);
425 if(image->polarmap_num_rings>0) {
426 fprintf(stdout, "polarmap_sectors_per_ring :=");
427 for(int i=0; i<image->polarmap_num_rings; i++)
428 fprintf(stdout, " %d", image->polarmap_sectors_per_ring[i]);
429 fprintf(stdout, "\n");
430 fprintf(stdout, "polarmap_ring_position :=");
431 for(int i=0; i<image->polarmap_num_rings; i++)
432 fprintf(stdout, " %g", image->polarmap_ring_position[i]);
433 fprintf(stdout, "\n");
434 fprintf(stdout, "polarmap_ring_angle :=");
435 for(int i=0; i<image->polarmap_num_rings; i++)
436 fprintf(stdout, " %d", image->polarmap_ring_angle[i]);
437 fprintf(stdout, "\n");
438 fprintf(stdout, "polarmap_start_angle := %d\n", image->polarmap_start_angle);
439 }
440 /* Check if the rest is available */
441 if(image->status==IMG_STATUS_INITIALIZED) return;
442
443 fprintf(stdout, "actual_plane_numbers := %d", image->planeNumber[0]);
444 for(int i=1; i<image->dimz; i++) fprintf(stdout, " %d", image->planeNumber[i]);
445 fprintf(stdout, "\n");
446 fprintf(stdout, "Frame times (sec):\n");
447 for(int i=0; i<image->dimt; i++) fprintf(stdout, " %e %e %e\n",
448 image->start[i], image->end[i], image->mid[i]);
449 if(image->isWeight) fprintf(stdout, "Frames are weighted.\n");
450 else fprintf(stdout, "Frames are not weighted.\n");
452 fprintf(stdout, "Decay correction factors for each frame:\n");
453 for(int i=0; i<image->dimt; i++)
454 fprintf(stdout, "%03i %e\n", i+1, image->decayCorrFactor[i]);
455 } else
456 fprintf(stdout, "Image is not decay corrected.\n");
457 return;
458}
char * imgUnit(int dunit)
Definition imgunits.c:315
#define IMG_STATUS_ERROR
const char * statmsg

Referenced by ecat63AddImg(), img_k1_using_ki(), img_logan(), img_patlak(), imgAnalyzeToEcat(), imgNiftiToEcat(), imgReadAnalyzeFirstFrame(), imgReadEcat63FirstFrame(), imgReadEcat7FirstFrame(), imgReadFrame(), imgReadMicropetFirstFrame(), imgReadNifti(), and imgReadNiftiFirstFrame().

◆ imgInit()

void imgInit ( IMG * image)
extern

Call this once before any use of IMG data.

See also
imgAllocate, imgEmpty
Parameters
imagePointer to IMG struct.

Definition at line 60 of file img.c.

63 {
64 if(IMG_TEST) printf("imgInit()\n");
65 if(image==NULL) return;
66 memset(image, 0, sizeof(IMG));
67 /*if(image->status!=IMG_STATUS_UNINITIALIZED) return;*/
69 imgSetStatus(image, STATUS_OK);
70 image->type=0;
71 image->unit=0;
72 image->calibrationFactor=0.0;
73 image->zoom=0.0;
74 image->radiopharmaceutical[0]=(char)0;
75 image->isotopeHalflife=0.0;
77 image->branchingFraction=0.0;
78 image->unit=0;
79 image->scanStart=0;
80 image->orientation=0;
81 image->axialFOV=image->transaxialFOV=image->sampleDistance=0.0;
82 image->studyNr[0]=image->patientName[0]=(char)0;
83 image->sizex=image->sizey=image->sizez=0;
84 image->_dataType=0;
85 image->_fileFormat=0;
86 image->scanner=0;
87 image->modality=0;
88 for(int i=0; i<2; i++) image->xform[i]=NIFTI_XFORM_UNKNOWN;
89 for(int i=0; i<18; i++) image->quatern[i]=0.0;
90 for(int i=0; i<12; i++) image->mt[i]=0.0;
91 iftInit(&image->ift);
92 image->polarmap_num_rings=0;
93 for(int i=0; i<MAX_POLARMAP_NUM_RINGS; i++) {
94 image->polarmap_sectors_per_ring[i]=0;
95 image->polarmap_ring_position[i]=0.0;
96 image->polarmap_ring_angle[i]=0;
97 }
98 image->polarmap_start_angle=0;
99 image->dimt=image->dimx=image->dimy=image->dimz=0;
100 image->gapx=image->gapy=image->gapz=0.0;
101 image->resolutionx=image->resolutiony=image->resolutionz=0.0;
102 image->m=(float****)NULL;
103 image->_header=(float*)NULL;
104 image->pixel=(float*)NULL;
105 image->column=(float**)NULL;
106 image->row=(float***)NULL;
107 image->plane=(float****)NULL;
108 image->planeNumber=(int*)NULL;
109 image->start=image->end=image->mid=(float*)NULL;
110 image->isWeight=0;
111 image->weight=image->sd=image->prompts=image->randoms=(float*)NULL;
112 image->decayCorrFactor=(float*)NULL;
113 image->errstatus=STATUS_OK;
114}

Referenced by imgAnalyzeToEcat(), imgFlipAbove(), imgFlipRight(), imgFormatDetermine(), imgMaskDilate(), imgMaskErode(), imgMicropetCTToEcat7(), imgMicropetPETToEcat7(), imgNiftiToEcat(), imgOutlierFilter(), imgPVCRRL(), imgPVCRVC(), imgReadFrame(), imgReadMinMax(), imgReadModelingData(), imgsegmSimilar(), imgThresholding(), imgThresholdingLowHigh(), imgWriteAnalyzeFrame(), imgWriteEcat63Frame(), imgWriteEcat7Frame(), and imgWriteNiftiFrame().

◆ imgIsotope()

char * imgIsotope ( IMG * img)
extern

Returns pointer to string describing the isotope in image data

Parameters
imgimage structure
Returns
pointer to string
See also
imgDecayCorrection

Definition at line 76 of file imgdecayc.c.

76 {
78}
char * hlIsotopeCode(int isotope)
Definition halflife.c:36

Referenced by ecat63AddImg(), ecat63WriteAllImg(), img2sif(), imgSetEcat63MHeader(), imgSetEcat7MHeader(), and sifAllocateWithIMG().

◆ imgMatch()

int imgMatch ( IMG * img1,
IMG * img2,
float accuracy )
extern

Checks if two IMG data contents are similar (header information, frame times, data dimensions, matrix contents inside specified accuracy).

Returns
Returns 0 if match was found, and >0 if not.
See also
imgMatchMatrix, imgMatchHeader, imgMaxDifference, imgConvertUnit
Parameters
img1Pointer to the first IMG data.
img2Pointer to the second IMG data to be compared against the first one.
accuracyPixel values must satisfy condition abs(x1-x2)/abs(mean(x1,x2)) <= accuracy (for example 0.01). If you want exact match, set accuracy=0.0.

Definition at line 15 of file imgcomp.c.

24 {
25 int ret=0;
26
27 if(img1==NULL || img2==NULL) return(1);
28 ret=imgMatchHeader(img1, img2); if(ret!=0) return(100+ret);
29 ret=imgMatchFrames(img1, img2); if(ret!=0) return(200+ret);
30 ret=imgMatchPlanes(img1, img2); if(ret!=0) return(300+ret);
31 ret=imgMatchMatrix(img1, img2, (double)accuracy); if(ret!=0) return(400+ret);
32 ret=imgMatchTransform(img1, img2); if(ret!=0) return(500+ret);
33 return(0);
34}
int imgMatchPlanes(IMG *img1, IMG *img2)
Definition imgcomp.c:307
int imgMatchMatrix(IMG *img1, IMG *img2, double accuracy)
Definition imgcomp.c:47
int imgMatchHeader(IMG *img1, IMG *img2)
Definition imgcomp.c:128
int imgMatchTransform(IMG *img1, IMG *img2)
Definition imgcomp.c:85
int imgMatchFrames(IMG *img1, IMG *img2)
Definition imgcomp.c:286

◆ imgMatchFrames()

int imgMatchFrames ( IMG * img1,
IMG * img2 )
extern

Checks if the frame times of two IMG data do match:

Returns
Returns 0 if match was found, and >0 if they do not match.
See also
imgMatchPlanes
Parameters
img1Pointer to the first IMG structure.
img2Pointer to the second IMG structure.

Definition at line 286 of file imgcomp.c.

291 {
292 if(img1->dimt!=img2->dimt) return(1);
293 for(int fi=0; fi<img1->dimt; fi++) {
294 if(fabs(img1->start[fi]-img2->start[fi])>0.001) return(11);
295 if(fabs(img1->end[fi]-img2->end[fi])>0.001) return(12);
296 if(fabs(img1->mid[fi]-img2->mid[fi])>0.001) return(13);
297 }
298 return(0);
299}

Referenced by imgMatch().

◆ imgMatchHeader()

int imgMatchHeader ( IMG * img1,
IMG * img2 )
extern

Checks if two image headers match.

Returns
Returns 0 if headers match, 1 if headers do not match.
See also
imgMatchPlanes, imgMatchFrames, imgMatchTransform
Parameters
img1Pointer to the first IMG structure.
img2Pointer to the second IMG structure.

Definition at line 128 of file imgcomp.c.

133 {
134
135 if(img1->unit!=img2->unit){
136 fprintf(stderr, "In the header: Mismatching unit.\n");
137 return 1;
138 }
139
140 // Not always preserved in read&write, therefore tested if present in both
141 if(img1->calibrationFactor>0.0 && img2->calibrationFactor>0.0 &&
143 {
144 fprintf(stderr, "In the header: Mismatching calibration factor.\n");
145 return 1;
146 }
147
148 if(img1->zoom!=img2->zoom){
149 fprintf(stderr, "In the header: Mismatching zoom.\n");
150 return 1;
151 }
152 if(strcasecmp(img1->radiopharmaceutical,img2->radiopharmaceutical)){
153 fprintf(stderr, "In the header: Mismatching radiopharmaceutical.\n");
154 return 1;
155 }
156 if(img1->isotopeHalflife!=img2->isotopeHalflife){
157 fprintf(stderr, "In the header: Mismatching isotope halflife.\n");
158 return 1;
159 }
160 if(img1->decayCorrection!=img2->decayCorrection){
161 fprintf(stderr, "In the header: One of the images is not corrected for decay.\n");
162 return 1;
163 }
164 if(img1->branchingFraction!=img2->branchingFraction){
165 fprintf(stderr, "In the header: Mismatching branching ratio.\n");
166 return 1;
167 }
168 if(img1->scanStart!=img2->scanStart){
169 fprintf(stderr, "In the header: Mismatching scan start times.\n");
170 fprintf(stderr, "difftime := %g s\n", difftime(img1->scanStart, img2->scanStart));
171 return 1;
172 }
173 if(img1->orientation!=img2->orientation){
174 fprintf(stderr, "In the header: Mismatching orientation.\n");
175 return 1;
176 }
177 if(img1->axialFOV!=img2->axialFOV){
178 fprintf(stderr, "In the header: Mismatching axial FOV.\n");
179 return 1;
180 }
181 if(img1->transaxialFOV!=img2->transaxialFOV){
182 fprintf(stderr, "In the header: Mismatching transaxial FOV.\n");
183 return 1;
184 }
185 if(img1->sampleDistance!=img2->sampleDistance){
186 fprintf(stderr, "In the header: Mismatching sample distance.\n");
187 return 1;
188 }
189
190 if(strcasecmp(img1->studyNr,img2->studyNr)){
191 fprintf(stderr, "In the header: Mismatching study number.\n");
192 return 1;
193 }
194 if(strcmp(img1->userProcessCode,img2->userProcessCode)){
195 fprintf(stderr, "In the header: Mismatching user process code.\n");
196 return 1;
197 }
198 if(strcmp(img1->studyDescription,img2->studyDescription)){
199 fprintf(stderr, "In the header: Mismatching study description.\n");
200 return 1;
201 }
202 if(strcasecmp(img1->patientName,img2->patientName)){
203 fprintf(stderr, "In the header: Mismatching patient name.\n");
204 return 1;
205 }
206 if(strcasecmp(img1->patientID,img2->patientID)){
207 fprintf(stderr, "In the header: Mismatching patient ID.\n");
208 return 1;
209 }
210
211 if(img1->type!=IMG_TYPE_UNKNOWN && img2->type!=IMG_TYPE_UNKNOWN &&
212 img1->type!=img2->type)
213 {
214 fprintf(stderr, "In the header: Mismatching image type.\n");
215 return 1;
216 }
217
218 if(img1->sizex!=img2->sizex){
219 fprintf(stderr, "In the header: Mismatching size (x-axis).\n");
220 return 1;
221 }
222 if(img1->sizey!=img2->sizey){
223 fprintf(stderr, "In the header: Mismatching size (y-axis).\n");
224 return 1;
225 }
226 if(img1->sizez!=img2->sizez){
227 fprintf(stderr, "In the header: Mismatching size (z-axis).\n");
228 return 1;
229 }
230 if(img1->gapx!=img2->gapx){
231 fprintf(stderr, "In the header: Mismatching x gap.\n");
232 return 1;
233 }
234 if(img1->gapy!=img2->gapy){
235 fprintf(stderr, "In the header: Mismatching y gap.\n");
236 return 1;
237 }
238 if(img1->gapz!=img2->gapz){
239 fprintf(stderr, "In the header: Mismatching z gap.\n");
240 return 1;
241 }
242
243 if(img1->resolutionx!=img2->resolutionx){
244 fprintf(stderr, "In the header: Mismatching resolution (x-axis).\n");
245 return 1;
246 }
247 if(img1->resolutiony!=img2->resolutiony){
248 fprintf(stderr, "In the header: Mismatching resolution (y-axis).\n");
249 return 1;
250 }
251 if(img1->resolutionz!=img2->resolutionz){
252 fprintf(stderr, "In the header: Mismatching resolution (z-axis).\n");
253 return 1;
254 }
255
256 if(img1->scanner!=img2->scanner){
257 fprintf(stderr, "In the header: Mismatching scanner.\n");
258 return 1;
259 }
260 if(img1->modality!=img2->modality){
261 fprintf(stderr, "In the header: Mismatching modality.\n");
262 return 1;
263 }
264 if(img1->_dataType!=img2->_dataType){
265 fprintf(stderr, "In the header: Mismatching data type.\n");
266 return 1;
267 }
268 if(img1->_fileFormat!=img2->_fileFormat){
269 fprintf(stderr, "In the header: Mismatching file format.\n");
270 return 1;
271 }
272 if(img1->isWeight!=img2->isWeight){
273 fprintf(stderr, "In the header: Mismatching in weights.\n");
274 return 1;
275 }
276
277 return 0;
278}

Referenced by imgMatch().

◆ imgMatchMatrix()

int imgMatchMatrix ( IMG * img1,
IMG * img2,
double accuracy )
extern

Checks if two image matrices match in the accuracy of argument "accuracy".

For example, set accuracy=0.99 and you will get match if all matrix values satisfy abs(x1-x2)/abs(mean(x1,x2))<=0.01). If you want exact match, set accuracy=0.0.

Returns
Returns 0 if matrices match, 1 if matrices do not match.
See also
imgMatch, imgMatchHeader, imgMaxDifference, imgSS
Parameters
img1Pointer to the first IMG structure.
img2Pointer to the second IMG structure.
accuracyRequired accuracy

Definition at line 47 of file imgcomp.c.

54 {
55
56 int xi, yi, pi, fi;
57 double s;
58
59 for(pi=0; pi<img1->dimz; pi++) for(yi=0; yi<img1->dimy; yi++)
60 for(xi=0; xi<img1->dimx; xi++) for(fi=0; fi<img1->dimt; fi++) {
61 s=fabs(img1->m[pi][yi][xi][fi]+img2->m[pi][yi][xi][fi])/2.0;
62 if(accuracy==0.0 || s==0.0) {
63 if(img1->m[pi][yi][xi][fi]!=img2->m[pi][yi][xi][fi]){
64 fprintf(stderr, "Mismatch in image matrix.\n");
65 return(1);
66 }
67 } else {
68 if(fabs(img1->m[pi][yi][xi][fi]-img2->m[pi][yi][xi][fi])/s > (1.0-accuracy)) {
69 fprintf(stderr, "Mismatch in image matrix.\n");
70 printf("img[%d][%d][%d][%d]: %g vs %g\n", pi, yi, xi, fi,
71 img1->m[pi][yi][xi][fi], img2->m[pi][yi][xi][fi]);
72 return(1);
73 }
74 }
75 }
76 return 0;
77}

Referenced by imgMatch().

◆ imgMatchMatrixSize()

int imgMatchMatrixSize ( IMG * d1,
IMG * d2 )
extern

Check whether two IMG data have the same matrix (x,y,z) size.

Returns
0 in case of match, 1 otherwise.
See also
imgMatch, imgMatchFrames
Author
Vesa Oikonen
Parameters
d1Pointer to IMG structure.
d2Pointer to IMG structure.

Definition at line 447 of file imgcomp.c.

452 {
453 if(d1==NULL || d2==NULL) return(1);
454 if(d1->dimz!=d2->dimz) return(1);
455 if(d1->dimy!=d2->dimy) return(1);
456 if(d1->dimx!=d2->dimx) return(1);
457 return(0);
458}

◆ imgMatchPlanes()

int imgMatchPlanes ( IMG * img1,
IMG * img2 )
extern

Checks if the planes of two IMG data do match: number of planes and plane numbers.

Returns
Returns 0 if match was found, and >0 if no match.
See also
imgMatchFrames
Parameters
img1Pointer to the first IMG structure.
img2Pointer to the second IMG structure.

Definition at line 307 of file imgcomp.c.

312 {
313 if(img1->dimz!=img2->dimz) return(1);
314 for(int zi=0; zi<img1->dimz; zi++) {
315 if(img1->planeNumber[zi]!=img2->planeNumber[zi]) return(11);
316 }
317 return(0);
318}

Referenced by imgMatch().

◆ imgMatchTransform()

int imgMatchTransform ( IMG * img1,
IMG * img2 )
extern

Checks if the transform parameters of two image headers match.

Returns
Returns 0 if headers match, 1 if headers do not match.
See also
imgMatchHeader
Parameters
img1Pointer to the first IMG structure.
img2Pointer to the second IMG structure.

Definition at line 85 of file imgcomp.c.

90 {
91 int i;
92 float f;
93
94 if(img1->xform[0]!=img2->xform[0]) {
95 fprintf(stderr, "In the header: Mismatching qform.\n");
96 return 1;
97 }
98 if(img1->xform[1]!=img2->xform[1]) {
99 fprintf(stderr, "In the header: Mismatching sform.\n");
100 return 1;
101 }
102
103 for(i=0; i<18; i++) {
104 f=img1->quatern[i]-img2->quatern[i];
105 if(fabs(f)>1.0E-05) {
106 fprintf(stderr, "In the header: Mismatching transformation parameter.\n");
107 return 1;
108 }
109 }
110
111 for(i=0; i<12; i++) {
112 f=img1->mt[i]-img2->mt[i];
113 if(fabs(f)>1.0E-05) {
114 fprintf(stderr, "In the header: Mismatching matrix transformation.\n");
115 return 1;
116 }
117 }
118
119 return 0;
120}

Referenced by imgMatch().

◆ imgMax()

int imgMax ( IMG * img,
float * maxvalue )
extern

Search the max pixel value in the IMG data.

See also
imgFrameMinMax, imgMinMax, imgSmoothMax, imgAvg
Returns
0 if ok, 1 invalid image status, 2 invalid output pointer, 3 invalid image dimensions.
Parameters
imgPointer to IMG structure.
maxvaluePointer to output.

Definition at line 15 of file imgminmax.c.

20 {
21 if(img->status<IMG_STATUS_OCCUPIED) return(1);
22 if(maxvalue==NULL) return(2); else *maxvalue=0.0;
23 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(3);
24 float f=nanf("");
25 for(int pi=0; pi<img->dimz; pi++)
26 for(int yi=0; yi<img->dimy; yi++)
27 for(int xi=0; xi<img->dimx; xi++)
28 for(int fi=0; fi<img->dimt; fi++) {
29 if(!isfinite(f) || img->m[pi][yi][xi][fi]>f) f=img->m[pi][yi][xi][fi];
30 }
31 *maxvalue=f;
32 return(0);
33}

Referenced by imgThresholding(), and imgThresholdingLowHigh().

◆ imgMaxDifference()

int imgMaxDifference ( IMG * img1,
IMG * img2,
VOXEL_4D * absdiff,
float * abs_max,
VOXEL_4D * reldiff,
float * rel_max )
extern

Calculates the maximal pixel value differences (absolute and relational) between two image matrices.

Returns
Returns 0 if successful, and some difference was found, -1 if no difference at all was found, and >0 in case of an error.
See also
imgSS, imgMatch, imgMatchMatrix, imgMatchHeader, imgMRT
Parameters
img1Pointer to the first IMG structure.
img2Pointer to the second IMG, with the same dimensions as img1.
absdiffVoxel where absolute difference was found largest; enter NULL if not needed; returns [0,0,0,0] if no difference was found.
abs_maxPointer where max absolute difference is written; NULL if not needed.
reldiffVoxel where relational difference was found largest; enter NULL if not needed; returns [0,0,0,0] if no difference was found.
rel_maxPointer where max relational difference is written; NULL if not needed.

Definition at line 328 of file imgcomp.c.

343 {
344
345 int xi, yi, zi, ti;
346 float s, v, absmax=0.0, relmax=0.0;
347
348 /* Initiate result voxels */
349 if(absdiff!=NULL) absdiff->x=absdiff->y=absdiff->z=absdiff->t=0;
350 if(abs_max!=NULL) *abs_max=0;
351 if(reldiff!=NULL) reldiff->x=reldiff->y=reldiff->z=reldiff->t=0;
352 if(rel_max!=NULL) *rel_max=0;
353
354 /* Check input */
355 if(img1==NULL || img2==NULL) return 1;
356 if(img1->dimx!=img2->dimx) return 2;
357 if(img1->dimy!=img2->dimy) return 3;
358 if(img1->dimz!=img2->dimz) return 4;
359 if(img1->dimt!=img2->dimt) return 5;
360
361
362 /* Search for max absolute difference */
363 for(zi=0; zi<img1->dimz; zi++) for(yi=0; yi<img1->dimy; yi++)
364 for(xi=0; xi<img1->dimx; xi++) for(ti=0; ti<img1->dimt; ti++) {
365 s=fabs(img1->m[zi][yi][xi][ti]-img2->m[zi][yi][xi][ti]);
366 if(s>absmax) {
367 absmax=s;
368 if(absdiff!=NULL) {absdiff->x=xi+1; absdiff->y=yi+1; absdiff->z=zi+1; absdiff->t=ti+1;}
369 }
370 }
371 //printf("absmax := %g\n", absmax);
372 if(abs_max!=NULL) *abs_max=absmax;
373
374
375 /* Search for max relational difference.
376 If relational difference is Inf (image average is zero), then relmax
377 is set to FLT_MAX, and from those pixels the one where
378 absolute difference is highest is searched */
379 float local_absmax=0.0;
380 for(zi=0; zi<img1->dimz; zi++) for(yi=0; yi<img1->dimy; yi++)
381 for(xi=0; xi<img1->dimx; xi++) for(ti=0; ti<img1->dimt; ti++) {
382 s=fabs(img1->m[zi][yi][xi][ti]-img2->m[zi][yi][xi][ti]);
383 v=0.5*fabs(img1->m[zi][yi][xi][ti]+img2->m[zi][yi][xi][ti]);
384 if(v>0.0) {
385 s/=v;
386 if(s>relmax && local_absmax==0.0) {
387 relmax=s;
388 if(reldiff!=NULL) {reldiff->x=xi+1; reldiff->y=yi+1; reldiff->z=zi+1; reldiff->t=ti+1;}
389 }
390 } else if(s>0.0) { // if relational max is find out the pixel where
391 if(s>local_absmax) {
392 local_absmax=s;
393 if(reldiff!=NULL) {reldiff->x=xi+1; reldiff->y=yi+1; reldiff->z=zi+1; reldiff->t=ti+1;}
394 }
395 }
396 }
397 if(local_absmax>0.0) relmax=FLT_MAX;
398 //printf("relmax := %g\n", relmax);
399 if(rel_max!=NULL) *rel_max=relmax;
400
401 /* Was there any difference? 0=yes, -1=no */
402 if(absmax>0.0 || relmax>0.0) return 0; else return -1;
403}

◆ imgMicropetCTToEcat7()

int imgMicropetCTToEcat7 ( FILE * fph,
FILE * fpi,
char * ecatfile,
int verbose )
extern

Read MicroPET CT image and write ECAT 7 image volume.

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fphMicroPET header file pointer
fpiMicroPET image datafile pointer
ecatfileECAT image file name
verboseVerbose level

Definition at line 196 of file img_upet.c.

205 {
206 IMG img;
207 int n, zi, xi, yi, zdim, xdim, ydim, ret;
208 float scale_factor;
209 char *mdata, *mptr;
210 char tmp[MAX_MICROPET_LINE_LEN];
211 short int *si;
212
213
214 if(verbose>1) printf("%s(*fph, *fpi, %s, %d)\n", __func__, ecatfile, verbose);
215 /* Check input */
216 if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
217
218 /*
219 * Read image dimensions from header
220 */
221 ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, NULL);
222 if(ret) {return(STATUS_INVALIDHEADER);}
223 if(verbose>2) {
224 printf("z_dim := %d\n", zdim);
225 printf("x_dim := %d\n", xdim);
226 printf("y_dim := %d\n", ydim);
227 }
228
229 /* Read scale factor */
230 rewind(fph);
231 if(upetHeaderReadParameter(fph, "scale_factor", tmp)!=0) {
232 return(STATUS_INVALIDHEADER);}
233 scale_factor=-1; (void)sscanf(tmp, "%f", &scale_factor);
234 if(scale_factor<=0) return(STATUS_INVALIDHEADER);
235 if(verbose>2) {
236 printf("scale_factor := %g\n", scale_factor);
237 }
238
239 /* Remove existing ECAT file */
240 if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
241 return(STATUS_CANNOTERASE);
242 }
243
244 /*
245 * Read and write image
246 */
247 imgInit(&img);
248 /* Allocate memory for one frame */
249 ret=imgAllocate(&img, zdim, ydim, xdim, 1);
250 if(ret) {return(STATUS_NOMEMORY);}
251 /* Fill header with what we now can */
252 ret=imgGetMicropetMainHeader(fph, &img, NULL, verbose-2);
253 if(ret) {
254 if(verbose>1) printf("ret := %d\n", ret);
255 imgEmpty(&img); return(STATUS_INVALIDHEADER);
256 }
259 studynr_from_fname(ecatfile, img.studyNr);
260 upetScanStart(fph, &img.scanStart);
261 /* Allocate memory for the binary data */
262 long long pxlNr=xdim*ydim;
263 mdata=(char*)malloc(pxlNr*sizeof(short int)); if(mdata==NULL) {
264 imgEmpty(&img); return(STATUS_NOMEMORY);
265 }
266 /* Read image data, plane-by-plane */
267 for(zi=0; zi<zdim; zi++) {
268 mptr=mdata;
269 if((n=fread(mptr, 2, pxlNr, fpi)) < pxlNr) {
270 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
271 free(mdata); imgEmpty(&img);
272 return(STATUS_NOMATRIX);
273 }
274 /* Copy short ints to IMG */
275 mptr=mdata;
276 for(yi=0; yi<ydim; yi++)
277 for(xi=0; xi<xdim; xi++) {
278 si=(short int*)mptr;
279 img.m[zi][yi][xi][0]=(float)*si*scale_factor;
280 mptr+=2;
281 }
282 if(verbose>3) printf(" plane %d\n", zi+1);
283 else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
284 }
285 free(mdata);
286 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
287 /* Save ECAT 7 image volume */
288 ret=imgWrite(ecatfile, &img);
289 if(ret!=0) {imgEmpty(&img); return(STATUS_CANNOTWRITE);}
290
291 imgEmpty(&img);
292 return STATUS_OK;
293}
int imgGetMicropetMainHeader(FILE *fp, IMG *img, float *calibration_factor, int verbose)
Definition img_upet.c:300
int imgWrite(const char *fname, IMG *img)
Definition imgfile.c:136
int upetGetImageDimensions(FILE *fp, int *z, int *x, int *y, int *f)
Definition micropet.c:154
int studynr_from_fname(char *fname, char *studynr)
Definition studynr.c:119

Referenced by imgMicropetToEcat7().

◆ imgMicropetPETToEcat7()

int imgMicropetPETToEcat7 ( FILE * fph,
FILE * fpi,
char * ecatfile,
int verbose )
extern

Read MicroPET static or dynamic PET image and write ECAT 7 image volume frame-by-frame.

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fphMicroPET header file pointer.
fpiMicroPET image datafile pointer.
ecatfileECAT image file name.
verboseVerbose level.

Definition at line 85 of file img_upet.c.

94 {
95 int n, zi, xi, yi, ti, ret;
96
97
98 if(verbose>1) printf("%s(*fph, *fpi, %s, %d)\n", __func__, ecatfile, verbose);
99 /* Check input */
100 if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
101
102 /* Remove existing ECAT file */
103 if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
104 return(STATUS_CANNOTERASE);
105 }
106
107 /*
108 * Read image dimensions from header
109 */
110 int zdim, xdim, ydim, tdim;
111 ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, &tdim);
112 if(ret) {return(STATUS_INVALIDHEADER);}
113 if(verbose>1) {
114 printf("z_dim := %d\n", zdim);
115 printf("x_dim := %d\n", xdim);
116 printf("y_dim := %d\n", ydim);
117 printf("t_dim := %d\n", tdim);
118 }
119
120 /*
121 * Read and write image frame-by-frame
122 */
123 IMG img; imgInit(&img);
124 /* Allocate memory for one frame */
125 ret=imgAllocate(&img, zdim, ydim, xdim, 1);
126 if(ret) {return(STATUS_NOMEMORY);}
127 /* Fill header with what we now can */
128 float calibration_factor;
129 ret=imgGetMicropetMainHeader(fph, &img, &calibration_factor, verbose-2);
130 if(ret) {
131 if(verbose>2) printf("ret := %d\n", ret);
132 imgEmpty(&img); return(STATUS_INVALIDHEADER);
133 }
134 if(verbose>1) printf("calibration_factor := %g\n", calibration_factor);
137 studynr_from_fname(ecatfile, img.studyNr);
138 upetScanStart(fph, &img.scanStart);
139 /* Allocate memory for the binary data */
140 long long int pxlnr=xdim*ydim*zdim;
141 char *mdata, *mptr;
142 mdata=(char*)malloc(pxlnr*sizeof(float)); if(mdata==NULL) {
143 imgEmpty(&img); return(STATUS_NOMEMORY);
144 }
145 /* Frame-by-frame */
146 float *fptr;
147 for(ti=0; ti<tdim; ti++) {
148 if(verbose>3) {printf("ti=%d\n", ti); fflush(stdout);}
149 /* Read frame information from MicroPET header into IMG */
150 ret=imgGetMicropetFrameHeader(fph, &img, ti, verbose-2);
151 if(ret) {
152 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
153 free(mdata); imgEmpty(&img);
154 return(STATUS_INVALIDHEADER);
155 }
156 /* Read floats */
157 mptr=mdata;
158 if((n=fread(mptr, 4, pxlnr, fpi)) < pxlnr) {
159 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
160 free(mdata); imgEmpty(&img);
161 return(STATUS_NOMATRIX);
162 }
163 /* Copy floats to IMG */
164 mptr=mdata;
165 for(zi=0; zi<zdim; zi++)
166 for(yi=0; yi<ydim; yi++)
167 for(xi=0; xi<xdim; xi++) {
168 fptr=(float*)mptr;
169 img.m[zi][yi][xi][0]=(*fptr)*img.weight[0]*calibration_factor;
170 mptr+=4;
171 }
172 /* Write frame */
173 ret=imgWriteFrame(ecatfile, ti+1, &img, 0); //printf("ret := %d\n", ret);
174 if(ret!=STATUS_OK) break;
175 if(verbose>1) {printf(" frame written.\n"); fflush(stdout);}
176 else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
177 };
178 free(mdata); imgEmpty(&img);
179 if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
180 if(verbose==0 && ret==STATUS_NOMATRIX) {
181 fprintf(stdout, " %d frame(s) processed.\n", ti);
182 }
183 if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
184 remove(ecatfile); return ret;
185 }
186
187 return STATUS_OK;
188}
int imgGetMicropetFrameHeader(FILE *fp, IMG *img, int frame_index, int verbose)
Definition img_upet.c:457
int imgWriteFrame(const char *fname, int frame_to_write, IMG *img, int frame_index)
Definition imgfile.c:392

Referenced by imgMicropetToEcat7().

◆ imgMicropetToEcat7()

int imgMicropetToEcat7 ( char * upetname,
char * ecatfile,
int verbose )
extern

Read MicroPET image and write ECAT 7 image volume frame-by-frame.

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
upetnameMicroPET image filename.
ecatfileECAT image filename.
verboseVerbose level

Definition at line 15 of file img_upet.c.

22 {
23 char upetheader[FILENAME_MAX], upetimage[FILENAME_MAX];
24 int n, ret;
25 int acquisition_mode, data_type;
26 char tmp[MAX_MICROPET_LINE_LEN];
27
28
29 if(verbose>1) printf("\n%s(%s, %s, %d)\n", __func__, upetname, ecatfile, verbose);
30 /* Check the arguments */
31 if(upetname==NULL || ecatfile==NULL) return STATUS_FAULT;
32 ret=upetExists(upetname, upetheader, upetimage, verbose-1);
33 if(ret!=2) return STATUS_NOFILE;
34
35 /*
36 * Open Micropet Header and binary data files
37 */
38 FILE *fph, *fpi;
39 if((fph=fopen(upetheader, "r"))==NULL) return(STATUS_NOHEADERFILE);
40 if((fpi=fopen(upetimage, "rb"))==NULL) {fclose(fph); return(STATUS_NOIMGDATA);}
41
42
43 /*
44 * Check that image format is (currently) supported
45 */
46 rewind(fph);
47 if(verbose>1) printf("checking that image format is supported\n");
48 n=-1; if(upetHeaderReadParameter(fph, "file_type", tmp)==0)
49 (void)sscanf(tmp, "%d", &n);
50 if(verbose>2) printf("file_type := %d\n", n);
51 if(n!=5) {fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
52 acquisition_mode=-1;
53 if(upetHeaderReadParameter(fph, "acquisition_mode", tmp)==0)
54 (void)sscanf(tmp, "%d", &acquisition_mode);
55 if(verbose>2) printf("acquisition_mode := %d\n", acquisition_mode);
56 if(acquisition_mode!=2 && acquisition_mode!=3 && acquisition_mode!=9) {
57 fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
58 data_type=-1;
59 if(upetHeaderReadParameter(fph, "data_type", tmp)==0)
60 (void)sscanf(tmp, "%d", &data_type);
61 if(verbose>2) printf("data_type := %d\n", data_type);
62 if(data_type!=4 && data_type!=2) {
63 fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
64
65 /*
66 * Convert PET or CT image
67 */
68 if(acquisition_mode==2 || acquisition_mode==3) {
69 ret=imgMicropetPETToEcat7(fph, fpi, ecatfile, verbose);
70 } else if(acquisition_mode==9) {
71 ret=imgMicropetCTToEcat7(fph, fpi, ecatfile, verbose);
72 } else {
73 ret=STATUS_UNSUPPORTED;
74 }
75 fclose(fph); fclose(fpi);
76 return ret;
77}
int imgMicropetPETToEcat7(FILE *fph, FILE *fpi, char *ecatfile, int verbose)
Definition img_upet.c:85
int imgMicropetCTToEcat7(FILE *fph, FILE *fpi, char *ecatfile, int verbose)
Definition img_upet.c:196

◆ imgMinMax()

int imgMinMax ( IMG * img,
float * minvalue,
float * maxvalue )
extern

Searches the min and max pixel value in the IMG data.

See also
imgFrameMinMax, imgRangeMinMax, imgReadMinMax
Returns
Returns 0 when successful.
Parameters
imgPointer to IMG struct from where min and pixels are searched.
minvaluePointer to min pixel value; Enter NULL if not needed.
maxvaluePointer to max pixel value; Enter NULL if not needed.

Definition at line 154 of file imgminmax.c.

161 {
162 return (imgRangeMinMax(img, NULL, NULL, maxvalue, NULL, minvalue));
163}
int imgRangeMinMax(IMG *img, IMG_RANGE *r, IMG_PIXEL *maxp, float *maxv, IMG_PIXEL *minp, float *minv)
Definition imgminmax.c:71

Referenced by imgPVCRRL(), imgPVCRVC(), imgReadMinMax(), imgSetAnalyzeHeader(), imgWriteAnalyze(), and imgWriteNifti().

◆ imgNaNs()

unsigned long long imgNaNs ( IMG * img,
int fix )
extern

Searches the image data for missing pixel values, optionally setting those to zero.

See also
imgExistentTimes
Returns
the number of missing pixel values.
Parameters
imgPointer to IMG structure.
fixSet (1) or do not set (0) missing pixels to zero.

Definition at line 658 of file img.c.

663 {
664 if(img==NULL) return(0);
665 unsigned long long n=0;
666 for(int zi=0; zi<img->dimz; zi++) {
667 for(int yi=0; yi<img->dimy; yi++) {
668 for(int xi=0; xi<img->dimx; xi++) {
669 for(int ti=0; ti<img->dimt; ti++) {
670 if(!isfinite(img->m[zi][yi][xi][ti])) {
671 n++;
672 if(fix!=0) img->m[zi][yi][xi][ti]=0.0;
673 }
674 }
675 }
676 }
677 }
678 return(n);
679}

◆ imgRangeMinMax()

int imgRangeMinMax ( IMG * img,
IMG_RANGE * r,
IMG_PIXEL * maxp,
float * maxv,
IMG_PIXEL * minp,
float * minv )
extern

Finds max and/or min voxel inside specified image range.

See also
imgFrameMinMax, imgMinMax, imgAvg
Returns
0 if ok, 1 invalid volume status, 2 invalid range endings, 3 inconsistent range dimensions, 4 inconsistent dimensions
Parameters
imgPointer to IMG structure.
rPointer to image range inside IMG; enter NULL if whole IMG is used.
maxpPixel where max pixel position is written; NULL if not needed.
maxvTarget for max value; NULL if not needed.
minpPixel where min pixel position is written; NULL if not needed.
minvTarget for min value; NULL if not needed.

Definition at line 71 of file imgminmax.c.

84 {
85 int zi, yi, xi, fi;
86 float lmax, lmin;
87
88 if(img->status<IMG_STATUS_OCCUPIED) return(1);
89 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(1);
90
91 if(r!=NULL) {
92 if(r->z1<1 || r->y1<1 || r->x1<1 || r->f1<1) return(2);
93 if(r->z2<r->z1 || r->y2<r->y1 || r->x2<r->x1 || r->f2<r->f1) return(3);
94 if(r->z2>img->dimz || r->y2>img->dimy || r->x2>img->dimx || r->f2>img->dimt) return(4);
95
96 zi=r->z1-1; yi=r->y1-1; xi=r->x1-1; fi=r->f1-1;
97 lmax=lmin=nanf("");
98 if(maxp!=NULL) {maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1; maxp->f=fi+1;}
99 if(minp!=NULL) {minp->z=zi+1; minp->y=yi+1; minp->x=xi+1; minp->f=fi+1;}
100 for(zi=r->z1-1; zi<r->z2; zi++) {
101 for(yi=r->y1-1; yi<r->y2; yi++) {
102 for(xi=r->x1-1; xi<r->x2; xi++) {
103 for(fi=r->f1-1; fi<r->f2; fi++) {
104 if(!isfinite(lmax) || img->m[zi][yi][xi][fi]>lmax) {
105 lmax=img->m[zi][yi][xi][fi];
106 if(maxp!=NULL && isfinite(img->m[zi][yi][xi][fi])) {
107 maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1; maxp->f=fi+1;}
108 }
109 if(!isfinite(lmin) || img->m[zi][yi][xi][fi]<lmin) {
110 lmin=img->m[zi][yi][xi][fi];
111 if(minp!=NULL && isfinite(img->m[zi][yi][xi][fi])) {
112 minp->z=zi+1; minp->y=yi+1; minp->x=xi+1; minp->f=fi+1;}
113 }
114 }
115 }
116 }
117 }
118 } else {
119 zi=yi=xi=fi=0; lmax=lmin=nanf("");
120 if(maxp!=NULL) {maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1; maxp->f=fi+1;}
121 if(minp!=NULL) {minp->z=zi+1; minp->y=yi+1; minp->x=xi+1; minp->f=fi+1;}
122 for(zi=0; zi<img->dimz; zi++) {
123 for(yi=0; yi<img->dimy; yi++) {
124 for(xi=0; xi<img->dimx; xi++) {
125 for(fi=0; fi<img->dimt; fi++) {
126 if(!isfinite(lmax) || img->m[zi][yi][xi][fi]>lmax) {
127 lmax=img->m[zi][yi][xi][fi];
128 if(maxp!=NULL && isfinite(img->m[zi][yi][xi][fi])) {
129 maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1; maxp->f=fi+1;}
130 }
131 if(!isfinite(lmin) || img->m[zi][yi][xi][fi]<lmin) {
132 lmin=img->m[zi][yi][xi][fi];
133 if(minp!=NULL && isfinite(img->m[zi][yi][xi][fi])) {
134 minp->z=zi+1; minp->y=yi+1; minp->x=xi+1; minp->f=fi+1;}
135 }
136 }
137 }
138 }
139 }
140 }
141 if(maxv!=NULL) *maxv=lmax;
142 if(minv!=NULL) *minv=lmin;
143 if(!isfinite(lmax) && (maxp!=NULL || maxv!=NULL)) return(5);
144 if(!isfinite(lmin) && (minp!=NULL || minv!=NULL)) return(5);
145 return(0);
146}

Referenced by imgMinMax().

◆ imgRead()

int imgRead ( const char * fname,
IMG * img )
extern

Read an image or sinogram file in ECAT 6.3 or ECAT 7.x format, or image in NIfTI-1, Analyze 7.5, or microPET format.

See also
imgReadFrame, imgWrite
Returns
0 if ok, 1 invalid input, 2 image status is not 'initialized', 4 unrecognised format, 5 unsupported Ecat7 type, sets IMG->statmsg in case of error.
Parameters
fnameInput filename.
imgPointer to initialized IMG structure.
See also
imgInit, imgEmpty

Definition at line 26 of file imgfile.c.

33 {
34 FILE *fp;
35 int ret;
36 ECAT7_mainheader ecat7_main_header;
37 ECAT63_mainheader ecat63_main_header;
38 char temp[FILENAME_MAX];
39
40 if(IMG_TEST) {printf("imgRead(%s, *img)\n", fname); fflush(stdout);}
41 /* Check the arguments */
42 if(fname==NULL) {img->statmsg=imgStatus(STATUS_FAULT); return(1);}
43 if(img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
44 img->statmsg=imgStatus(STATUS_FAULT); return(2);}
45
46 /* Check if we have NIfTI file, which may be in single file format,
47 or dual file format which has similar names as microPET and Analyze */
48 if(niftiExists(fname, NULL, NULL, NULL, NULL, IMG_TEST-3, NULL)>0) {
49 /* Read NIfTI image */
50 ret=imgReadNifti(fname, img, IMG_TEST);
51 if(IMG_TEST) {printf("imgReadNifti() := %d\n", ret); fflush(stdout);}
52 if(ret==STATUS_OK) {
53 if(IMG_TEST) printf("%s identified as supported NIfTI.\n", fname);
54 img->statmsg=imgStatus(STATUS_OK);
55 return(STATUS_OK);
56 }
57 img->statmsg=imgStatus(ret); return(4);
58 }
59
60 /* Check if we have microPET or Analyze file, which consist of separate header
61 and data files, and have similar names */
62 if(upetExists(fname, NULL, NULL, IMG_TEST-3)==2) {
63 /* Read microPET image */
64 ret=imgReadMicropet(fname, img); if(ret!=STATUS_OK) return(3);
65 if(IMG_TEST) printf("%s identified as microPET format.\n", fname);
66 return(0);
67 }
68 if(anaExistsNew(fname, temp, NULL, NULL)!=0) {
70 /* Read Analyze image */
71 ret=imgReadAnalyze(temp, img);
72 if(IMG_TEST) {printf("imgReadAnalyze() := %d\n", ret); fflush(stdout);}
73 if(ret==STATUS_OK) {
74 if(IMG_TEST) printf("%s identified as supported Analyze 7.5 format.\n", fname);
75 img->statmsg=imgStatus(STATUS_OK);
76 return(0);
77 }
78 if(ret==STATUS_NOSIFDATA || ret==STATUS_WRONGSIFDATA) {
79 img->statmsg=imgStatus(ret); return(0);}
80 img->statmsg=imgStatus(ret); return(4);
81 }
82
83 /* Check if we have an ECAT file */
84 /* Open file for read */
85 if((fp=fopen(fname, "rb")) == NULL) {
86 img->statmsg=imgStatus(STATUS_NOFILE); return(4);
87 }
88 /* Try to read ECAT 7.x main header */
89 ret=ecat7ReadMainheader(fp, &ecat7_main_header);
90 if(ret) {fclose(fp); img->statmsg=imgStatus(STATUS_UNKNOWNFORMAT); return(4);}
91 /* If header could be read, check for magic number */
92 if(strncmp(ecat7_main_header.magic_number, ECAT7V_MAGICNR, 7)==0) {
93 /* This is ECAT 7.x file */
94 /* Check if file type is supported */
95 if(imgEcat7Supported(&ecat7_main_header)==0) {
96 fclose(fp); img->statmsg=imgStatus(STATUS_UNSUPPORTED); return(5);
97 }
98 fclose(fp);
99 /* Read file */
100 if(IMG_TEST) printf("%s identified as supported ECAT 7.x %s format\n",
101 fname, ecat7filetype(ecat7_main_header.file_type));
102 ret=imgReadEcat7(fname, img);
103 if(ret) {if(IMG_TEST) printf("imgReadEcat7()=%d\n", ret); return(6);}
104 } else {
105 /* Check if file is in ECAT 6.3 format */
106 ret=ecat63ReadMainheader(fp, &ecat63_main_header);
107 fclose(fp);
108 if(ret==0) {
109 /* It seems to be ECAT 6.3, so read it */
110 if(IMG_TEST) printf("%s identified as supported ECAT 6.3 %s format\n",
111 fname, ecat7filetype(ecat63_main_header.file_type));
112 ret=ecat63ReadAllToImg(fname, img);
113 if(ret) {
114 if(IMG_TEST) fprintf(stderr, "ecat63ReaddAllToImg: %s\n", ecat63errmsg);
115 if(ret==6) img->statmsg=imgStatus(STATUS_MISSINGMATRIX);
116 else img->statmsg=imgStatus(STATUS_UNSUPPORTED);
117 return(6);
118 }
119 } else {img->statmsg=imgStatus(STATUS_UNKNOWNFORMAT); return(4);}
120 }
121 img->statmsg=imgStatus(STATUS_OK);
122 return(0);
123}
int anaExistsNew(const char *filename, char *hdrfile, char *imgfile, char *siffile)
Definition analyze.c:45
char * imgStatus(int status_index)
Definition img.c:330
int imgReadAnalyze(const char *dbname, IMG *img)
Definition img_ana.c:24
int ecat63ReadAllToImg(const char *fname, IMG *img)
Definition img_e63.c:22
int imgEcat7Supported(ECAT7_mainheader *h)
Definition img_e7.c:1036
int imgReadEcat7(const char *fname, IMG *img)
Definition img_e7.c:19
int imgReadNifti(const char *filename, IMG *img, int verbose)
Definition img_nii.c:23
int imgReadMicropet(const char *fname, IMG *img)
Definition img_upet.c:971

Referenced by imgReadModelingData().

◆ imgReadAnalyze()

int imgReadAnalyze ( const char * dbname,
IMG * img )
extern

Read Analyze 7.5 image.

Analyze database name must be given with path. Image and header files with .img and .hdr extensions must exist. Also SIF file with .sif extension is used, if it exists. anaFlipping() determines whether image is flipped in z-direction; image is always flipped in x,y-directions.

Parameters
dbnameAnalyze database name with path, with or without extension
imgPointer to initialized IMG structure
Returns
0 if ok, and otherwise IMG status code; sets IMG->statmsg in case of error.

Definition at line 24 of file img_ana.c.

24 {
25 FILE *fp;
26 int ret;
27 float *fdata=NULL, *fptr;
28 ANALYZE_DSR dsr;
29 char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
30 int dimNr, dimx, dimy, dimz=1, dimt=1;
31 SIF sif;
32
33
34 if(IMG_TEST) printf("imgReadAnalyze(%s, *img)\n", dbname);
35
36 /* Check the arguments */
37 imgSetStatus(img, STATUS_OK);
38 if(img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
39 imgSetStatus(img, STATUS_FAULT); return(2);}
40 if(dbname==NULL || !dbname[0]) {imgSetStatus(img, STATUS_FAULT); return(1);}
41
42 /* Make the image and header filenames */
43 ret=anaExistsNew(dbname, hdrfile, datfile, siffile);
44 if(ret==0) {imgSetStatus(img, STATUS_NOHEADERFILE); return(3);}
45 if(ret==1 && IMG_TEST>0) printf("no SIF found for %s\n", dbname);
46
47 /* Read Analyze header file */
48 ret=anaReadHeader(hdrfile, &dsr);
49 if(ret) {
50 if(ret==1) imgSetStatus(img, STATUS_FAULT);
51 else if(ret==2) imgSetStatus(img, STATUS_NOHEADERFILE);
52 else imgSetStatus(img, STATUS_UNSUPPORTED);
53 return(3);
54 }
55 if(IMG_TEST) anaPrintHeader(&dsr, stdout);
56
57 /* Open image datafile */
58 if(IMG_TEST) fprintf(stdout, "reading image data %s\n", datfile);
59 if((fp=fopen(datfile, "rb")) == NULL) {
60 imgSetStatus(img, STATUS_NOIMGDATA); return(5);}
61
62 /* Prepare IMG for Analyze image */
63 /* Get the image dimensions from header */
64 dimNr=dsr.dime.dim[0];
65 if(dimNr<2) {fclose(fp); imgSetStatus(img, STATUS_INVALIDHEADER); return(4);}
66 dimx=dsr.dime.dim[1]; dimy=dsr.dime.dim[2];
67 if(dimNr>2) {dimz=dsr.dime.dim[3]; if(dimNr>3) dimt=dsr.dime.dim[4];}
68 long long pxlNr=dimx*dimy*dimz;
69 if(pxlNr<1) {fclose(fp); imgSetStatus(img, STATUS_INVALIDHEADER); return(4);}
70 /* Allocate memory for IMG */
71 ret=imgAllocate(img, dimz, dimy, dimx, dimt);
72 if(ret) {fclose(fp); imgSetStatus(img, STATUS_NOMEMORY); return(11);}
73 /* Copy information from Analyze header */
76 if(strcmp(img->studyNr, ".")==0) strcpy(img->studyNr, "");
77 strcpy(img->patientName, dsr.hist.patient_id);
78 img->sizex=dsr.dime.pixdim[1];
79 img->sizey=dsr.dime.pixdim[2];
80 img->sizez=dsr.dime.pixdim[3];
81 img->xform[0]=NIFTI_XFORM_UNKNOWN; // qform
82 img->xform[1]=NIFTI_XFORM_SCANNER_ANAT; // sform
83 /*if(dsr.dime.funused2>1.E-5) img->zoom=dsr.dime.funused2;*/
84 if(dsr.dime.funused3>1.E-5) img->isotopeHalflife=dsr.dime.funused3;
85 for(int pi=0; pi<dimz; pi++) img->planeNumber[pi]=pi+1;
86 if(dsr.little) img->_fileFormat=IMG_ANA_L; else img->_fileFormat=IMG_ANA;
87 /* Decay correction */
88 if(strstr(dsr.hist.descrip, "Decay corrected.")!=NULL)
90 else if(strstr(dsr.hist.descrip, "No decay correction.")!=NULL)
92 else
93 img->decayCorrection=IMG_DC_CORRECTED; // just assumed so
94
95 /* Allocate memory for one image frame */
96 fdata=malloc(pxlNr*sizeof(float));
97 if(fdata==NULL) {fclose(fp); imgSetStatus(img, STATUS_NOMEMORY); return(12);}
98
99 /* Read one image frame at a time */
100 for(int fi=0; fi<dimt; fi++) {
101 fptr=fdata;
102 ret=anaReadImagedata(fp, &dsr, fi+1, fptr);
103 if(ret) {
104 free(fdata); fclose(fp); imgSetStatus(img, STATUS_NOIMGDATA); return(7);}
105 /* Copy pixel values to IMG */
106 fptr=fdata;
107 if(anaFlipping()==0) { /* no flipping in z-direction */
108 for(int pi=0; pi<img->dimz; pi++)
109 for(int yi=dimy-1; yi>=0; yi--)
110 for(int xi=dimx-1; xi>=0; xi--)
111 img->m[pi][yi][xi][fi]=*fptr++;
112 } else {
113 for(int pi=dimz-1; pi>=0; pi--)
114 for(int yi=dimy-1; yi>=0; yi--)
115 for(int xi=dimx-1; xi>=0; xi--)
116 img->m[pi][yi][xi][fi]=*fptr++;
117 }
118 } /* next frame */
119 free(fdata);
120 fclose(fp);
121
122 /* Try to read frame time information from SIF file */
123 /* Check if SIF file is found */
124 if(siffile[0]) {
125 if(IMG_TEST) printf("reading SIF file %s\n", siffile);
126 if(access(siffile, 0) == -1) {
127 if(IMG_TEST) printf(" No SIF file; therefore unknown frame times.\n");
128 return(0);
129 }
130 }
131 /* If found, then read it */
132 sifInit(&sif); ret=sifRead(siffile, &sif);
133 if(ret) {imgSetStatus(img, STATUS_NOSIFDATA); return(21);}
134
135 /* Copy SIF contents */
136 ret=sif2img(&sif, img, 1, 1, 1, IMG_TEST-2);
137 sifEmpty(&sif);
138 if(ret!=0) {imgSetStatus(img, STATUS_WRONGSIFDATA); return(22);}
139
140 return(0);
141}
int anaFlipping()
Definition analyze.c:635
int anaPrintHeader(ANALYZE_DSR *h, FILE *fp)
Definition analyze.c:380
int anaReadImagedata(FILE *fp, ANALYZE_DSR *h, int frame, float *data)
Definition analyze.c:454
int sif2img(SIF *sif, IMG *img, int copy_header, int copy_frames, int copy_counts, int verbose)
Definition img_sif.c:13
void sifInit(SIF *data)
Definition sif.c:17
void sifEmpty(SIF *data)
Definition sif.c:33
int sifRead(char *filename, SIF *data)
Definition sifio.c:21

Referenced by imgRead().

◆ imgReadAnalyzeFirstFrame()

int imgReadAnalyzeFirstFrame ( const char * fname,
IMG * img )
extern

Read the first frame from an Analyze 7.5 database into IMG data structure.

Parameters
fnameName of Analyze database from which IMG contents will be read
imgpointer to the initiated but not preallocated IMG data
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 592 of file img_ana.c.

592 {
593 int ret=0;
594
595 if(IMG_TEST) printf("\nimgReadAnalyzeFirstFrame(%s, *img)\n", fname);
596 /* Check the input */
597 if(img==NULL) return STATUS_FAULT;
598 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
599 imgSetStatus(img, STATUS_FAULT);
600 if(fname==NULL) return STATUS_FAULT;
601
602 /* Read header information from file */
603 ret=imgReadAnalyzeHeader(fname, img); if(ret) return(ret);
604 if(IMG_TEST>3) imgInfo(img);
605
606 /* Allocate memory for one frame */
607 img->dimt=1;
608 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
609 if(ret) return STATUS_NOMEMORY;
610
611 /* Read the first frame */
612 ret=imgReadAnalyzeFrame(fname, 1, img, 0); if(ret) return(ret);
613
614 /* All went well */
615 imgSetStatus(img, STATUS_OK);
616 return STATUS_OK;
617}
int imgReadAnalyzeFrame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition img_ana.c:639

Referenced by imgAnalyzeToEcat().

◆ imgReadAnalyzeFrame()

int imgReadAnalyzeFrame ( const char * fname,
int frame_to_read,
IMG * img,
int frame_index )
extern

Read a specified frame from an Analyze 7.5 database into preallocated IMG data structure.

Analyze database consists of two or three files in the same directory: fname.hdr, fname.img, and optionally fname.sif. IMG header is assumed to be filled correctly before calling this function, except for information concerning separate planes and this frame, which is filled here. If frame does not exist, then and only then STATUS_NOMATRIX is returned.

Parameters
fnamename of Analyze database from which IMG contents will be read
frame_to_readframe which will be read [1..frameNr]
imgpointer to the IMG data. Place for the frame must be preallocated
frame_indexIMG frame index [0..dimt-1] where data will be placed
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 639 of file img_ana.c.

641 {
642 FILE *fp;
643 int ret;
644 float *fdata=NULL, *fptr;
645 ANALYZE_DSR dsr;
646 char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
647 SIF sif;
648
649
650 if(IMG_TEST) printf("\nimgReadAnalyzeFrame(%s, %d, *img, %d)\n",
651 fname, frame_to_read, frame_index);
652
653 /* Check the input */
654 if(img==NULL) return STATUS_FAULT;
655 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
656 if(fname==NULL) return STATUS_FAULT;
657 if(frame_index<0 || frame_index>img->dimt-1) return STATUS_FAULT;
658 if(frame_to_read<1) return STATUS_FAULT;
659 imgSetStatus(img, STATUS_FAULT);
660
661 /* Determine the names of hdr, data and sif files */
662 ret=anaDatabaseExists(fname, hdrfile, datfile, siffile);
663 if(ret==0) return STATUS_NOFILE;
664
665 /* Read Analyze header file */
666 ret=anaReadHeader(hdrfile, &dsr);
667 if(ret!=0) {
668 if(ret==1) return STATUS_FAULT;
669 else if(ret==2) return STATUS_NOHEADERFILE;
670 else return STATUS_UNSUPPORTED;
671 return(STATUS_FAULT);
672 }
673
674 /* Open image datafile */
675 if(IMG_TEST>2) fprintf(stdout, "reading image data %s\n", datfile);
676 if((fp=fopen(datfile, "rb")) == NULL) return STATUS_NOIMGDATA;
677
678 /* Allocate memory for one image frame */
679 fdata=malloc((size_t)img->dimx*img->dimy*img->dimz*sizeof(float));
680 if(fdata==NULL) {fclose(fp); return STATUS_NOMEMORY;}
681
682 /* Read the required image frame */
683 fptr=fdata;
684 ret=anaReadImagedata(fp, &dsr, frame_to_read, fptr);
685 fclose(fp);
686 if(ret==3) {free(fdata); return STATUS_NOMATRIX;} /* no more frames */
687 if(ret!=0) {free(fdata); return STATUS_UNSUPPORTED;}
688
689 /* Copy pixel values to IMG */
690 fptr=fdata;
691 if(anaFlipping()==0) { /* no flipping in z-direction */
692 for(int pi=0; pi<img->dimz; pi++)
693 for(int yi=img->dimy-1; yi>=0; yi--)
694 for(int xi=img->dimx-1; xi>=0; xi--)
695 img->m[pi][yi][xi][frame_index]=*fptr++;
696 } else {
697 for(int pi=img->dimz-1; pi>=0; pi--)
698 for(int yi=img->dimy-1; yi>=0; yi--)
699 for(int xi=img->dimx-1; xi>=0; xi--)
700 img->m[pi][yi][xi][frame_index]=*fptr++;
701 }
702 free(fdata);
703
704 /* Set decay correction factor to zero */
705 img->decayCorrFactor[frame_index]=0.0;
706
707 imgSetStatus(img, STATUS_OK); /* If the rest is failed, no problem */
708
709 /*
710 * Try to read frame time information from SIF file
711 */
712 sifInit(&sif);
713 if(sifRead(siffile, &sif)!=0) return STATUS_OK;
714 /* Frame information */
715 if(sif.frameNr>=frame_to_read) {
716 img->start[frame_index]=sif.x1[frame_to_read-1];
717 img->end[frame_index]=sif.x2[frame_to_read-1];
718 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
719 img->prompts[frame_index]=sif.prompts[frame_to_read-1];
720 img->randoms[frame_index]=sif.randoms[frame_to_read-1];
721 }
722 sifEmpty(&sif);
723
724 return STATUS_OK;
725}

Referenced by imgAnalyzeToEcat(), imgReadAnalyzeFirstFrame(), and imgReadFrame().

◆ imgReadAnalyzeHeader()

int imgReadAnalyzeHeader ( const char * dbname,
IMG * img )
extern

Fill IMG struct header information from Analyze 7.5 database files.

SIF file is read if available. Information concerning separate frames or planes is not filled though.

Parameters
dbnamename of Analyze database, may contain filename extension
imgpointer to the initiated IMG data
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 360 of file img_ana.c.

360 {
361 char hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
362 ANALYZE_DSR ana_header;
363 SIF sif;
364 double f;
365 int ret;
366
367 if(IMG_TEST) printf("\nimgReadAnalyzeHeader(%s, *img)\n", dbname);
368
369 /* Check the input */
370 if(img==NULL) return STATUS_FAULT;
371 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
372 imgSetStatus(img, STATUS_FAULT);
373 if(dbname==NULL) return STATUS_FAULT;
374
375 /* Determine the names of hdr and sif files */
376 ret=anaDatabaseExists(dbname, hdrfile, NULL, siffile);
377 if(ret==0) return STATUS_NOFILE;
378
379 /* Read Analyze header file */
380 ret=anaReadHeader(hdrfile, &ana_header);
381 if(ret!=0) {
382 if(IMG_TEST>1) printf("anaReadHeader() return value := %d\n", ret);
383 if(ret==1) return STATUS_FAULT;
384 else if(ret==2) return STATUS_NOHEADERFILE;
385 else return STATUS_UNSUPPORTED;
386 return(STATUS_FAULT);
387 }
388 /* and set IMG contents */
389 ret=imgGetAnalyzeHeader(img, &ana_header);
390 if(ret!=0) {
391 imgSetStatus(img, ret);
392 return(ret);
393 }
394
395 /* If SIF does not exist, then that's it */
396 if(!siffile[0]) {
397 imgSetStatus(img, STATUS_OK);
398 return STATUS_OK;
399 }
400
401 /* SIF is available, so read that too */
402 sifInit(&sif); ret=0;
403 if(sifRead(siffile, &sif)!=0) return STATUS_OK;
404 /* Copy scan time */
405 img->scanStart=sif.scantime;
406 /* Study number, if not yet defined */
407 if(!img->studyNr[0] && strlen(sif.studynr)>1 )
409 /* Isotope half-life, if not yet defined */
411 if(img->isotopeHalflife<=0.0 && f>0.0) img->isotopeHalflife=60.0*f;
412 sifEmpty(&sif);
413
414 return STATUS_OK;
415}
double hlFromIsotope(char *isocode)
Definition halflife.c:55
int imgGetAnalyzeHeader(IMG *img, ANALYZE_DSR *h)
Definition img_ana.c:427

Referenced by imgFormatDetermine(), imgReadAnalyzeFirstFrame(), imgReadHeader(), and imgWriteAnalyzeFrame().

◆ imgReadEcat63FirstFrame()

int imgReadEcat63FirstFrame ( const char * fname,
IMG * img )
extern

Read the first frame from an ECAT 6.3 file into IMG data structure.

Parameters
fnamename of file from which IMG contents will be read
imgpointer to the initiated but not preallocated IMG data
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 1457 of file img_e63.c.

1457 {
1458 int ret=0;
1459
1460 if(IMG_TEST) printf("\nimgReadEcat63FirstFrame(%s, *img)\n", fname);
1461 /* Check the input */
1462 if(img==NULL) return STATUS_FAULT;
1463 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
1464 imgSetStatus(img, STATUS_FAULT);
1465 if(fname==NULL) return STATUS_FAULT;
1466
1467 /* Read header information from file */
1468 ret=imgReadEcat63Header(fname, img); if(ret) return(ret);
1469 if(IMG_TEST>4) imgInfo(img);
1470
1471 /* Allocate memory for one frame */
1472 img->dimt=1;
1473 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
1474 if(ret) return STATUS_NOMEMORY;
1475
1476 /* Read the first frame */
1477 ret=imgReadEcat63Frame(fname, 1, img, 0); if(ret) return(ret);
1478
1479 /* All went well */
1480 imgSetStatus(img, STATUS_OK);
1481 return STATUS_OK;
1482}
int imgReadEcat63Frame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition img_e63.c:1503

◆ imgReadEcat63Frame()

int imgReadEcat63Frame ( const char * fname,
int frame_to_read,
IMG * img,
int frame_index )
extern

Read a specified frame from an ECAT 6.3 file into preallocated IMG data structure.

IMG header is assumed to be filled correctly before calling this function, except for information concerning separate planes and this frame, which is filled here.

Parameters
fnamename of file from which IMG contents will be read
frame_to_readframe which will be read (1..frameNr)
imgpointer to the IMG data. Place for the frame must be preallocated
frame_indexIMG frame index (0..dimt-1) where data will be placed
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error. If frame does not exist, then and only then STATUS_NOMATRIX is returned.

Definition at line 1503 of file img_e63.c.

1505 {
1506 int ret=0, blkNr=0, frame, plane, seqplane=-1;
1507 int local_data_type=0;
1508 FILE *fp;
1509 ECAT63_mainheader main_header;
1510 MATRIXLIST mlist;
1511 Matval matval;
1512 ECAT63_imageheader image_header;
1513 ECAT63_scanheader scan_header;
1514 ECAT63_attnheader attn_header;
1515 ECAT63_normheader norm_header;
1516 float scale=1.0;
1517 short int *sptr;
1518 char *mdata=NULL, *mptr;
1519 /*int *iptr;*/
1520
1521
1522 if(IMG_TEST) printf("\nimgReadEcat63Frame(%s, %d, *img, %d)\n",
1523 fname, frame_to_read, frame_index);
1524
1525 /* Check the input */
1526 if(img==NULL) return STATUS_FAULT;
1527 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
1528 imgSetStatus(img, STATUS_FAULT);
1529 if(fname==NULL) return STATUS_FAULT;
1530 if(frame_index<0 || frame_index>img->dimt-1) return STATUS_FAULT;
1531 if(frame_to_read<1) return STATUS_FAULT;
1532
1533 /* Open the file */
1534 if((fp=fopen(fname, "rb")) == NULL) return STATUS_NOFILE;
1535
1536 /* Read main header */
1537 if((ret=ecat63ReadMainheader(fp, &main_header))) {
1538 fclose(fp); return STATUS_NOMAINHEADER;}
1539
1540 /* Read matrix list and nr and sort it */
1541 ecat63InitMatlist(&mlist);
1542 ret=ecat63ReadMatlist(fp, &mlist, IMG_TEST-1);
1543 if(ret) {fclose(fp); return STATUS_NOMATLIST;}
1544 if(mlist.matrixNr<=0) {
1545 fclose(fp); ecat63EmptyMatlist(&mlist); return STATUS_INVALIDMATLIST;}
1546 /* Make sure that plane and frame numbers are continuous */
1547 ecat63GatherMatlist(&mlist, 1, 1, 1, 1);
1549
1550 /* Calculate and check the size of one data matrix */
1551 ret=ecat63GetMatrixBlockSize(&mlist, &blkNr);
1552 if(ret) {ecat63EmptyMatlist(&mlist); fclose(fp); return ret;}
1553 /* And allocate memory for the raw data blocks */
1554 if(IMG_TEST>6) printf("allocating memory for %d blocks\n", blkNr);
1555 mdata=(char*)malloc((size_t)blkNr*MatBLKSIZE);
1556 if(mdata==NULL) {
1557 fclose(fp); ecat63EmptyMatlist(&mlist); return STATUS_NOMEMORY;}
1558
1559 /* Read all matrices that belong to the required frame */
1560 ret=0; seqplane=-1;
1561 for(int m=0; m<mlist.matrixNr; m++) if(mlist.matdir[m].matstat==1) {
1562 /* get frame and plane */
1563 mat_numdoc(mlist.matdir[m].matnum, &matval);
1564 plane=matval.plane;
1565 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
1566 else frame=matval.gate; /* printf("frame=%d plane=%d\n", frame, plane); */
1567 if(frame!=frame_to_read) continue; /* do not process other frames */
1568 seqplane++;
1569 if(img->planeNumber[seqplane]<1) {
1570 img->planeNumber[seqplane]=plane;
1571 } else if(img->planeNumber[seqplane]!=plane) {
1572 fclose(fp); ecat63EmptyMatlist(&mlist); free(mdata);
1573 return STATUS_MISSINGMATRIX;
1574 }
1575
1576 /* Read the subheader */
1577 if(IMG_TEST>4) printf("reading subheader for matrix %d,%d\n", frame, plane);
1578 if(main_header.file_type==IMAGE_DATA) {
1579 ret=ecat63ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header, IMG_TEST-10, NULL);
1580 scale=image_header.quant_scale;
1581 if(image_header.ecat_calibration_fctr>0.0 &&
1582 fabs(main_header.calibration_factor/image_header.ecat_calibration_fctr - 1.0)>0.0001)
1583 scale*=image_header.ecat_calibration_fctr;
1584 local_data_type=image_header.data_type;
1585 img->start[frame_index]=image_header.frame_start_time/1000.;
1586 img->end[frame_index]=img->start[frame_index]+image_header.frame_duration/1000.;
1587 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1588 if(image_header.decay_corr_fctr>1.0) {
1589 img->decayCorrFactor[frame_index]=image_header.decay_corr_fctr;
1591 } else {
1592 img->decayCorrFactor[frame_index]=0.0;
1594 }
1595 img->xform[0]=NIFTI_XFORM_UNKNOWN; // qform
1596 img->xform[1]=NIFTI_XFORM_SCANNER_ANAT; // sform
1597 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
1598 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
1599 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
1600 } else if(main_header.file_type==RAW_DATA) {
1601 ret=ecat63ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header, IMG_TEST-10, NULL);
1602 scale=scan_header.scale_factor;
1603 if(scan_header.loss_correction_fctr>0.0) scale*=scan_header.loss_correction_fctr;
1604 local_data_type=scan_header.data_type;
1605 img->start[frame_index]=scan_header.frame_start_time/1000.;
1606 img->end[frame_index]=img->start[frame_index]+scan_header.frame_duration/1000.;
1607 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1608 img->sampleDistance=10.0*scan_header.sample_distance;
1609 img->prompts[frame_index]=(float)scan_header.prompts;
1610 img->randoms[frame_index]=(float)scan_header.delayed;
1611 } else if(main_header.file_type==ATTN_DATA) {
1612 ret=ecat63ReadAttnheader(fp, mlist.matdir[m].strtblk, &attn_header, IMG_TEST-10, NULL);
1613 img->sampleDistance=10.0*attn_header.sample_distance;
1614 scale=attn_header.scale_factor;
1615 local_data_type=attn_header.data_type;
1616 } else if(main_header.file_type==NORM_DATA) {
1617 ret=ecat63ReadNormheader(fp, mlist.matdir[m].strtblk, &norm_header, IMG_TEST-10, NULL);
1618 scale=norm_header.scale_factor;
1619 local_data_type=norm_header.data_type;
1620 } else
1621 img->_dataType=-1;
1622 if(ret) {
1623 ecat63EmptyMatlist(&mlist); free(mdata); fclose(fp);
1624 return STATUS_NOSUBHEADER;
1625 }
1626 if(main_header.calibration_factor>0.0) scale*=main_header.calibration_factor;
1627 if(IMG_TEST>6) printf("scale=%e datatype=%d\n", scale, img->_dataType);
1628 /* Read the pixel data */
1629 if(IMG_TEST>4) printf("reading matrix data\n");
1630 ret=ecat63ReadMatdata(fp, mlist.matdir[m].strtblk+1,
1631 mlist.matdir[m].endblk-mlist.matdir[m].strtblk,
1632 mdata, local_data_type);
1633 if(ret) {
1634 ecat63EmptyMatlist(&mlist); free(mdata); fclose(fp);
1635 return STATUS_MISSINGMATRIX;
1636 }
1637 if(IMG_TEST>4) printf("converting matrix data to floats\n");
1638 mptr=mdata;
1639 if(local_data_type==BYTE_TYPE) {
1640 for(int yi=0; yi<img->dimy; yi++)
1641 for(int xi=0; xi<img->dimx; xi++, mptr++) {
1642 img->m[seqplane][yi][xi][frame_index]=scale*(float)(*mptr);
1643 }
1644 } else if(local_data_type==VAX_I2 || local_data_type==SUN_I2) {
1645 for(int yi=0; yi<img->dimy; yi++)
1646 for(int xi=0; xi<img->dimx; xi++, mptr+=2) {
1647 sptr=(short int*)mptr;
1648 img->m[seqplane][yi][xi][frame_index]=scale*(float)(*sptr);
1649 }
1650 } else if(local_data_type==VAX_I4 || local_data_type==SUN_I4) {
1651 for(int yi=0; yi<img->dimy; yi++)
1652 for(int xi=0; xi<img->dimx; xi++, mptr+=4) {
1653 /*iptr=(int*)mptr;*/
1654 img->m[seqplane][yi][xi][frame_index]=1.0; /* scale*(float)(*iptr); */
1655 }
1656 } else if(local_data_type==VAX_R4 || local_data_type==IEEE_R4) {
1657 for(int yi=0; yi<img->dimy; yi++)
1658 for(int xi=0; xi<img->dimx; xi++, mptr+=4) {
1659 memcpy(&img->m[seqplane][yi][xi][frame_index], mptr, 4);
1660 img->m[seqplane][yi][xi][frame_index]*=scale;
1661 }
1662 }
1663 } /* next matrix */
1664 if(IMG_TEST>3) printf("end of matrices.\n");
1665
1666 free(mdata);
1667 ecat63EmptyMatlist(&mlist);
1668 fclose(fp);
1669
1670 /* seqplane is <0 only if this frame did not exist at all; return -1 */
1671 if(IMG_TEST>4) printf("last_seqplane := %d.\n", seqplane);
1672 if(seqplane<0) {imgSetStatus(img, STATUS_NOMATRIX); return STATUS_NOMATRIX;}
1673
1674 /* check that correct number of planes was read */
1675 if(seqplane+1 != img->dimz) {
1676 imgSetStatus(img, STATUS_MISSINGMATRIX);
1677 return STATUS_MISSINGMATRIX;
1678 }
1679
1680 /* For saving IMG data, only 2-byte VAX data types are allowed,
1681 so change it now */
1682 if(img->_dataType==VAX_I4 || img->_dataType==VAX_R4) img->_dataType=VAX_I2;
1683
1684 /* All went well */
1685 imgSetStatus(img, STATUS_OK);
1686 return STATUS_OK;
1687}
int ecat63GatherMatlist(MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)
Definition ecat63ml.c:510
int ecat63GetMatrixBlockSize(MATRIXLIST *mlist, int *blk_nr)
Definition ecat63ml.c:366
void ecat63SortMatlistByFrame(MATRIXLIST *ml)
Definition ecat63ml.c:297

Referenced by imgReadEcat63FirstFrame(), and imgReadFrame().

◆ imgReadEcat63Header()

int imgReadEcat63Header ( const char * fname,
IMG * img )
extern

Fill IMG structure header information from an image or sinogram file in ECAT 6.3 format. Information concerning separate frames or planes is not filled.

Note
ECAT 6.3 files do not have a magic number, therefore, do not use this function to determine if your file is in this format, at least test all other possible formats before calling this.
Parameters
fnameimage or sinogram filename
imgpointer to initialized IMG structure
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 1318 of file img_e63.c.

1321 {
1322 int m, blkNr=0, ret=0;
1323 int frameNr, planeNr;
1324 FILE *fp;
1325 ECAT63_mainheader main_header;
1326 MATRIXLIST mlist;
1327 ECAT63_imageheader image_header;
1328 ECAT63_scanheader scan_header;
1329 ECAT63_attnheader attn_header;
1330 ECAT63_normheader norm_header;
1331
1332
1333 if(IMG_TEST>0) printf("\nimgReadEcat63Header(%s, *img)\n", fname);
1334
1335 /* Check the arguments */
1336 if(img==NULL) return STATUS_FAULT;
1337 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
1338 imgSetStatus(img, STATUS_FAULT);
1339 if(fname==NULL) return STATUS_FAULT;
1340
1341 /* Open the file */
1342 if((fp=fopen(fname, "rb")) == NULL) return STATUS_NOFILE;
1343
1344 /* Read main header */
1345 if((ret=ecat63ReadMainheader(fp, &main_header))) {
1346 fclose(fp); return STATUS_NOMAINHEADER;}
1347 /* Check if file_type is supported */
1348 if(imgEcat63Supported(&main_header)==0) {
1349 fclose(fp); return STATUS_UNSUPPORTED;}
1350 /* Copy main header information into IMG; sets also img.type */
1351 imgGetEcat63MHeader(img, &main_header);
1352 if(IMG_TEST>7) printf("img.type := %d\n", img->type);
1353 img->_fileFormat=imgGetEcat63Fileformat(&main_header);
1354 if(IMG_TEST>7) printf("img._fileFormat := %d\n", img->_fileFormat);
1355 if(img->_fileFormat==IMG_UNKNOWN) {fclose(fp); return STATUS_UNSUPPORTED;}
1356
1357 /* Read matrix list and nr and sort it */
1358 ecat63InitMatlist(&mlist);
1359 ret=ecat63ReadMatlist(fp, &mlist, IMG_TEST-1);
1360 if(ret) {fclose(fp); return STATUS_NOMATLIST;}
1361 if(mlist.matrixNr<=0) {
1362 ecat63EmptyMatlist(&mlist); fclose(fp); return STATUS_INVALIDMATLIST;}
1363 /* Make sure that plane and frame numbers are continuous */
1364 ecat63GatherMatlist(&mlist, 1, 1, 1, 1);
1365 ecat63SortMatlistByPlane(&mlist); // otherwise frameNr can't be computed below
1366 /* Trim extra frames */
1367 if(main_header.num_frames>0)
1368 /*del_nr=*/ecat63DeleteLateFrames(&mlist, main_header.num_frames);
1369 /* Get plane and frame numbers and check that volume is full */
1370 ret=ecat63GetPlaneAndFrameNr(&mlist, &main_header, &planeNr, &frameNr);
1371 if(ret) {ecat63EmptyMatlist(&mlist); fclose(fp); return ret;}
1372 img->dimz=planeNr;
1373 img->dimt=frameNr;
1374 /* Calculate and check the size of one data matrix */
1375 ret=ecat63GetMatrixBlockSize(&mlist, &blkNr);
1376 if(ret) {ecat63EmptyMatlist(&mlist); fclose(fp); return ret;}
1377
1378 /* Read one subheader */
1379 if(IMG_TEST>5) printf("main_header.file_type := %d\n", main_header.file_type);
1380 m=0;
1381 switch(main_header.file_type) {
1382 case IMAGE_DATA:
1383 ret=ecat63ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header, IMG_TEST-10, NULL);
1384 break;
1385 case RAW_DATA:
1386 ret=ecat63ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header, IMG_TEST-10, NULL);
1387 break;
1388 case ATTN_DATA:
1389 ret=ecat63ReadAttnheader(fp, mlist.matdir[m].strtblk, &attn_header, IMG_TEST-10, NULL);
1390 break;
1391 case NORM_DATA:
1392 ret=ecat63ReadNormheader(fp, mlist.matdir[m].strtblk, &norm_header, IMG_TEST-10, NULL);
1393 break;
1394 default: ret=-1;
1395 }
1396 /* Free locally allocated memory and close the file */
1397 ecat63EmptyMatlist(&mlist); fclose(fp);
1398 /* Check whether subheader was read */
1399 if(ret) return STATUS_NOSUBHEADER;
1400
1401 /* Get the following information in the subheader:
1402 dimensions x, y and z; datatype;
1403 image decay correction on/off, zoom, and pixel size;
1404 sinogram sample distance.
1405 */
1406 switch(main_header.file_type) {
1407 case IMAGE_DATA:
1408 img->dimx=image_header.dimension_1; img->dimy=image_header.dimension_2;
1409 if(img->unit<1) imgUnitFromEcat(img, image_header.quant_units);
1410 img->_dataType=image_header.data_type;
1411 img->zoom=image_header.recon_scale;
1412 if(image_header.decay_corr_fctr>1.0) img->decayCorrection=IMG_DC_CORRECTED;
1414 img->sizex=img->sizey=10.*image_header.pixel_size;
1415 if(img->sizez<10.*image_header.slice_width)
1416 img->sizez=10.*image_header.slice_width;
1417 break;
1418 case RAW_DATA:
1419 img->dimx=scan_header.dimension_1; img->dimy=scan_header.dimension_2;
1420 img->type=IMG_TYPE_RAW;
1421 img->_dataType=scan_header.data_type;
1423 img->sampleDistance=10.0*scan_header.sample_distance;
1424 break;
1425 case ATTN_DATA:
1426 img->dimx=attn_header.dimension_1; img->dimy=attn_header.dimension_2;
1427 img->type=IMG_TYPE_ATTN;
1429 img->_dataType=attn_header.data_type;
1430 break;
1431 case NORM_DATA:
1432 img->dimx=norm_header.dimension_1; img->dimy=norm_header.dimension_2;
1433 img->type=IMG_TYPE_RAW;
1435 img->_dataType=norm_header.data_type;
1436 break;
1437 }
1438
1439 /* For saving IMG data, only 2-byte VAX data types are allowed,
1440 so change it now */
1441 if(img->_dataType==VAX_I4 || img->_dataType==VAX_R4) img->_dataType=VAX_I2;
1442
1443 imgSetStatus(img, STATUS_OK);
1444 return STATUS_OK;
1445}
int ecat63GetPlaneAndFrameNr(MATRIXLIST *mlist, ECAT63_mainheader *h, int *plane_nr, int *frame_nr)
Definition ecat63ml.c:400
int imgGetEcat63Fileformat(ECAT63_mainheader *h)
Definition img_e63.c:1288
int imgEcat63Supported(ECAT63_mainheader *h)
Definition img_e63.c:1155
void imgGetEcat63MHeader(IMG *img, ECAT63_mainheader *h)
Definition img_e63.c:1172

Referenced by imgFormatDetermine(), imgReadEcat63FirstFrame(), imgReadHeader(), and imgWriteEcat63Frame().

◆ imgReadEcat7()

int imgReadEcat7 ( const char * fname,
IMG * img )
extern

Read ECAT 7 image, volume or 2D sinogram.

Returns
0 if ok, 1 invalid input, 2 image status is not 'initialized', 3 failed to open file field for reading, 4 recognize file, 5 file type not supported, 6 invalid matrix list, 7 invalid number of matrices/frames, 8 variable matrix size, 9 failed to read header, 11 failed to allocate memory for data, 13 failed to read data.
Parameters
fnameName of the input ECAT 7 file.
imgData structure in which the file is read; must be initialized before using this function.

Definition at line 19 of file img_e7.c.

25 {
26 ECAT7_mainheader main_header;
27 ECAT7_imageheader image_header;
28 ECAT7_2Dscanheader scan2d_header;
29 ECAT7_scanheader scan_header;
30 ECAT7_polmapheader polmap_header;
31 ECAT7_MATRIXLIST mlist;
32 ECAT7_Matval matval;
33 float *fdata=NULL, *fptr;
34 int blkNr=0;
35
36
37 if(IMG_TEST) printf("imgReadEcat7(%s, *img)\n", fname);
38 /* Check the arguments */
39 if(fname==NULL) return(1);
40 if(img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
41 imgSetStatus(img, STATUS_FAULT); return(2);}
42
43 /* Open file for read */
44 FILE *fp;
45 if((fp=fopen(fname, "rb"))==NULL) {imgSetStatus(img,STATUS_NOFILE); return(3);}
46
47 /* Read main header */
48 int ret=ecat7ReadMainheader(fp, &main_header);
49 if(ret) {fclose(fp); imgSetStatus(img, STATUS_UNKNOWNFORMAT); return(4);}
50 /* Check for magic number */
51 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {
52 fclose(fp); imgSetStatus(img, STATUS_UNKNOWNFORMAT); return(4);
53 }
54
55 /* Check if file_type is supported */
56 if(imgEcat7Supported(&main_header)==0) {
57 fclose(fp); imgSetStatus(img, STATUS_UNSUPPORTED); return(5);
58 }
59
60 /* Read matrix list */
61 ecat7InitMatlist(&mlist);
62 ret=ecat7ReadMatlist(fp, &mlist, IMG_TEST-1);
63 if(ret || mlist.matrixNr<1 || ecat7CheckMatlist(&mlist)) {
64 if(IMG_TEST) printf(" ret=%d mlist.matrixNr=%d\n", ret, mlist.matrixNr);
65 fclose(fp); imgSetStatus(img, STATUS_INVALIDMATLIST); return(6);}
67 if(IMG_TEST>2) ecat7PrintMatlist(&mlist);
68
69 /* Calculate the number of planes, frames and gates */
70 /* Check that all planes have equal nr of frames (gates) */
71 /* and check that frames (gates) are consequentally numbered */
72 int frame, plane, prev_frame, prev_plane, planeNr, frameNr;
73 prev_plane=plane=-1; prev_frame=frame=-1; frameNr=planeNr=0; ret=0;
74 for(int m=0; m<mlist.matrixNr; m++) {
75 ecat7_id_to_val(mlist.matdir[m].id, &matval); plane=matval.plane;
76 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
77 else frame=matval.gate;
78 if(plane!=prev_plane) {frameNr=1; planeNr++;}
79 else {frameNr++; if(prev_frame>0 && frame!=prev_frame+1) {ret=1; break;}}
80 prev_plane=plane; prev_frame=frame;
81 /* Calculate and check the size of one data matrix */
82 if(m==0) {
83 blkNr=mlist.matdir[m].endblk-mlist.matdir[m].strtblk;
84 } else if(blkNr!=mlist.matdir[m].endblk-mlist.matdir[m].strtblk) {
85 ret=2; break;
86 }
87 } /* next matrix */
88 if(IMG_TEST>2) printf("frameNr=%d planeNr=%d\n", frameNr, planeNr);
89 if(ret==1 || (frameNr*planeNr != mlist.matrixNr)) {
90 fclose(fp); imgSetStatus(img, STATUS_MISSINGMATRIX);
91 ecat7EmptyMatlist(&mlist); return(7);
92 }
93 if(ret==2) {
94 fclose(fp); imgSetStatus(img, STATUS_VARMATSIZE);
95 ecat7EmptyMatlist(&mlist); return(8);
96 }
97
98 /* Read the first subheader to get planeNr from volumes and to get x&y dim */
99 int m=0, dimx, dimy, dimz=1;
100 imgSetStatus(img, STATUS_NOSUBHEADER);
101 switch(main_header.file_type) {
102 case ECAT7_IMAGE8:
103 case ECAT7_IMAGE16:
104 case ECAT7_VOLUME8:
105 case ECAT7_VOLUME16:
106 img->type=IMG_TYPE_IMAGE;
107 ret=ecat7ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header);
108 dimx=image_header.x_dimension; dimy=image_header.y_dimension;
109 if(image_header.num_dimensions>2 && image_header.z_dimension>1)
110 planeNr=dimz=image_header.z_dimension;
111 break;
112 case ECAT7_2DSCAN:
113 img->type=IMG_TYPE_RAW;
114 ret=ecat7Read2DScanheader(fp, mlist.matdir[m].strtblk, &scan2d_header);
115 dimx=scan2d_header.num_r_elements; dimy=scan2d_header.num_angles;
116 if(scan2d_header.num_dimensions>2 && scan2d_header.num_z_elements>1)
117 planeNr=dimz=scan2d_header.num_z_elements;
118 break;
119 case ECAT7_3DSCAN:
120 case ECAT7_3DSCAN8:
121 case ECAT7_3DSCANFIT:
122 img->type=IMG_TYPE_RAW;
123 ret=ecat7ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header);
124 dimx=scan_header.num_r_elements; dimy=scan_header.num_angles;
125 dimz=0;
126 for(int i=0; i<64; i++) dimz+=scan_header.num_z_elements[i];
127 planeNr=dimz;
128 /*if(scan_header.axial_compression!=0) {
129 img->statmsg=imgmsg[STATUS_UNSUPPORTEDAXIALCOMP]; ret=-1;}*/
130 break;
131 case ECAT7_POLARMAP:
133 ret=ecat7ReadPolmapheader(fp, mlist.matdir[m].strtblk, &polmap_header);
134 planeNr=dimz=dimy=1; dimx=0;
135 for(int i=0; i<polmap_header.num_rings; i++)
136 dimx+=polmap_header.sectors_per_ring[i];
137 break;
138 default: dimx=dimy=dimz=planeNr=0; ret=-1;
139 }
140 long long pxlNr=dimx*dimy;
141 if(ret || pxlNr<1 || planeNr<1) {
142 fclose(fp); ecat7EmptyMatlist(&mlist); return(9);}
143 imgSetStatus(img, STATUS_OK);
144
145 /* Allocate memory for IMG data */
146 ret=imgAllocate(img, planeNr, dimy, dimx, frameNr);
147 if(ret) {
148 fclose(fp); imgSetStatus(img, STATUS_NOMEMORY);
149 ecat7EmptyMatlist(&mlist); return(11);
150 }
151 /* Copy information from mainheader */
152 imgGetEcat7MHeader(img, &main_header);
153 /* Set fileFormat */
154 switch(main_header.file_type) {
155 case ECAT7_IMAGE8:
156 case ECAT7_IMAGE16:
157 img->_fileFormat=IMG_E7_2D; break;
158 case ECAT7_VOLUME8:
159 case ECAT7_VOLUME16:
160 img->_fileFormat=IMG_E7; break;
161 case ECAT7_2DSCAN:
162 img->_fileFormat=IMG_E7_2D; break;
163 case ECAT7_3DSCAN:
164 case ECAT7_3DSCAN8:
165 case ECAT7_3DSCANFIT:
166 img->_fileFormat=IMG_E7; break;
167 case ECAT7_POLARMAP:
168 img->_fileFormat=IMG_POLARMAP; break;
169 default:
170 img->_fileFormat=IMG_UNKNOWN; break;
171 }
172
173 if(dimz>1) {
174 /* Read ECAT volume matrices */
175 int fi=0;
176 for(int m=0; m<mlist.matrixNr; m++) {
177 /* Get matrix values */
178 ecat7_id_to_val(mlist.matdir[m].id, &matval);
179 /* Read subheader and data */
180 if(img->type==IMG_TYPE_IMAGE)
181 ret=ecat7ReadImageMatrix(fp, mlist.matdir[m].strtblk,
182 mlist.matdir[m].endblk, &image_header, &fdata);
183 else
184 ret=ecat7ReadScanMatrix(fp, mlist.matdir[m].strtblk,
185 mlist.matdir[m].endblk, &scan_header, &fdata);
186 if(ret || fdata==NULL) {
187 if(IMG_TEST) printf("ecat7ReadXMatrix()=%d\n%s\n", ret, ecat7errmsg);
188 fclose(fp); imgSetStatus(img, STATUS_NOMATRIX);
189 ecat7EmptyMatlist(&mlist); return(13);
190 }
191 /* Copy subheader information */
192 if(img->type==IMG_TYPE_POLARMAP) {
193 img->_dataType=polmap_header.data_type;
194 img->start[fi]=polmap_header.frame_start_time/1000.;
195 img->end[fi]=img->start[fi]+polmap_header.frame_duration/1000.;
196 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
197 img->sizex=0.001*polmap_header.pixel_size;
198 } else if(img->type==IMG_TYPE_IMAGE) {
199 img->_dataType=image_header.data_type;
200 img->start[fi]=image_header.frame_start_time/1000.;
201 img->end[fi]=img->start[fi]+image_header.frame_duration/1000.;
202 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
203 if(image_header.decay_corr_fctr>1.0) {
204 img->decayCorrFactor[fi]=image_header.decay_corr_fctr;
206 } else {
207 img->decayCorrFactor[fi]=0.0;
209 }
210 img->zoom=image_header.recon_zoom;
211 img->sizex=10.*image_header.x_pixel_size;
212 img->sizey=10.*image_header.y_pixel_size;
213 img->sizez=10.*image_header.z_pixel_size;
214 img->resolutionx=10.*image_header.x_resolution;
215 img->resolutiony=10.*image_header.y_resolution;
216 img->resolutionz=10.*image_header.z_resolution;
217 img->xform[0]=NIFTI_XFORM_UNKNOWN; // qform
218 img->xform[1]=NIFTI_XFORM_SCANNER_ANAT; // sform
219 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
220 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
221 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
222 img->mt[0]=image_header.mt_1_1;
223 img->mt[1]=image_header.mt_1_2;
224 img->mt[2]=image_header.mt_1_3;
225 img->mt[3]=image_header.mt_1_4;
226 img->mt[4]=image_header.mt_2_1;
227 img->mt[5]=image_header.mt_2_2;
228 img->mt[6]=image_header.mt_2_3;
229 img->mt[7]=image_header.mt_2_4;
230 img->mt[8]=image_header.mt_3_1;
231 img->mt[9]=image_header.mt_3_2;
232 img->mt[10]=image_header.mt_3_3;
233 img->mt[11]=image_header.mt_3_4;
234 } else {
235 img->_dataType=scan_header.data_type;
236 img->start[fi]=scan_header.frame_start_time/1000.;
237 img->end[fi]=img->start[fi]+scan_header.frame_duration/1000.;
238 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
239 if(scan_header.x_resolution>0.0)
240 img->sampleDistance=10.0*scan_header.x_resolution;
241 else
242 img->sampleDistance=10.0*main_header.bin_size;
243 /* also, correct for dead-time */
244 if(scan_header.deadtime_correction_factor>0.0) {
245 fptr=fdata;
246 for(long long i=0; i<dimz*pxlNr; i++, fptr++)
247 *fptr*=scan_header.deadtime_correction_factor;
248 }
249 img->prompts[fi]=(float)scan_header.prompts;
250 img->randoms[fi]=scan_header.delayed;
251 }
252 /* Copy matrix data through volume planes */
253 for(int pi=0; pi<dimz; pi++) {
254 fptr=fdata+pi*pxlNr;
255 for(int yi=0; yi<dimy; yi++)
256 for(int xi=0; xi<dimx; xi++)
257 img->m[pi][yi][xi][fi]= *fptr++;
258 }
259 free(fdata); fi++;
260 } /* next matrix */
261 /* Set plane numbers */
262 for(int pi=0; pi<dimz; pi++) img->planeNumber[pi]=pi+1;
263 } else {
264 /* Read separate matrices */
265 prev_plane=plane=-1; prev_frame=frame=-1;
266 int pi=-1, fi=-1;
267 for(int m=0; m<mlist.matrixNr; m++) {
268 ecat7_id_to_val(mlist.matdir[m].id, &matval); plane=matval.plane;
269 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
270 else frame=matval.gate;
271 if(plane!=prev_plane) {fi=0; pi++;} else fi++;
272 /* Read subheader and data */
273 if(img->type==IMG_TYPE_POLARMAP)
274 ret=ecat7ReadPolarmapMatrix(fp, mlist.matdir[m].strtblk,
275 mlist.matdir[m].endblk, &polmap_header, &fdata);
276 else if(img->type==IMG_TYPE_IMAGE)
277 ret=ecat7ReadImageMatrix(fp, mlist.matdir[m].strtblk,
278 mlist.matdir[m].endblk, &image_header, &fdata);
279 else
280 ret=ecat7Read2DScanMatrix(fp, mlist.matdir[m].strtblk,
281 mlist.matdir[m].endblk, &scan2d_header, &fdata);
282 if(ret || fdata==NULL) {
283 fclose(fp); imgSetStatus(img, STATUS_NOMATRIX);
284 ecat7EmptyMatlist(&mlist); return(13);
285 }
286 /* Copy subheader information */
287 if(fi==0) img->planeNumber[pi]=plane;
288 if(img->type==IMG_TYPE_POLARMAP) {
289 img->_dataType=polmap_header.data_type;
290 img->start[fi]=polmap_header.frame_start_time/1000.;
291 img->end[fi]=img->start[fi]+polmap_header.frame_duration/1000.;
292 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
293 img->sizex=0.001*polmap_header.pixel_size;
294 } else if(img->type==IMG_TYPE_IMAGE) {
295 img->_dataType=image_header.data_type;
296 img->start[fi]=image_header.frame_start_time/1000.;
297 img->end[fi]=img->start[fi]+image_header.frame_duration/1000.;
298 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
299 if(image_header.decay_corr_fctr>1.0) {
300 img->decayCorrFactor[fi]=image_header.decay_corr_fctr;
302 } else {
303 img->decayCorrFactor[fi]=0.0;
305 }
306 img->zoom=image_header.recon_zoom;
307 img->sizex=10.*image_header.x_pixel_size;
308 img->sizey=10.*image_header.y_pixel_size;
309 img->sizez=10.*image_header.z_pixel_size;
310 img->resolutionx=10.*image_header.x_resolution;
311 img->resolutiony=10.*image_header.y_resolution;
312 img->resolutionz=10.*image_header.z_resolution;
313 img->xform[0]=NIFTI_XFORM_UNKNOWN; // qform
314 img->xform[1]=NIFTI_XFORM_SCANNER_ANAT; // sform
315 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
316 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
317 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
318 img->mt[0]=image_header.mt_1_1;
319 img->mt[1]=image_header.mt_1_2;
320 img->mt[2]=image_header.mt_1_3;
321 img->mt[3]=image_header.mt_1_4;
322 img->mt[4]=image_header.mt_2_1;
323 img->mt[5]=image_header.mt_2_2;
324 img->mt[6]=image_header.mt_2_3;
325 img->mt[7]=image_header.mt_2_4;
326 img->mt[8]=image_header.mt_3_1;
327 img->mt[9]=image_header.mt_3_2;
328 img->mt[10]=image_header.mt_3_3;
329 img->mt[11]=image_header.mt_3_4;
330 } else {
331 img->_dataType=scan2d_header.data_type;
332 img->start[fi]=scan2d_header.frame_start_time/1000.;
333 img->end[fi]=img->start[fi]+scan2d_header.frame_duration/1000.;
334 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
335 if(scan_header.x_resolution>0.0)
336 img->sampleDistance=10.0*scan_header.x_resolution;
337 else
338 img->sampleDistance=10.0*main_header.bin_size;
339 /* also, correct for dead-time */
340 if(scan2d_header.deadtime_correction_factor>0.0) {
341 fptr=fdata;
342 for(long long i=0; i<pxlNr; i++, fptr++)
343 *fptr*=scan2d_header.deadtime_correction_factor;
344 }
345 img->prompts[fi]=(float)scan_header.prompts;
346 img->randoms[fi]=scan_header.delayed;
347 }
348 /* Copy matrix data */
349 fptr=fdata;
350 for(int yi=0; yi<dimy; yi++) for(int xi=0; xi<dimx; xi++)
351 img->m[pi][yi][xi][fi]= *fptr++;
352 free(fdata);
353 /* prepare for the next matrix */
354 prev_plane=plane; prev_frame=frame;
355 } /* next matrix */
356 }
357 fclose(fp); ecat7EmptyMatlist(&mlist);
358
359 /* Calibrate */
360 if(main_header.ecat_calibration_factor>0.0)
361 for(int pi=0; pi<img->dimz; pi++)
362 for(int yi=0; yi<img->dimy; yi++) for(int xi=0; xi<img->dimx; xi++)
363 for(int fi=0; fi<img->dimt; fi++)
364 img->m[pi][yi][xi][fi]*=main_header.ecat_calibration_factor;
365
366 imgSetStatus(img, STATUS_OK);
367 return(0);
368}
int ecat7Read2DScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_2Dscanheader *h, float **fdata)
Definition ecat7r.c:959
int ecat7ReadPolarmapMatrix(FILE *fp, int first_block, int last_block, ECAT7_polmapheader *h, float **fdata)
Definition ecat7r.c:1154
int ecat7ReadImageMatrix(FILE *fp, int first_block, int last_block, ECAT7_imageheader *h, float **fdata)
Definition ecat7r.c:858
int ecat7ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_scanheader *h, float **fdata)
Definition ecat7r.c:1055
void imgGetEcat7MHeader(IMG *img, ECAT7_mainheader *h)
Definition img_e7.c:742

Referenced by imgRead().

◆ imgReadEcat7FirstFrame()

int imgReadEcat7FirstFrame ( const char * fname,
IMG * img )
extern

Read the first frame from an ECAT 7 file into IMG data structure.

Parameters
fnamename of file from which IMG contents will be read
imgpointer to the initiated but not preallocated IMG data
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 1060 of file img_e7.c.

1060 {
1061 int ret=0;
1062
1063 if(IMG_TEST) printf("\nimgReadEcat7FirstFrame(%s, *img)\n", fname);
1064 /* Check the input */
1065 if(img==NULL) return STATUS_FAULT;
1066 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
1067 imgSetStatus(img, STATUS_FAULT);
1068 if(fname==NULL) return STATUS_FAULT;
1069
1070 /* Read header information from file */
1071 ret=imgReadEcat7Header(fname, img); if(ret) return(ret);
1072 if(IMG_TEST>3) imgInfo(img);
1073
1074 /* Allocate memory for one frame */
1075 img->dimt=1;
1076 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
1077 if(ret) return STATUS_NOMEMORY;
1078
1079 /* Read the first frame */
1080 ret=imgReadEcat7Frame(fname, 1, img, 0); if(ret) return(ret);
1081
1082 /* All went well */
1083 imgSetStatus(img, STATUS_OK);
1084 return STATUS_OK;
1085}
int imgReadEcat7Frame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition img_e7.c:1103

◆ imgReadEcat7Frame()

int imgReadEcat7Frame ( const char * fname,
int frame_to_read,
IMG * img,
int frame_index )
extern

Read a specified frame from an ECAT 7 file into preallocated IMG data structure. IMG header is assumed to be filled correctly before calling this function, except for information concerning separate planes and this frame, which is filled here. If frame does not exist, then and only then STATUS_NOMATRIX is returned.

Parameters
fnamename of file from which IMG contents will be read
frame_to_readframe which will be read [1..frameNr]
imgpointer to the IMG data. Place for the frame must be preallocated
frame_indexIMG frame index [0..dimt-1] where data will be placed
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 1103 of file img_e7.c.

1105 {
1106 FILE *fp;
1107 int ret, frame, plane, seqplane;
1108 /* int blkNr=0; */
1109 ECAT7_mainheader main_header;
1110 ECAT7_imageheader image_header;
1111 ECAT7_2Dscanheader scan2d_header;
1112 ECAT7_scanheader scan_header;
1113 ECAT7_polmapheader polmap_header;
1114 ECAT7_MATRIXLIST mlist;
1115 ECAT7_Matval matval;
1116 float *fdata=NULL, *fptr;
1117
1118
1119 if(IMG_TEST) printf("\nimgReadEcat7Frame(%s, %d, *img, %d)\n",
1120 fname, frame_to_read, frame_index);
1121
1122 /* Check the input */
1123 if(img==NULL) return STATUS_FAULT;
1124 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
1125 if(fname==NULL) return STATUS_FAULT;
1126 if(frame_index<0 || frame_index>img->dimt-1) return STATUS_FAULT;
1127 if(frame_to_read<1) return STATUS_FAULT;
1128
1129 /* Open file for read */
1130 if((fp=fopen(fname, "rb")) == NULL) return STATUS_NOFILE;
1131
1132 /* Read main header */
1133 ret=ecat7ReadMainheader(fp, &main_header);
1134 if(ret) {fclose(fp); return STATUS_NOMAINHEADER;}
1135 /* Check for magic number */
1136 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {
1137 fclose(fp); return STATUS_UNKNOWNFORMAT;}
1138 /* Check if file_type is supported */
1139 if(imgEcat7Supported(&main_header)==0) {
1140 fclose(fp); return STATUS_UNSUPPORTED;}
1141 /* Read matrix list and nr and sort it */
1142 ecat7InitMatlist(&mlist);
1143 ret=ecat7ReadMatlist(fp, &mlist, IMG_TEST-1);
1144 if(ret) {fclose(fp); return STATUS_NOMATLIST;}
1145 if(mlist.matrixNr<=0 || ecat7CheckMatlist(&mlist)) {
1146 fclose(fp); ecat7EmptyMatlist(&mlist); return STATUS_INVALIDMATLIST;}
1147 /* Make sure that plane and frame numbers are continuous */
1148 ecat7GatherMatlist(&mlist, 1, 1, 1, 1);
1149 ecat7SortMatlistByFrame(&mlist); /* printf("matlist sorted\n"); */
1150 /* Calculate and check the size of one data matrix */
1151 /*ret=ecat7GetMatrixBlockSize(&mlist, &blkNr);
1152 if(ret) {fclose(fp); return ret;}*/
1153
1154 /* Read all matrices that belong to the required frame */
1155 /*blkNr=-1;*/
1156 ret=0; seqplane=-1;
1157 long long pxlNr=img->dimx*img->dimy;
1158 for(int m=0; m<mlist.matrixNr; m++) {
1159 /* get frame and plane */
1160 ecat7_id_to_val(mlist.matdir[m].id, &matval); plane=matval.plane;
1161 if(main_header.num_frames>=main_header.num_gates) frame=matval.frame;
1162 else frame=matval.gate; /* printf("frame=%d plane=%d\n", frame, plane); */
1163 if(frame!=frame_to_read) continue; /* do not process other frames */
1164 /*if(img->dimz>1) seqplane++; else seqplane=plane-1; */
1165 if(img->_fileFormat==IMG_E7_2D) seqplane=plane-1; else seqplane++;
1166
1167 /* Read subheader and data */
1168 if(IMG_TEST>4) printf("reading matrix %d,%d\n", frame, plane);
1169 if(img->type==IMG_TYPE_IMAGE) { /* 2D or 3D image */
1170 ret=ecat7ReadImageMatrix(fp, mlist.matdir[m].strtblk,
1171 mlist.matdir[m].endblk, &image_header, &fdata);
1172 } else if(img->type==IMG_TYPE_POLARMAP) { /* polarmap */
1173 ret=ecat7ReadPolarmapMatrix(fp, mlist.matdir[m].strtblk,
1174 mlist.matdir[m].endblk, &polmap_header, &fdata);
1175 } else if(img->dimz>1) { /* 3D sinogram */
1176 ret=ecat7ReadScanMatrix(fp, mlist.matdir[m].strtblk,
1177 mlist.matdir[m].endblk, &scan_header, &fdata);
1178 } else { /* 2D sinogram */
1179 ret=ecat7Read2DScanMatrix(fp, mlist.matdir[m].strtblk,
1180 mlist.matdir[m].endblk, &scan2d_header, &fdata);
1181 }
1182 if(ret || fdata==NULL) {
1183 fclose(fp); ecat7EmptyMatlist(&mlist); return STATUS_NOMATRIX;}
1184
1185 /* Copy information concerning this frame and make correction to data */
1186 if(img->type==IMG_TYPE_IMAGE) {
1187 img->start[frame_index]=image_header.frame_start_time/1000.;
1188 img->end[frame_index]=
1189 img->start[frame_index]+image_header.frame_duration/1000.;
1190 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1191 if(image_header.decay_corr_fctr>1.0) {
1192 img->decayCorrFactor[frame_index]=image_header.decay_corr_fctr;
1194 } else {
1195 img->decayCorrFactor[frame_index]=0.0;
1197 }
1198 } else if(img->type==IMG_TYPE_POLARMAP) { /* polarmap */
1199 img->start[frame_index]=polmap_header.frame_start_time/1000.;
1200 img->end[frame_index]=
1201 img->start[frame_index]+polmap_header.frame_duration/1000.;
1202 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1203 } else if(img->dimz>1) {
1204 img->start[frame_index]=scan_header.frame_start_time/1000.;
1205 img->end[frame_index]=
1206 img->start[frame_index]+scan_header.frame_duration/1000.;
1207 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1208 /* also, correct for dead-time */
1209 if(scan_header.deadtime_correction_factor>0.0) {
1210 fptr=fdata;
1211 for(long long i=0; i<img->dimz*pxlNr; i++, fptr++)
1212 *fptr*=scan_header.deadtime_correction_factor;
1213 }
1214 img->prompts[frame_index]=(float)scan_header.prompts;
1215 img->randoms[frame_index]=scan_header.delayed;
1216 } else {
1217 img->start[frame_index]=scan2d_header.frame_start_time/1000.;
1218 img->end[frame_index]=
1219 img->start[frame_index]+scan2d_header.frame_duration/1000.;
1220 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
1221 /* also, correct for dead-time */
1222 if(scan2d_header.deadtime_correction_factor>0.0) {
1223 fptr=fdata;
1224 for(long long i=0; i<pxlNr; i++, fptr++)
1225 *fptr*=scan2d_header.deadtime_correction_factor;
1226 }
1227 img->prompts[frame_index]=(float)scan2d_header.prompts;
1228 img->randoms[frame_index]=scan2d_header.delayed;
1229 }
1230 /* Copy matrix data through volume planes */
1231 if(img->_fileFormat!=IMG_E7_2D) {
1232 /* if(img->dimz>1) { */
1233 for(int pi=0; pi<img->dimz; pi++) {
1234 if(IMG_TEST>5)
1235 printf(" putting data into m[%d][][][%d]\n", pi, frame_index);
1236 fptr=fdata+pi*pxlNr;
1237 for(int yi=0; yi<img->dimy; yi++)
1238 for(int xi=0; xi<img->dimx; xi++)
1239 img->m[pi][yi][xi][frame_index]= *fptr++;
1240 }
1241 } else {
1242 if(IMG_TEST>5)
1243 printf(" putting data into m[%d][][][%d]\n", seqplane, frame_index);
1244 fptr=fdata;
1245 for(int yi=0; yi<img->dimy; yi++)
1246 for(int xi=0; xi<img->dimx; xi++)
1247 img->m[seqplane][yi][xi][frame_index]= *fptr++;
1248 img->planeNumber[seqplane]=plane;
1249 }
1250 free(fdata);
1251 /* Calibrate */
1252 if(main_header.ecat_calibration_factor>0.0)
1253 for(int pi=0; pi<img->dimz; pi++)
1254 for(int yi=0; yi<img->dimy; yi++) for(int xi=0; xi<img->dimx; xi++)
1255 img->m[pi][yi][xi][frame_index]*=main_header.ecat_calibration_factor;
1256 } /* next matrix */
1257 if(IMG_TEST>3) printf("end of matrices.\n");
1258 ecat7EmptyMatlist(&mlist);
1259 fclose(fp);
1260
1261 /* seqplane is <0 only if this frame did not exist at all; return -1 */
1262 if(IMG_TEST>4) printf("last_seqplane := %d.\n", seqplane);
1263 if(seqplane<0) return STATUS_NOMATRIX;
1264
1265 /* check that correct number of planes was read */
1266 if(seqplane>0 && (seqplane+1 != img->dimz)) return STATUS_MISSINGMATRIX;
1267
1268 /* All went well */
1269 imgSetStatus(img, STATUS_OK);
1270 return STATUS_OK;
1271}
void ecat7SortMatlistByFrame(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:303
int ecat7GatherMatlist(ECAT7_MATRIXLIST *ml, short int do_planes, short int do_frames, short int do_gates, short int do_beds)
Definition ecat7ml.c:535

Referenced by imgReadEcat7FirstFrame(), and imgReadFrame().

◆ imgReadEcat7Header()

int imgReadEcat7Header ( const char * fname,
IMG * img )
extern

Fill IMG struct header information from an image or sinogram file in ECAT 7 format. Information concerning separate frames or planes is not filled.

Parameters
fnameimage or sinogram filename
imgpointer to initialized IMG structure
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 860 of file img_e7.c.

860 {
861 FILE *fp;
862 int ret, m;
863 int planeNr, frameNr, blkNr=0;
864 ECAT7_mainheader main_header;
865 ECAT7_imageheader image_header;
866 ECAT7_2Dscanheader scan2d_header;
867 ECAT7_scanheader scan_header;
868 ECAT7_polmapheader polmap_header;
869 ECAT7_MATRIXLIST mlist;
870
871
872 if(IMG_TEST) printf("\nimgReadEcat7Header(%s, *img)\n", fname);
873
874 /* Check the arguments */
875 if(img==NULL) return STATUS_FAULT;
876 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
877 imgSetStatus(img, STATUS_FAULT);
878 if(fname==NULL) return STATUS_FAULT;
879
880 /* Open the file */
881 if((fp=fopen(fname, "rb")) == NULL) return STATUS_NOFILE;
882
883 /* Read main header */
884 ret=ecat7ReadMainheader(fp, &main_header);
885 if(ret) {fclose(fp); return STATUS_NOMAINHEADER;}
886 /* Check for magic number */
887 if(strncmp(main_header.magic_number, ECAT7V_MAGICNR, 7)!=0) {
888 fclose(fp); return STATUS_UNKNOWNFORMAT;}
889 /* Check if file_type is supported */
890 if(imgEcat7Supported(&main_header)==0) {fclose(fp); return STATUS_UNSUPPORTED;}
891 /* Copy main header information into IMG; sets also img.type */
892 imgGetEcat7MHeader(img, &main_header);
893 if(IMG_TEST>7) printf("img.type := %d\n", img->type);
894 img->_fileFormat=imgGetEcat7Fileformat(&main_header);
895 if(IMG_TEST>7) printf("img._fileFormat := %d\n", img->_fileFormat);
896 if(img->_fileFormat==IMG_UNKNOWN) {fclose(fp); return STATUS_UNSUPPORTED;}
897
898 /* Read matrix list */
899 ecat7InitMatlist(&mlist);
900 ret=ecat7ReadMatlist(fp, &mlist, IMG_TEST-1);
901 if(ret || mlist.matrixNr<1 || ecat7CheckMatlist(&mlist)) {
902 fclose(fp); return STATUS_INVALIDMATLIST;}
903 /* Make sure that plane and frame numbers are continuous */
904 ecat7GatherMatlist(&mlist, 1, 1, 1, 1);
905 /* Get plane and frame numbers and check that volume is full */
906 ret=ecat7GetPlaneAndFrameNr(&mlist, &main_header, &planeNr, &frameNr);
907 if(ret) {ecat7EmptyMatlist(&mlist); fclose(fp); return ret;}
908 img->dimz=planeNr;
909 img->dimt=frameNr;
910 /* Get and check the size of data matrices */
911 ret=ecat7GetMatrixBlockSize(&mlist, &blkNr);
912 if(ret) {ecat7EmptyMatlist(&mlist); fclose(fp); return ret;}
913
914 /* Read one subheader */
915 if(IMG_TEST>5) printf("main_header.file_type := %d\n", main_header.file_type);
916 m=0;
917 switch(main_header.file_type) {
918 case ECAT7_IMAGE8:
919 case ECAT7_IMAGE16:
920 case ECAT7_VOLUME8:
921 case ECAT7_VOLUME16:
922 ret=ecat7ReadImageheader(fp, mlist.matdir[m].strtblk, &image_header);
923 break;
924 case ECAT7_2DSCAN:
925 ret=ecat7Read2DScanheader(fp, mlist.matdir[m].strtblk, &scan2d_header);
926 break;
927 case ECAT7_3DSCAN:
928 case ECAT7_3DSCAN8:
929 case ECAT7_3DSCANFIT:
930 ret=ecat7ReadScanheader(fp, mlist.matdir[m].strtblk, &scan_header);
931 break;
932 case ECAT7_POLARMAP:
933 ret=ecat7ReadPolmapheader(fp, mlist.matdir[m].strtblk, &polmap_header);
934 break;
935 default: ret=-1;
936 }
937 /* Free locally allocated memory and close the file */
938 ecat7EmptyMatlist(&mlist); fclose(fp);
939 /* Check whether subheader was read */
940 if(ret) return STATUS_NOSUBHEADER;
941
942 /* Get the following information in the subheader:
943 dimensions x, y and z; datatype;
944 image decay correction on/off, zoom, pixel size and resolution;
945 sinogram sample distance; matrix transformation parameters.
946 */
947 switch(main_header.file_type) {
948 case ECAT7_IMAGE8:
949 case ECAT7_IMAGE16:
950 case ECAT7_VOLUME8:
951 case ECAT7_VOLUME16:
952 img->dimx=image_header.x_dimension; img->dimy=image_header.y_dimension;
953 if(image_header.num_dimensions>2 && image_header.z_dimension>1)
954 /*planeNr=*/ img->dimz=image_header.z_dimension;
955 img->_dataType=image_header.data_type;
956 if(image_header.decay_corr_fctr>1.0) img->decayCorrection=IMG_DC_CORRECTED;
957 img->zoom=image_header.recon_zoom;
958 img->sizex=10.*image_header.x_pixel_size;
959 img->sizey=10.*image_header.y_pixel_size;
960 img->sizez=10.*image_header.z_pixel_size;
961 img->resolutionx=10.*image_header.x_resolution;
962 img->resolutiony=10.*image_header.y_resolution;
963 img->resolutionz=10.*image_header.z_resolution;
966 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
967 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
968 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
969 img->mt[0]=image_header.mt_1_1;
970 img->mt[1]=image_header.mt_1_2;
971 img->mt[2]=image_header.mt_1_3;
972 img->mt[3]=image_header.mt_1_4;
973 img->mt[4]=image_header.mt_2_1;
974 img->mt[5]=image_header.mt_2_2;
975 img->mt[6]=image_header.mt_2_3;
976 img->mt[7]=image_header.mt_2_4;
977 img->mt[8]=image_header.mt_3_1;
978 img->mt[9]=image_header.mt_3_2;
979 img->mt[10]=image_header.mt_3_3;
980 img->mt[11]=image_header.mt_3_4;
981 break;
982 case ECAT7_2DSCAN:
983 img->dimx=scan2d_header.num_r_elements;
984 img->dimy=scan2d_header.num_angles;
985 if(scan2d_header.num_dimensions>2 && scan2d_header.num_z_elements>1)
986 planeNr=img->dimz=scan2d_header.num_z_elements;
987 img->_dataType=scan2d_header.data_type;
988 if(scan2d_header.x_resolution>0.0)
989 img->sampleDistance=10.0*scan2d_header.x_resolution;
990 else
991 img->sampleDistance=10.0*main_header.bin_size;
992 break;
993 case ECAT7_3DSCAN:
994 case ECAT7_3DSCAN8:
995 case ECAT7_3DSCANFIT:
996 img->dimx=scan_header.num_r_elements; img->dimy=scan_header.num_angles;
997 for(int i=img->dimz=0; i<64; i++) img->dimz+=scan_header.num_z_elements[i];
998 /* planeNr=img->dimz; */
999 img->_dataType=scan_header.data_type;
1000 if(scan_header.x_resolution>0.0)
1001 img->sampleDistance=10.0*scan_header.x_resolution;
1002 else
1003 img->sampleDistance=10.0*main_header.bin_size;
1004 break;
1005 case ECAT7_POLARMAP:
1006 img->dimy=img->dimz=1;
1007 img->polarmap_num_rings=polmap_header.num_rings;
1009 return STATUS_INVALIDPOLARMAP;
1010 for(int i=0; i<img->polarmap_num_rings; i++) {
1011 img->polarmap_sectors_per_ring[i]=polmap_header.sectors_per_ring[i];
1012 img->polarmap_ring_position[i]=polmap_header.ring_position[i];
1013 img->polarmap_ring_angle[i]=polmap_header.ring_angle[i];
1014 }
1015 img->polarmap_start_angle=polmap_header.start_angle;
1016 img->dimx=0;
1017 for(int i=0; i<img->polarmap_num_rings; i++)
1018 img->dimx+=img->polarmap_sectors_per_ring[i];
1019 /* pixel_size actually contains volume, in cubic cm */
1020 img->sizex=img->sizey=img->sizez=0.001*polmap_header.pixel_size;
1021 break;
1022 }
1023
1024 imgSetStatus(img, STATUS_OK);
1025 return STATUS_OK;
1026}
int ecat7GetPlaneAndFrameNr(ECAT7_MATRIXLIST *mlist, ECAT7_mainheader *h, int *plane_nr, int *frame_nr)
Definition ecat7ml.c:372
int ecat7GetMatrixBlockSize(ECAT7_MATRIXLIST *mlist, int *blk_nr)
Definition ecat7ml.c:418
int imgGetEcat7Fileformat(ECAT7_mainheader *h)
Definition img_e7.c:827

Referenced by imgFormatDetermine(), imgReadEcat7FirstFrame(), imgReadHeader(), and imgWriteEcat7Frame().

◆ imgReadFrame()

int imgReadFrame ( const char * fname,
int frame_to_read,
IMG * img,
int frame_index )
extern

Read one time frame from a supported PET image or sinogram file into IMG data structure.

This functions can be called repeatedly to read all the frames one at a time to conserve memory.

See also
imgRead, imgReadHeader, imgWriteFrame
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error. Specifically, return value STATUS_NOMATRIX signals that frame does not exist, i.e. all frames have been read. IMG.statmsg can be set using ERROR_STATUS.
Parameters
fnameName of file from which IMG contents will be read. Currently supported file formats are ECAT 6.3 images and sinograms, ECAT 7.x 2D and 3D images and sinograms, and NIfTI-1, Analyze 7.5, and microPET 3D and 4D images.
frame_to_readFrame which will be read [1..frameNr].
imgPointer to initiated or occupied IMG data. If occupied, then new frame is tested to match the previous file type, dimensions, and other fundamental information contained in the IMG. If not occupied, then memory is allocated here.
frame_indexIMG frame index (0..dimt-1) where data will be placed. If index is >0, then the memory for that frame must be allocated before calling this function.

Definition at line 269 of file imgfile.c.

285 {
286 IMG test_img;
287 int ret=0;
288
289 if(IMG_TEST) {
290 printf("\nimgReadFrame(%s, %d, *img, %d)\n", fname, frame_to_read, frame_index);
291 fflush(stdout);
292 }
293 /*
294 * Check the input
295 */
296 if(fname==NULL) return STATUS_FAULT;
297 if(img==NULL) return STATUS_FAULT;
298 if(img->status!=IMG_STATUS_INITIALIZED && img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
299 if(frame_to_read<1) return STATUS_FAULT;
300 if(frame_index<0) return STATUS_FAULT;
301 /* if frame_index>0, then there must be sufficient memory allocated for it */
302 if(frame_index>0) {
303 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
304 if(frame_index>img->dimt-1) return STATUS_FAULT;
305 }
306
307 /*
308 * If IMG is preallocated, check that fundamental header information
309 * is compatible with old and new contents.
310 * If not allocated, then read the header contents, and allocate it
311 */
312 imgInit(&test_img);
313 if(img->status==IMG_STATUS_OCCUPIED) {
314 ret=imgReadHeader(fname, &test_img, img->_fileFormat);
315 imgSetStatus(&test_img, ret);
316 if(IMG_TEST>1) printf("imgReadHeader() return message := %s\n", test_img.statmsg);
317 if(ret) return(ret);
318 if(IMG_TEST>3) imgInfo(&test_img);
319 /* Test that file format and type are the same */
320 ret=0;
321 if(img->type!=test_img.type) ret++;
322 if(img->_fileFormat!=test_img._fileFormat) ret++;
323 /* Test that x, y, and z dimensions are the same */
324 if(img->dimx!=test_img.dimx) ret++;
325 if(img->dimy!=test_img.dimy) ret++;
326 if(img->dimz!=test_img.dimz) ret++;
327 imgEmpty(&test_img); if(ret>0) return STATUS_INVALIDHEADER;
328 } else {
329 ret=imgReadHeader(fname, img, IMG_UNKNOWN);
330 imgSetStatus(img, ret);
331 if(IMG_TEST>1) printf("imgReadHeader() return message := %s\n", img->statmsg);
332 if(ret) return(ret);
333 if(IMG_TEST>3) imgInfo(img);
334 /* Allocate memory for one frame */
335 img->dimt=1;
336 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
337 if(ret) return STATUS_NOMEMORY;
338 }
339
340 /*
341 * Read the frame data and corresponding information like frame time
342 * if available
343 */
344 switch(img->_fileFormat) {
345 case IMG_E7:
346 case IMG_E7_2D:
347 case IMG_POLARMAP:
348 ret=imgReadEcat7Frame(fname, frame_to_read, img, frame_index);
349 if(IMG_TEST>1) printf("imgReadEcat7Frame() return value := %d\n", ret);
350 break;
351 case IMG_E63:
352 ret=imgReadEcat63Frame(fname, frame_to_read, img, frame_index);
353 if(IMG_TEST>1) printf("imgReadEcat63Frame() return value := %d\n", ret);
354 break;
355 case IMG_ANA:
356 case IMG_ANA_L:
357 ret=imgReadAnalyzeFrame(fname, frame_to_read, img, frame_index);
358 if(IMG_TEST>1) printf("imgReadAnalyzeFrame() return value := %d\n", ret);
359 break;
360 case IMG_NIFTI_1S:
361 case IMG_NIFTI_1D:
362 ret=imgReadNiftiFrame(fname, frame_to_read, img, frame_index, IMG_TEST-2);
363 if(IMG_TEST>1) printf("imgReadNiftiFrame() return value := %d\n", ret);
364 break;
365 case IMG_MICROPET:
366 ret=imgReadMicropetFrame(fname, frame_to_read, img, frame_index);
367 if(IMG_TEST>1) printf("imgReadAnalyzeFrame() return value := %d\n", ret);
368 break;
369 default:
370 ret=STATUS_UNSUPPORTED;
371 }
372 imgSetStatus(img, ret);
373 return ret;
374}
int imgReadNiftiFrame(const char *filename, int frame_to_read, IMG *img, int frame_index, int verbose)
Definition img_nii.c:311
int imgReadMicropetFrame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition img_upet.c:819
int imgReadHeader(const char *fname, IMG *img, int format)
Definition imgfile.c:199

Referenced by imgReadMinMax().

◆ imgReadHeader()

int imgReadHeader ( const char * fname,
IMG * img,
int format )
extern

Fill IMG struct header information from an image or sinogram file in ECAT 6.3, ECAT 7.x or Analyze 7.5 format.

Information concerning separate frames or planes is not filled.

See also
imgInit, imgEmpty, imgReadFrame
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fnameImage or sinogram file name
imgPointer to initialized but not allocated IMG structure.
formatImage file format, if known (IMG_E63, IMG_E7, ...); if not known, set to IMG_UNKNOWN or 0.

Definition at line 199 of file imgfile.c.

207 {
208 int ret;
209
210 if(IMG_TEST) {
211 printf("\nimgReadHeader(%s, *img, %d)\n", fname, format);
212 fflush(stdout);
213 }
214
215 /* Check the arguments */
216 if(fname==NULL) return STATUS_FAULT;
217 if(img==NULL) return STATUS_FAULT;
218 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
219
220 /* If user did not know the file format, then try to decide it */
221 if(format==IMG_UNKNOWN) {
222 int scanner, imgtype, modality;
223 ret=imgFormatDetermine(fname, NULL, NULL, NULL, NULL,
224 &format, &scanner, &imgtype, &modality, IMG_TEST-3);
225 if(ret!=0) {
226 imgSetStatus(img, ret);
227 return(ret);
228 }
229 if(format==IMG_UNKNOWN) {
230 imgSetStatus(img, STATUS_UNSUPPORTED);
231 return(STATUS_UNSUPPORTED);
232 }
233 }
234
235 /* Read the header for the file format */
236 ret=STATUS_UNSUPPORTED;
237 if(format==IMG_ANA || format==IMG_ANA_L) {
238 /* Read Analyze header information */
239 ret=imgReadAnalyzeHeader(fname, img);
240 } else if(format==IMG_NIFTI_1S || format==IMG_NIFTI_1D) {
241 /* Read NIfTI image header information */
242 ret=imgReadNiftiHeader(fname, img, IMG_TEST-2);
243 } else if(format==IMG_MICROPET) {
244 /* Read microPET header information */
245 ret=imgReadMicropetHeader(fname, img);
246 } else if(format==IMG_E7 || format==IMG_E7_2D) {
247 ret=imgReadEcat7Header(fname, img);
248 } else if(format==IMG_E63 || format==IMG_POLARMAP) {
249 ret=imgReadEcat63Header(fname, img);
250 }
251 imgSetStatus(img, ret);
252 return(ret);
253}
int imgReadNiftiHeader(const char *filename, IMG *img, int verbose)
Definition img_nii.c:134
int imgFormatDetermine(const char *fname, char *basename, char *hdrfile, char *imgfile, char *siffile, int *file_format, int *scanner, int *type, int *modality, int verbose)
Definition imgfile.c:536

Referenced by imgReadFrame().

◆ imgReadMicropet()

int imgReadMicropet ( const char * fname,
IMG * img )
extern

Read the whole dynamic microPET image into IMG data structure.

Note that microPET images are often too large for 32-bit systems.

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fnameName of microPET image (hdr or img file, or without extension) from which IMG contents will be read.
imgPointer to the initiated but not preallocated IMG data.

Definition at line 971 of file img_upet.c.

977 {
978 int fi=0, ret=0;
979
980 if(IMG_TEST) printf("\n%s(%s, *img)\n", __func__, fname);
981 /* Check the input */
982 if(img==NULL) return STATUS_FAULT;
983 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
984 imgSetStatus(img, STATUS_FAULT);
985 if(fname==NULL) return STATUS_FAULT;
986
987 /* Read the first frame into IMG struct */
988 fi=0;
989 if(IMG_TEST>2) printf("reading frame %d\n", fi+1);
990 ret=imgReadMicropetFirstFrame(fname, img);
991 if(ret!=STATUS_OK) {
992 if(IMG_TEST>0) printf("imgReadMicropetFirstFrame() := %s\n", img->statmsg);
993 imgEmpty(img); return ret;
994 }
995 /* Read rest of the frames */
996 do {
997 fi++;
998 if(IMG_TEST>2) printf("reading frame %d\n", fi+1);
999 ret=imgReadMicropetFrame(fname, fi+1, img, fi);
1000 } while(ret==0);
1001 if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
1002 if(IMG_TEST>0) printf("imgReadMicropetFrame() := %s\n", img->statmsg);
1003 imgEmpty(img); return ret;
1004 }
1005 if(IMG_TEST>1) printf("%d frame(s) were read.\n", fi);
1006
1007 /* All went well */
1008 imgSetStatus(img, STATUS_OK);
1009 return STATUS_OK;
1010}
int imgReadMicropetFirstFrame(const char *fname, IMG *img)
Definition img_upet.c:925

Referenced by imgRead().

◆ imgReadMicropetFirstFrame()

int imgReadMicropetFirstFrame ( const char * fname,
IMG * img )
extern

Read the first frame from a microPET image into IMG data structure.

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fnameName of microPET image (hdr or img file, or without extension) from which IMG contents will be read.
imgPointer to the initiated but not preallocated IMG data.

Definition at line 925 of file img_upet.c.

931 {
932 int ret=0;
933
934 if(IMG_TEST) printf("\n%s(%s, *img)\n", __func__, fname);
935 /* Check the input */
936 if(img==NULL) return STATUS_FAULT;
937 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
938 imgSetStatus(img, STATUS_FAULT);
939 if(fname==NULL) return STATUS_FAULT;
940
941 /* Read header information from file */
942 ret=imgReadMicropetHeader(fname, img);
943 if(IMG_TEST>1) printf("imgReadMicropetHeader() := %s\n", img->statmsg);
944 if(ret) return(ret);
945 if(IMG_TEST>3) imgInfo(img);
946
947 /* Allocate memory for one frame */
948 img->dimt=1;
949 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
950 if(ret) return STATUS_NOMEMORY;
951
952 /* Read the first frame */
953 ret=imgReadMicropetFrame(fname, 1, img, 0);
954 if(IMG_TEST>1) printf("imgReadMicropetFrame() := %s\n", img->statmsg);
955 if(ret) return(ret);
956
957 /* All went well */
958 imgSetStatus(img, STATUS_OK);
959 return STATUS_OK;
960}

Referenced by imgReadMicropet().

◆ imgReadMicropetFrame()

int imgReadMicropetFrame ( const char * fname,
int frame_to_read,
IMG * img,
int frame_index )
extern

Read a specified frame from microPET image into preallocated IMG data structure.

MicroPET image consists of two files in the same directory: fname.hdr and fname.img. IMG header is assumed to be filled correctly before calling this function, except for information concerning separate planes and this frame, which is filled here. If frame does not exist, then and only then STATUS_NOMATRIX is returned.

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fnameName of microPET image (hdr or img file, or without extension) from which IMG contents will be read.
frame_to_readFrame which will be read [1..frameNr].
imgPointer to the IMG data. Place for the frame must be preallocated.
frame_indexIMG frame index [0..dimt-1] where data will be placed.

Definition at line 819 of file img_upet.c.

829 {
830 FILE *fp;
831 int i, fi, ret, zi, xi, yi;
832 float *fdata=NULL, *fptr, f;
833 char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX];
835
836
837 if(IMG_TEST) printf("\n%s(%s, %d, *img, %d)\n", __func__, fname, frame_to_read, frame_index);
838
839 /* Check the input */
840 if(img==NULL) return STATUS_FAULT;
841 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
842 if(fname==NULL) return STATUS_FAULT;
843 if(frame_index<0 || frame_index>img->dimt-1) return STATUS_FAULT;
844 if(frame_to_read<1) return STATUS_FAULT;
845 imgSetStatus(img, STATUS_FAULT);
846
847 /* Determine the names of hdr and data files */
848 ret=upetExists(fname, hdrfile, datfile, IMG_TEST-1);
849 if(ret<2) {imgSetStatus(img, STATUS_NOFILE); return STATUS_NOFILE;}
850
851 /* Read microPET header file into IFT, if not available already */
852 imgSetStatus(img, STATUS_INVALIDHEADER);
853 if(img->ift.keyNr<10) {
854 iftEmpty(&img->ift);
855 ret=defRead(&img->ift, hdrfile, 0);
856 if(ret!=0) {
857 if(IMG_TEST>1) printf("defRead() return value := %d\n", ret);
858 return(STATUS_INVALIDHEADER);
859 }
860 if(IMG_TEST>3) printf("ift.keyNr := %d\n", img->ift.keyNr);
861 }
862
863 /* Read frame header information */
864 strcpy(key, "frame"); sprintf(value, "%d", frame_to_read-1);
865 fi=iftGetFullmatchFrom(&img->ift, 0, key, value, 0);
866 if(fi<0) {imgSetStatus(img, STATUS_NOMATRIX); return STATUS_NOMATRIX;}
867 i=iftGetFloatValue(&img->ift, fi+1, "frame_start", &f, 0);
868 if(i<0 || isnan(f)) {return STATUS_INVALIDHEADER;}
869 img->start[frame_index]=f;
870 i=iftGetFloatValue(&img->ift, fi+1, "frame_duration", &f, 0);
871 if(i<0 || isnan(f) || f<0.0) {return STATUS_INVALIDHEADER;}
872 img->end[frame_index]=img->start[frame_index]+f;
873 img->mid[frame_index]=0.5*(img->end[frame_index]+img->start[frame_index]);
874 /* decay correction */
875 i=iftGetFloatValue(&img->ift, fi+1, "decay_correction", &f, 0);
876 if(i<0 || isnan(f) || f<0.0) {return STATUS_INVALIDHEADER;}
877 img->decayCorrFactor[frame_index]=f;
878 //printf(" decayCorrFactor=%g\n", img->decayCorrFactor[0]);
879 /* set plane numbers */
880 for(zi=0; zi<img->dimz; zi++) img->planeNumber[zi]=zi+1;
881 /* prompts and randoms (delays), without checking the result */
882 i=iftGetFloatValue(&img->ift, fi+1, "prompts_rate", &img->prompts[frame_index], 0);
883 i=iftGetFloatValue(&img->ift, fi+1, "delays_rate", &img->randoms[frame_index], 0);
884
885 /* Open image datafile */
886 if(IMG_TEST>2) fprintf(stdout, "reading image data %s\n", datfile);
887 if((fp=fopen(datfile, "rb"))==NULL) {
888 imgSetStatus(img, STATUS_NOIMGDATA); return STATUS_NOIMGDATA;}
889
890 /* Allocate memory for one image frame */
891 fdata=malloc((size_t)img->dimx*img->dimy*img->dimz*sizeof(float));
892 if(fdata==NULL) {
893 fclose(fp); imgSetStatus(img, STATUS_NOMEMORY);
894 return STATUS_NOMEMORY;
895 }
896
897 /* Read the required image frame */
898 fptr=fdata;
899 ret=upetReadImagedata(fp, &img->ift, frame_to_read, fptr);
900 if(ret!=0 && IMG_TEST) fprintf(stdout, "upetReadImagedata() := %d\n", ret);
901 fclose(fp);
902 if(ret==3) { /* no more frames */
903 free(fdata); imgSetStatus(img, STATUS_NOMATRIX); return STATUS_NOMATRIX;}
904 if(ret!=0) {
905 free(fdata); imgSetStatus(img, STATUS_UNSUPPORTED); return STATUS_UNSUPPORTED;}
906
907 /* Copy pixel values to IMG */
908 fptr=fdata;
909 for(zi=0; zi<img->dimz; zi++)
910 for(yi=0; yi<img->dimy; yi++)
911 for(xi=0; xi<img->dimx; xi++)
912 img->m[zi][yi][xi][frame_index]=*fptr++;
913 free(fdata);
914
915 imgSetStatus(img, STATUS_OK); /* If the rest is failed, no problem */
916 return STATUS_OK;
917}
int defRead(IFT *ift, char *filename, int verbose)
Definition iftfile.c:321
int iftGetFullmatchFrom(IFT *ift, int si, const char *key, const char *value, int verbose)
Definition iftsrch.c:191
int upetReadImagedata(FILE *fp, IFT *ift, int frame, float *data)
Definition micropet.c:243

Referenced by imgReadFrame(), imgReadMicropet(), and imgReadMicropetFirstFrame().

◆ imgReadMicropetHeader()

int imgReadMicropetHeader ( const char * dbname,
IMG * img )
extern

Fill IMG struct header information from microPET database files.

Information concerning separate frames or planes is not filled though.

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
dbnameName of microPET database, may contain filename extension
imgPointer to the initiated IMG data

Definition at line 767 of file img_upet.c.

772 {
773 char hdrfile[FILENAME_MAX];
774 int ret;
775
776 if(IMG_TEST) printf("\n%s(%s, *img)\n", __func__, dbname);
777
778 /* Check the input */
779 if(img==NULL) return STATUS_FAULT;
780 if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
781 imgSetStatus(img, STATUS_FAULT);
782 if(dbname==NULL) return STATUS_FAULT;
783
784 /* Determine the names of hdr and sif files */
785 ret=upetExists(dbname, hdrfile, NULL, IMG_TEST-1);
786 if(ret==0) return STATUS_NOFILE;
787
788 /* Read microPET header file into IFT */
789 iftEmpty(&img->ift);
790 ret=defRead(&img->ift, hdrfile, 0);
791 if(ret!=0) {
792 if(IMG_TEST>1) printf("defRead() return value := %d\n", ret);
793 return(STATUS_FAULT);
794 }
795 /* and set IMG contents */
796 ret=imgGetMicropetHeader(img);
797 if(ret!=0) {
798 imgSetStatus(img, ret);
799 return(ret);
800 }
801
802 return STATUS_OK;
803}
int imgGetMicropetHeader(IMG *img)
Definition img_upet.c:583

Referenced by imgFormatDetermine(), imgReadHeader(), and imgReadMicropetFirstFrame().

◆ imgReadMinMax()

int imgReadMinMax ( const char * fname,
float * fmin,
float * fmax )
extern

Read the calibrated maximum and minimum pixel values in the specified file in ECAT 7, ECAT 6.3, or Analyze 7.5 format.

File is read frame-by-frame with normal IMG functions.

See also
imgFrameMinMax, imgRangeMinMax, imgMinMax
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fnameECAT 7 or ECAT 6.3 filename, or Analyze 7.5 database.
fminPointer to minimum pixel value that will be set by this function.
fmaxPointer to maximum pixel value that will be set by this function.

Definition at line 211 of file imgminmax.c.

218 {
219 int fi=0, ret;
220 IMG img;
221 float frmin, frmax;
222
223 if(IMG_TEST) printf("imgReadMinMax(%s, *fmin, *fmax)\n", fname);
224 imgInit(&img);
225 while((ret=imgReadFrame(fname, fi+1, &img, 0)) == 0) {
226 if(imgMinMax(&img, &frmin, &frmax)!=0) {imgEmpty(&img); return STATUS_FAULT;}
227 if(fi==0) {
228 if(fmin!=NULL) *fmin=frmin;
229 if(fmin!=NULL) *fmax=frmax;
230 } else {
231 if(fmin!=NULL && !(*fmin<=frmin)) *fmin=frmin;
232 if(fmax!=NULL && !(*fmax>=frmax)) *fmax=frmax;
233 }
234 fi++;
235 } /* next frame */
236 imgEmpty(&img);
237 if(ret==STATUS_NOMATRIX && fi>0) return STATUS_OK;
238 else return ret;
239}
int imgReadFrame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition imgfile.c:269
int imgMinMax(IMG *img, float *minvalue, float *maxvalue)
Definition imgminmax.c:154

◆ imgReadNifti()

int imgReadNifti ( const char * filename,
IMG * img,
int verbose )
extern

Read Nifti-1 image.

Nifti database name must be given with path. Either one file with extension .nii, or image and header files with extensions .img and .hdr must exist. Also SIF file with .sif extension is used, if it exists.

Returns
0 if ok, and otherwise IMG status code (<>0); sets IMG->statmsg in case of an error.
See also
imgInit, imgReadNiftiFirstFrame, imgReadNiftiHeader, imgWriteNifti
Parameters
filenameNifti database name with path, with or without extension
imgPointer to initialized IMG structure
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 23 of file img_nii.c.

30 {
31 if(verbose>0) {printf("imgReadNifti(%s, ...)\n", filename); fflush(stdout);}
32
33 /* Check the arguments */
34 if(img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
35 if(img!=NULL) imgSetStatus(img, STATUS_FAULT);
36 if(verbose>0) fprintf(stderr, "Error: invalid IMG argument\n");
37 return(STATUS_FAULT);
38 }
39 if(filename==NULL || !filename[0]) {
40 imgSetStatus(img, STATUS_FAULT);
41 if(verbose>0) fprintf(stderr, "Error: invalid filename\n");
42 return(STATUS_FAULT);
43 }
44 imgSetStatus(img, STATUS_OK);
45
46 /* Read header information from file */
47 int ret=imgReadNiftiHeader(filename, img, verbose-1); if(ret) {return(ret);}
48 if(verbose>10) imgInfo(img);
49
50 /* Allocate memory for all frames */
51 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
52 if(ret) {
53 imgSetStatus(img, STATUS_OK);
54 return STATUS_NOMEMORY;
55 }
56
57 /* Read one frame at a time */
58 for(int fi=0; fi<img->dimt; fi++) {
59 ret=imgReadNiftiFrame(filename, 1+fi, img, fi, verbose-1);
60 if(ret) return(ret);
61 }
62
63 /* All went well */
64 imgSetStatus(img, STATUS_OK);
65 return(STATUS_OK);
66}

Referenced by imgRead().

◆ imgReadNiftiFirstFrame()

int imgReadNiftiFirstFrame ( const char * filename,
IMG * img,
int verbose )
extern

Read the first frame of Nifti-1 image into IMG data structure.

Nifti database name must be given with path. Either one file with extension .nii, or image and header files with extensions .img and .hdr must exist. Also SIF file with .sif extension is used, if it exists.

Returns
0 if ok, and otherwise IMG status code (<>0); sets IMG->statmsg in case of an error.
Parameters
filenameNifti database name with path, with or without extension
imgPointer to initialized IMG structure
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 78 of file img_nii.c.

85 {
86 if(verbose>0) {printf("imgReadNiftiFirstFrame(%s, ...)\n", filename); fflush(stdout);}
87
88 /* Check the arguments */
89 if(img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
90 if(img!=NULL) imgSetStatus(img, STATUS_FAULT);
91 if(verbose>0) fprintf(stderr, "Error: invalid IMG argument\n");
92 return(STATUS_FAULT);
93 }
94 if(filename==NULL || !filename[0]) {
95 imgSetStatus(img, STATUS_FAULT);
96 if(verbose>0) fprintf(stderr, "Error: invalid filename\n");
97 return(STATUS_FAULT);
98 }
99 imgSetStatus(img, STATUS_OK);
100
101 /* Read header information from file */
102 int ret=imgReadNiftiHeader(filename, img, verbose-1); if(ret) {return(ret);}
103 if(verbose>10) imgInfo(img);
104
105 /* Allocate memory for one frame */
106 img->dimt=1;
107 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt);
108 if(ret) {
109 imgSetStatus(img, STATUS_OK);
110 return STATUS_NOMEMORY;
111 }
112
113 /* Read the first frame */
114 ret=imgReadNiftiFrame(filename, 1, img, 0, verbose-1); if(ret) return(ret);
115
116 /* All went well */
117 imgSetStatus(img, STATUS_OK);
118 return(STATUS_OK);
119}

Referenced by imgNiftiToEcat().

◆ imgReadNiftiFrame()

int imgReadNiftiFrame ( const char * filename,
int frame_to_read,
IMG * img,
int frame_index,
int verbose )
extern

Read a specified frame from a Nifti database files into preallocated IMG data structure.

IMG header is assumed to be filled correctly before calling this function, except for information concerning separate planes and this frame, which is filled here.

Returns
0 if ok, and otherwise IMG status code (<>0); sets IMG->statmsg in case of an error. If frame does not exist, then and only then STATUS_NOMATRIX is returned.
See also
imgReadNifti, imgNaNs
Parameters
filenamePointer to string that contains the name of NIfTI database with path, with or without filename extension. Either one file with extension .nii, or image and header files with extensions .img and .hdr must exist. Also SIF file with .sif extension is used, if it exists; however, information concerning separate frames or planes is not filled.
frame_to_readFrame which will be read from database [1..frameNr]
imgPointer to the IMG data. Place for the frame must be preallocated
frame_indexIMG frame index [0..dimt-1] where data will be placed
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 311 of file img_nii.c.

327 {
328 char basefile[FILENAME_MAX], tmp[256];
329 char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
330 NIFTI_DSR dsr;
331 int ret;
332 SIF sif;
333 FILE *fp;
334 float *fdata=NULL, *fptr;
335
336
337 if(verbose>0) {
338 printf("\nimgReadNiftiFrame(%s, %d, *img, %d, %d)\n",
339 filename, frame_to_read, frame_index, verbose);
340 fflush(stdout);
341 }
342
343 /* Check the input */
344 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
345 if(img!=NULL) imgSetStatus(img, STATUS_FAULT);
346 if(verbose>0) fprintf(stderr, "Error: invalid IMG argument\n");
347 return(STATUS_FAULT);
348 }
349 if(filename==NULL || !filename[0]) {
350 imgSetStatus(img, STATUS_FAULT);
351 if(verbose>0) fprintf(stderr, "Error: invalid filename\n");
352 return(STATUS_FAULT);
353 }
354 if(frame_index<0 || frame_index>img->dimt-1 || frame_to_read<1) {
355 imgSetStatus(img, STATUS_FAULT);
356 if(verbose>0) fprintf(stderr, "Error: invalid frame settings\n");
357 return STATUS_FAULT;
358 }
359
360 /* Extract the base file name without extensions */
361 strcpy(basefile, filename); niftiRemoveFNameExtension(basefile);
362 if(strlen(basefile)<1) {
363 imgSetStatus(img, STATUS_FAULT);
364 if(verbose>0) fprintf(stderr, "Error: invalid filename\n");
365 return(STATUS_FAULT);
366 }
367
368 /* Make the image and header filenames, and read Nifti header */
369 ret=niftiExists(basefile, hdrfile, datfile, siffile, &dsr, verbose-2, tmp);
370 if(ret==0) {
371 imgSetStatus(img, STATUS_NOFILE);
372 if(verbose>0) fprintf(stderr, "Error: %s\n", tmp);
373 return(STATUS_NOFILE);
374 }
375 if(ret==1 && verbose>1) {
376 printf("no SIF found for %s\n", basefile); fflush(stdout);}
377
378 /* Open image datafile */
379 if(verbose>2) {fprintf(stdout, "reading image data %s\n", datfile); fflush(stdout);}
380 if((fp=fopen(datfile, "rb")) == NULL) {
381 imgSetStatus(img, STATUS_NOIMGDATAFILE);
382 return STATUS_NOIMGDATAFILE;
383 }
384
385 /* Allocate memory for one image frame */
386 imgSetStatus(img, STATUS_NOMEMORY);
387 fdata=calloc((size_t)img->dimx*img->dimy*img->dimz, sizeof(float));
388 if(fdata==NULL) {fclose(fp); return STATUS_NOMEMORY;}
389
390 /* Read the required image frame */
391 fptr=fdata;
392 ret=niftiReadImagedata(fp, &dsr, frame_to_read, fptr, verbose-1, tmp);
393 if(verbose>1) printf("niftiReadImagedata() -> %s\n", tmp);
394 fclose(fp);
395 if(ret==-1) { /* no more frames */
396 free(fdata); imgSetStatus(img, STATUS_NOMATRIX);
397 return STATUS_NOMATRIX;
398 }
399 if(ret!=0) {
400 free(fdata); imgSetStatus(img, STATUS_UNSUPPORTED);
401 return STATUS_UNSUPPORTED;
402 }
403
404 if(0) { // Call imgNaNs(IMG, 1) instead
405 /* Check for invalid pixel values and set to zero.
406 SPM can write lots of NaNs on image borders.
407 Remove this later, if/when all image processing functions support NaN and Inf. */
408 long long int goodNr=0;
409 fptr=fdata;
410 for(int zi=0; zi<img->dimz; zi++)
411 for(int yi=0; yi<img->dimy; yi++)
412 for(int xi=0; xi<img->dimx; xi++) {
413 if(isfinite(*fptr)) goodNr++; else *fptr=0.0;
414 fptr++;
415 }
416 if(goodNr==0) {
417 free(fdata);
418 imgSetStatus(img, STATUS_NOIMGDATA);
419 return STATUS_NOIMGDATA;
420 }
421 }
422
423 /* Copy pixel values to IMG */
424 fptr=fdata;
425 for(int zi=0; zi<img->dimz; zi++)
426 for(int yi=0; yi<img->dimy; yi++)
427 for(int xi=0; xi<img->dimx; xi++)
428 img->m[zi][yi][xi][frame_index]=*fptr++;
429 free(fdata);
430
431 /* Set decay correction factor to zero */
432 img->decayCorrFactor[frame_index]=0.0;
433
434 /* Set plane numbers */
435 for(int fi=0; fi<img->dimz; fi++) img->planeNumber[fi]=fi+1;
436
437 /*
438 * Try to read frame time information from SIF file
439 */
440 imgSetStatus(img, STATUS_OK); /* If the rest is failed, no problem */
441 sifInit(&sif);
442 if(sifRead(siffile, &sif)!=0) {
443 if(verbose>1) {fprintf(stdout, " cannot read SIF (%s)\n", siffile); fflush(stdout);}
444 return STATUS_OK;
445 }
446 /* Frame information */
447 if(verbose>3) {fprintf(stdout, " setting frame times\n"); fflush(stdout);}
448 if(sif.frameNr>=frame_to_read) {
449 img->start[frame_index]=sif.x1[frame_to_read-1];
450 img->end[frame_index]=sif.x2[frame_to_read-1];
451 img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
452 img->prompts[frame_index]=sif.prompts[frame_to_read-1];
453 img->randoms[frame_index]=sif.randoms[frame_to_read-1];
454 }
455 sifEmpty(&sif);
456
457 imgSetStatus(img, STATUS_OK);
458 return STATUS_OK;
459}
void niftiRemoveFNameExtension(char *fname)
Definition nifti.c:23
int niftiReadImagedata(FILE *fp, NIFTI_DSR *h, int frame, float *data, int verbose, char *status)
Definition nifti.c:619

Referenced by imgNiftiToEcat(), imgReadFrame(), imgReadNifti(), and imgReadNiftiFirstFrame().

◆ imgReadNiftiHeader()

int imgReadNiftiHeader ( const char * filename,
IMG * img,
int verbose )
extern

Fill IMG struct header information from Nifti database files.

Nifti database name must be given with path. Either one file with extension .nii, or image and header files with extensions .img and .hdr must exist. Also SIF file with .sif extension is used, if it exists; however, information concerning separate frames or planes is not filled.

Returns
0 if ok, and otherwise IMG status code (<>0); sets IMG->statmsg in case of an error.
See also
imgGetNiftiHeader
Parameters
filenameNifti database name with path, with or without extension
imgPointer to initialized IMG structure
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 134 of file img_nii.c.

141 {
142 char basefile[FILENAME_MAX], tmp[256];
143 char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
144 NIFTI_DSR dsr;
145 int ret;
146 SIF sif;
147 double f;
148
149 if(verbose>0) {printf("imgReadNiftiHeader(%s, ...)\n", filename); fflush(stdout);}
150
151 /* Check the arguments */
152 if(img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
153 if(img!=NULL) imgSetStatus(img, STATUS_FAULT);
154 if(verbose>0) fprintf(stderr, "Error: invalid IMG argument\n");
155 return(STATUS_FAULT);
156 }
157 if(filename==NULL || !filename[0]) {
158 imgSetStatus(img, STATUS_FAULT);
159 if(verbose>0) fprintf(stderr, "Error: invalid filename\n");
160 return(STATUS_FAULT);
161 }
162 imgSetStatus(img, STATUS_OK);
163
164 /* Extract the base file name without extensions */
165 strcpy(basefile, filename); niftiRemoveFNameExtension(basefile);
166 if(strlen(basefile)<1) {
167 imgSetStatus(img, STATUS_FAULT);
168 if(verbose>0) fprintf(stderr, "Error: invalid filename\n");
169 return(STATUS_FAULT);
170 }
171
172 /* Make the image and header filenames, and read Nifti header */
173 ret=niftiExists(basefile, hdrfile, datfile, siffile, &dsr, verbose-2, tmp);
174 if(ret==0) {
175 imgSetStatus(img, STATUS_NOFILE);
176 if(verbose>0) fprintf(stderr, "Error: %s\n", tmp);
177 return(STATUS_NOFILE);
178 }
179 if(ret==1 && verbose>1) printf("no SIF found for %s\n", basefile);
180
181 /* and set IMG contents */
182 ret=imgGetNiftiHeader(img, &dsr, verbose-2);
183 if(ret!=0) {
184 imgSetStatus(img, ret);
185 return(ret);
186 }
187
188 /* If SIF does not exist, then that's it */
189 if(!siffile[0]) {
190 imgSetStatus(img, STATUS_OK);
191 return STATUS_OK;
192 }
193
194 /* SIF is available, so read that too */
195 if(verbose>1) {printf("reading SIF %s\n", siffile); fflush(stdout);}
196 sifInit(&sif); ret=0;
197 if(sifRead(siffile, &sif)!=0) return STATUS_OK;
198 /* Copy scan time */
199 img->scanStart=sif.scantime;
200 /* Study number, if not yet defined */
201 if(!img->studyNr[0] && strlen(sif.studynr)>1 )
203 /* Isotope half-life, if not yet defined */
205 if(img->isotopeHalflife<=0.0 && f>0.0) img->isotopeHalflife=60.0*f;
206 sifEmpty(&sif);
207
208 return(STATUS_OK);
209}

Referenced by imgReadHeader(), imgReadNifti(), and imgReadNiftiFirstFrame().

◆ imgSetAnalyzeHeader()

int imgSetAnalyzeHeader ( IMG * img,
const char * dbname,
ANALYZE_DSR * dsr,
float fmin,
float fmax )
extern

Copy header information in IMG struct into Analyze 7.5 header struct.

Min, max, and scale factor are set here and they apply to all frames.

Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
imgpointer to IMG struct from which header information is read
dbnameAnalyze 7.5 database name
dsrpointer to Analyze header struct to be filled
fminminimum pixel value in all frames that will be written
fmaxmaximum pixel value in all frames that will be written

Definition at line 486 of file img_ana.c.

497 {
498 struct tm tm; //*st;
499 char *cptr;
500 float g;
501
502 if(IMG_TEST) printf("\nimgSetAnalyzeHeader(*img, %s, *dsr, %g, %g)\n",
503 dbname, fmin, fmax);
504
505 /* Check the input */
506 if(img==NULL) return STATUS_FAULT;
508 return STATUS_FAULT;
509 imgSetStatus(img, STATUS_FAULT);
510 if(dsr==NULL) return STATUS_FAULT;
511
512 /* Byte order */
513 if(img->_fileFormat==IMG_ANA_L) dsr->little=1; else dsr->little=0;
514 /* Header key */
515 memset(&dsr->hk, 0, sizeof(ANALYZE_HEADER_KEY));
516 memset(&dsr->dime, 0, sizeof(ANALYZE_HEADER_IMGDIM));
517 memset(&dsr->hist, 0, sizeof(ANALYZE_HEADER_HISTORY));
518 dsr->hk.sizeof_hdr=348;
519 strcpy(dsr->hk.data_type, "");
520 cptr=strrchr(dbname, '/'); if(cptr==NULL) cptr=strrchr(dbname, '\\');
521 if(cptr!=NULL) cptr++;
522 if(cptr==NULL) cptr=(char*)dbname;
523 strncpy(dsr->hk.db_name, cptr, 17);
524 dsr->hk.extents=16384;
525 dsr->hk.regular='r';
526 /* Image dimension */
527 dsr->dime.dim[0]=4;
528 dsr->dime.dim[1]=img->dimx;
529 dsr->dime.dim[2]=img->dimy;
530 dsr->dime.dim[3]=img->dimz;
531 dsr->dime.dim[4]=img->dimt;
533 dsr->dime.bitpix=16;
534 dsr->dime.pixdim[0]=0.0;
535 dsr->dime.pixdim[1]=img->sizex;
536 dsr->dime.pixdim[2]=img->sizey;
537 dsr->dime.pixdim[3]=img->sizez;
538 dsr->dime.pixdim[4]=0.0;
539 dsr->dime.funused1=0.0; /* Scale factor is set later */
540 /* dsr.dime.funused2=img->zoom; */ /* Reconstruction zoom */
541 dsr->dime.funused3=img->isotopeHalflife;
542 /* Data history */
544 strcpy(dsr->hist.descrip, "Decay corrected.");
546 strcpy(dsr->hist.descrip, "No decay correction.");
547 else
548 strcpy(dsr->hist.descrip, "");
549 if(strlen(img->studyNr)>0 && strcmp(img->studyNr, ".")!=0)
550 memcpy(dsr->hist.scannum, img->studyNr, 10);
551 else
552 strcpy(img->studyNr, "");
553 gmtime_r((time_t*)&img->scanStart, &tm);
554 if(!strftime(dsr->hist.exp_date, 10, "%Y%m%d", &tm))
555 strcpy(dsr->hist.exp_date, "19000101");
556 if(!strftime(dsr->hist.exp_time, 10, "%H:%M:%S", &tm))
557 strncpy(dsr->hist.exp_time, "00:00:00", 10);
558
559 /* Determine and set scale factor and cal_min & cal_max */
560 if(fmin<fmax) {
561 dsr->dime.cal_min=fmin; dsr->dime.cal_max=fmax;
562 } else { /* not given in function call, try to find those here */
563 if(img->status==IMG_STATUS_OCCUPIED &&
564 imgMinMax(img, &dsr->dime.cal_min, &dsr->dime.cal_max)==0) {}
565 else return STATUS_FAULT;
566 }
567 if(fabs(dsr->dime.cal_min) > fabs(dsr->dime.cal_max)) g=fabs(dsr->dime.cal_min);
568 else g = fabs(dsr->dime.cal_max);
569 /* if(fabs(dsr->dime.cal_min)>fabs(dsr->dime.cal_max))
570 g=fabs(dsr->dime.cal_min); */
571 /* else g=fabs(dsr->dime.cal_max); */
572 if(g<1E-20) g=1.0; else g=32767./g; dsr->dime.funused1=1.0/g;
573 /* Set header glmin & glmax */
574 dsr->dime.glmin=temp_roundf(fmin*g); dsr->dime.glmax=temp_roundf(fmax*g);
575 /* printf("glmin=%d\n", dsr->dime.glmin); */
576 /* printf("glmax=%d\n", dsr->dime.glmax); */
577
578 imgSetStatus(img, STATUS_OK);
579 return STATUS_OK;
580}

Referenced by imgWriteAnalyzeFrame().

◆ imgSetDecayCorrFactors()

int imgSetDecayCorrFactors ( IMG * image,
int mode )
extern

Sets (mode=1) or removes (mode=0) decay correction factors in IMG. IMG pixel data is not changed.

Returns
0 if ok, 1 image status is not 'occupied', 2 invalid exponent value, 3 image frame times are missing.
See also
imgDecayCorrection, imgBranchingCorrection, imgIsotope
Parameters
imagePointer to IMG data.
modeFactors are calculated for decay correction (1) or for removing decay correction (0).

Definition at line 87 of file imgdecayc.c.

92 {
93 float lambda, cf, dur;
94
95 /* Check for arguments */
96 if(image->status!=IMG_STATUS_OCCUPIED) return(1);
97 if(image->isotopeHalflife<=0.0) return(1);
98
99 /* Check that image contains frame times */
100 if(mode!=0 && image->end[image->dimt-1]<=0.0) return(3);
101
102 /* All time frames */
103 for(int fi=0; fi<image->dimt; fi++) {
104 if(mode==0) {
105 image->decayCorrFactor[fi]=1.0;
106 } else {
107 dur=image->end[fi]-image->start[fi];
108 if(image->end[fi]>0.0) {
109 lambda=hl2lambda(image->isotopeHalflife); if(lambda<0.0) return(2);
110 cf=hlLambda2factor_float(lambda, image->start[fi], dur);
111 image->decayCorrFactor[fi]=cf;
112 }
113 }
114 } /* next frame */
115 if(mode==0) image->decayCorrection=IMG_DC_NONCORRECTED;
117 return(0);
118}

◆ imgSetEcat63MHeader()

void imgSetEcat63MHeader ( IMG * img,
ECAT63_mainheader * h )
extern

Copy information from IMG struct into ECAT 6.3 main header

Parameters
imgsource image structure
htarget Ecat 6.3 main header

Definition at line 1223 of file img_e63.c.

1224{
1225 struct tm tm;
1226 memset(&tm, 0, sizeof(struct tm));
1227
1228 if(IMG_TEST>0) printf("imgSetEcat63MHeader()\n");
1229 if(IMG_TEST>2) {
1230 char buf[32];
1231 if(!ctime_r_int(&img->scanStart, buf)) strcpy(buf, "1900-01-01 00:00:00");
1232 fprintf(stdout, " scan_start_time := %s\n", buf);
1233 }
1234 h->sw_version=2;
1235 h->num_planes=img->dimz;
1236 h->num_frames=img->dimt;
1237 h->num_gates=1;
1238 h->num_bed_pos=1;
1240 else h->file_type=RAW_DATA;
1241 h->data_type=VAX_I2;
1242 if(img->scanner>0) h->system_type=img->scanner;
1244 h->calibration_factor=1.0;
1245 h->axial_fov=img->axialFOV/10.0;
1246 h->transaxial_fov=img->transaxialFOV/10.0;
1247 h->plane_separation=img->sizez/10.0;
1249 strncpy(h->radiopharmaceutical, img->radiopharmaceutical, 32);
1250 if(gmtime_r(&img->scanStart, &tm)!=NULL) {
1251 h->scan_start_year=tm.tm_year+1900;
1252 h->scan_start_month=tm.tm_mon+1;
1253 h->scan_start_day=tm.tm_mday;
1254 h->scan_start_hour=tm.tm_hour;
1255 h->scan_start_minute=tm.tm_min;
1256 h->scan_start_second=tm.tm_sec;
1257 if(IMG_TEST>2) {
1258 printf(" img->scanStart := %ld\n", (long int)img->scanStart);
1259 printf(" -> tm_year := %d\n", tm.tm_year);
1260 printf(" -> tm_hour := %d\n", tm.tm_hour);
1261 }
1262 } else {
1263 h->scan_start_year=1900;
1264 h->scan_start_month=1;
1265 h->scan_start_day=1;
1266 h->scan_start_hour=0;
1267 h->scan_start_minute=0;
1268 h->scan_start_second=0;
1269 if(IMG_TEST>0) printf("invalid scan_start_time in IMG\n");
1270 }
1272 strcpy(h->isotope_code, imgIsotope(img));
1273 strlcpy(h->study_name, img->studyNr, 12);
1274 strcpy(h->patient_name, img->patientName);
1275 strcpy(h->patient_id, img->patientID);
1278}

Referenced by imgWriteEcat63Frame().

◆ imgSetEcat63SHeader()

void imgSetEcat63SHeader ( IMG * img,
void * h )
extern

Copies Ecat6.3 image or scan sub header information from IMG struct.

Parameters
imgsource image structure
htarget sub header structure

Definition at line 1872 of file img_e63.c.

1872 {
1873 ECAT63_imageheader *image_header;
1874 ECAT63_scanheader *scan_header;
1875
1876 if(img->type==IMG_TYPE_RAW) {
1877 scan_header=(ECAT63_scanheader*)h;
1878 scan_header->data_type=VAX_I2;
1879 scan_header->dimension_1=img->dimx;
1880 scan_header->dimension_2=img->dimy;
1881 scan_header->frame_duration_sec=1;
1882 scan_header->scale_factor=1.0;
1883 scan_header->frame_start_time=0;
1884 scan_header->frame_duration=1000;
1885 scan_header->loss_correction_fctr=1.0;
1886 scan_header->sample_distance=img->sampleDistance/10.0;
1887 } else {
1888 image_header=(ECAT63_imageheader*)h;
1889 image_header->data_type=VAX_I2;
1890 image_header->num_dimensions=2;
1891 image_header->dimension_1=img->dimx;
1892 image_header->dimension_2=img->dimy;
1893 image_header->recon_scale=img->zoom;
1894 image_header->quant_scale=1.0;
1895 image_header->slice_width=img->sizez/10.;
1896 image_header->pixel_size=img->sizex/10.;
1897 image_header->frame_start_time=0;
1898 image_header->frame_duration=1000;
1899 image_header->plane_eff_corr_fctr=1.0; // now we don't know which plane
1900 image_header->decay_corr_fctr=1.0;
1901 image_header->loss_corr_fctr=1.0;
1902 image_header->ecat_calibration_fctr=1.0;
1903 image_header->well_counter_cal_fctr=1.0;
1904 image_header->quant_units=imgUnitToEcat6(img);
1905 }
1906}

Referenced by imgWriteEcat63Frame().

◆ imgSetEcat7MHeader()

void imgSetEcat7MHeader ( IMG * img,
ECAT7_mainheader * h )
extern

Copy information from IMG to ECAT 7 main header

Parameters
imgsource structure
htarget structure

Definition at line 781 of file img_e7.c.

782{
783 h->sw_version=72;
784 if(img->type==IMG_TYPE_POLARMAP) {
785 strcpy(h->magic_number, ECAT7V_MAGICNR);
787 } else if(img->type==IMG_TYPE_RAW) {
788 strcpy(h->magic_number, ECAT7S_MAGICNR);
790 else h->file_type=ECAT7_3DSCAN;
791 } else {
792 strcpy(h->magic_number, ECAT7V_MAGICNR);
795 }
796 h->system_type=img->scanner;
799 imgUnitToEcat7(img, h);
801 h->transaxial_fov=img->transaxialFOV/10.0;
802 h->num_planes=img->dimz; /* h->num_planes=1; */
803 h->num_frames=img->dimt;
804 h->num_gates=1;
805 h->num_bed_pos=0;
806 h->distance_scanned=img->axialFOV/10.0;
807 h->plane_separation=img->sizez/10.0;
808 strncpy(h->radiopharmaceutical, img->radiopharmaceutical, 32);
809 strcpy(h->isotope_name, imgIsotope(img));
810 strlcpy(h->study_type, img->studyNr, 12);
811 strcpy(h->patient_name, img->patientName);
812 strcpy(h->patient_id, img->patientID);
814 strcpy(h->study_description, img->studyDescription);
817}
void imgUnitToEcat7(IMG *img, ECAT7_mainheader *h)
Definition imgunits.c:209

Referenced by imgWrite2DEcat7(), imgWriteEcat7(), imgWriteEcat7Frame(), and imgWritePolarmap().

◆ imgSetEcat7SHeader()

void imgSetEcat7SHeader ( IMG * img,
void * h )
extern

Set ECAT7 subheader based on IMG contents

Parameters
imgimage structure
hEcat7 image, scan, 2D scan or polar map header

Definition at line 1482 of file img_e7.c.

1482 {
1483 ECAT7_imageheader *image_header;
1484 ECAT7_scanheader *scan_header;
1485 ECAT7_2Dscanheader *scan2d_header;
1486 ECAT7_polmapheader *polmap_header;
1487
1488 if(img->type==IMG_TYPE_POLARMAP) {
1489 polmap_header=(ECAT7_polmapheader*)h;
1490 polmap_header->data_type=ECAT7_SUNI2;
1491 polmap_header->num_rings=img->polarmap_num_rings;
1492 if(polmap_header->num_rings>32) polmap_header->num_rings=32;
1493 for(int i=0; i<polmap_header->num_rings; i++) {
1494 polmap_header->sectors_per_ring[i]=img->polarmap_sectors_per_ring[i];
1495 polmap_header->ring_position[i]=img->polarmap_ring_position[i];
1496 polmap_header->ring_angle[i]=img->polarmap_ring_angle[i];
1497 }
1498 polmap_header->start_angle=258;
1499 polmap_header->pixel_size=1000.0*img->sizex;
1500 polmap_header->quant_units=0; /* default, see main header */
1501 } else if(img->type==IMG_TYPE_RAW) {
1502 if(img->_fileFormat==IMG_E7_2D) {
1503 scan2d_header=(ECAT7_2Dscanheader*)h;
1504 scan2d_header->num_dimensions=2;
1505 scan2d_header->num_z_elements=1;
1506 scan2d_header->data_type=ECAT7_SUNI2;
1507 scan2d_header->num_r_elements=img->dimx;
1508 scan2d_header->num_angles=img->dimy;
1509 } else {
1510 scan_header=(ECAT7_scanheader*)h;
1511 scan_header->x_resolution=img->sampleDistance/10.0;
1512 scan_header->num_dimensions=4;
1513 if(img->dimz==239) {
1514 scan_header->num_z_elements[0]=63;
1515 scan_header->num_z_elements[1]=106;
1516 scan_header->num_z_elements[2]=70;
1517 } else {
1518 scan_header->num_z_elements[0]=img->dimz;
1519 }
1520 scan_header->storage_order=1;
1521 scan_header->data_type=ECAT7_SUNI2;
1522 scan_header->num_r_elements=img->dimx;
1523 scan_header->num_angles=img->dimy;
1524 }
1525 } else {
1526 image_header=(ECAT7_imageheader*)h;
1527 image_header->data_type=ECAT7_SUNI2;
1528 image_header->x_dimension=img->dimx;
1529 image_header->y_dimension=img->dimy;
1530 image_header->recon_zoom=img->zoom;
1531 image_header->x_pixel_size=0.1*img->sizex;
1532 image_header->y_pixel_size=0.1*img->sizey;
1533 image_header->z_pixel_size=0.1*img->sizez;
1534 image_header->x_resolution=0.1*img->resolutionx;
1535 image_header->y_resolution=0.1*img->resolutiony;
1536 image_header->z_resolution=0.1*img->resolutionz;
1537 image_header->mt_1_1=img->mt[0];
1538 image_header->mt_1_2=img->mt[1];
1539 image_header->mt_1_3=img->mt[2];
1540 image_header->mt_1_4=img->mt[3];
1541 image_header->mt_2_1=img->mt[4];
1542 image_header->mt_2_2=img->mt[5];
1543 image_header->mt_2_3=img->mt[6];
1544 image_header->mt_2_4=img->mt[7];
1545 image_header->mt_3_1=img->mt[8];
1546 image_header->mt_3_2=img->mt[9];
1547 image_header->mt_3_3=img->mt[10];
1548 image_header->mt_3_4=img->mt[11];
1549 if(img->_fileFormat==IMG_E7_2D) {
1550 image_header->num_dimensions=2;
1551 image_header->z_dimension=1;
1552 } else {
1553 image_header->num_dimensions=3;
1554 image_header->z_dimension=img->dimz;
1555 }
1556 for(int i=0; i<49; i++) image_header->fill_user[i]=0;
1557 }
1558}

Referenced by imgWriteEcat7Frame(), and imgWritePolarmap().

◆ imgSetNiftiHeader()

int imgSetNiftiHeader ( IMG * img,
const char * dbname,
NIFTI_DSR * dsr,
float fmin,
float fmax,
int verbose )
extern

Copy header information in IMG structure into NIfTI header structure.

Min, max, and scale factor are set here and they apply to all frames.

Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
See also
imgGetNiftiHeader, imgReadNiftiHeader
Parameters
imgpointer to IMG structure from which header information is read
dbnameNIfTI database name
dsrpointer to NIfTI header struct to be filled
fminminimum pixel value in all frames that will be written
fmaxmaximum pixel value in all frames that will be written
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 471 of file img_nii.c.

484 {
485 if(verbose>0) {
486 printf("\nimgSetNiftiHeader(*img, %s, *dsr, %g, %g, ...)\n", dbname, fmin, fmax);
487 fflush(stdout);
488 }
489 /* Check the input */
490 if(dbname==NULL || !dbname[0]) {
491 if(verbose>0) fprintf(stderr, "Error: invalid filename\n");
492 return(STATUS_FAULT);
493 }
494 if(img==NULL || (img->status!=IMG_STATUS_INITIALIZED && img->status!=IMG_STATUS_OCCUPIED)) {
495 if(verbose>0) fprintf(stderr, "Error: invalid IMG argument\n");
496 return(STATUS_FAULT);
497 }
498 if(dsr==NULL) {
499 if(verbose>0) fprintf(stderr, "Error: invalid header struct\n");
500 return STATUS_FAULT;
501 }
502
503 /* Set NIfTI byte order to current machines byte order */
505
506 /* Initiate header struct with zeroes */
507 memset(&dsr->h, 0, sizeof(NIFTI_1_HEADER));
508 memset(&dsr->e, 0, sizeof(NIFTI_EXTENDER));
509
510 /* Set header */
512 strcpy(dsr->h.data_type, "");
513 char *cptr=strrchr(dbname, '/'); if(cptr==NULL) cptr=strrchr(dbname, '\\');
514 if(cptr!=NULL) cptr++;
515 if(cptr==NULL) cptr=(char*)dbname;
516 strncpy(dsr->h.db_name, cptr, 17);
517 dsr->h.extents=16384; // not used in NIfTI, but required for Analyze compatibility
518 dsr->h.regular='r'; // not used in NIfTI, but required for Analyze compatibility
519 dsr->h.dim_info='\0'; // MRI slice ordering
520
521 /* Image dimension */
522 for(int i=0; i<8; i++) dsr->h.dim[i]=1;
523 dsr->h.dim[0]=4;
524 dsr->h.dim[1]=img->dimx;
525 dsr->h.dim[2]=img->dimy;
526 dsr->h.dim[3]=img->dimz;
527 dsr->h.dim[4]=img->dimt;
528 dsr->h.intent_p1=0.0;
529 dsr->h.intent_p2=0.0;
530 dsr->h.intent_p3=0.0;
532 dsr->h.datatype=NIFTI_DT_FLOAT; // data as floats, so no need to scale
533 dsr->h.bitpix=32;
534 dsr->h.slice_start=0;
535 for(int i=0; i<8; i++) dsr->h.pixdim[i]=0.0;
536 // https://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/qsform.html
537 dsr->h.pixdim[0]=1.0; // Set to either 1.0 or -1.0
538 dsr->h.pixdim[1]=img->sizex;
539 dsr->h.pixdim[2]=img->sizey;
540 dsr->h.pixdim[3]=img->sizez;
541 if(img->_fileFormat==IMG_NIFTI_1D)
542 dsr->h.vox_offset=0;
543 else
544 dsr->h.vox_offset=352;
545 dsr->h.scl_slope=1.0; // data as floats, so no need to scale
546 dsr->h.scl_inter=0.0; // data as floats, so no need to scale
547 dsr->h.slice_end=0;
548 dsr->h.slice_code=0;
550 dsr->h.cal_max=fmax;
551 dsr->h.cal_min=0.0; // scale display colours to have black at zero
552 dsr->h.slice_duration=0.0;
553 dsr->h.toffset=0.0;
554 dsr->h.glmax=fmax; // unused in NIfTI
555 dsr->h.glmin=fmin; // unused in NIfTI
556
557 strlcpy(dsr->h.descrip, img->studyNr, 80);
558 strcpy(dsr->h.aux_file, "");
559
560 dsr->h.qform_code=img->xform[0];
561 dsr->h.sform_code=img->xform[1];
562 dsr->h.quatern_b=img->quatern[0];
563 dsr->h.quatern_c=img->quatern[1];
564 dsr->h.quatern_d=img->quatern[2];
565 dsr->h.qoffset_x=img->quatern[3];
566 dsr->h.qoffset_y=img->quatern[4];
567 dsr->h.qoffset_z=img->quatern[5];
568 for(int i=0; i<4; i++) dsr->h.srow_x[i]=img->quatern[6+i];
569 for(int i=0; i<4; i++) dsr->h.srow_y[i]=img->quatern[10+i];
570 for(int i=0; i<4; i++) dsr->h.srow_z[i]=img->quatern[14+i];
571 strcpy(dsr->h.intent_name, "");
572
573 if(img->_fileFormat==IMG_NIFTI_1D) strcpy(dsr->h.magic, "ni1");
574 else strcpy(dsr->h.magic, "n+1");
575
576 /* Extension is left as 0 0 0 0 */
577
578 return STATUS_OK;
579}
#define NIFTI_DT_FLOAT
#define NIFTI_HEADER_SIZE
#define NIFTI_INTENT_NONE
#define NIFTI_UNITS_SEC
short int slice_start
short int slice_end
short int datatype
char aux_file[24]
char intent_name[16]
short int bitpix
char data_type[10]
short int intent_code
NIFTI_EXTENDER e

Referenced by imgWriteNiftiFrame().

◆ imgSetStatus()

void imgSetStatus ( IMG * img,
int status_index )
extern

◆ imgSetUnit()

int imgSetUnit ( IMG * img,
char * unit )
extern

Sets the unit in IMG based on specified unit string.

See also
imgUnitId, imgUnitFromEcat, imgUnitFromEcat7
Returns
Returns 0 if successful.

Definition at line 328 of file imgunits.c.

329{
330 int new_unit;
331
332 if(img==NULL || unit==NULL) return(1);
333 new_unit=imgUnitId(unit); if(new_unit<0) return(1-new_unit);
334 img->unit=new_unit;
335 return(0);
336}
int imgUnitId(char *unit)
Definition imgunits.c:14

◆ imgSmoothMax()

int imgSmoothMax ( IMG * img,
float * maxvalue,
IMG_PIXEL * p )
extern

Searches the spatially (3x3) smoothed max pixel value in the IMG data.

See also
imgFrameMinMax, imgMinMax, imgMax, imgAbsMax, imgGetPeak
Returns
0 if ok, 1 invalid image status, 2 invalid output pointer, 3 invalid image dimensions.
Parameters
imgPointer to IMG struct
maxvaluePointer to float in which max pixel value will be written; enter NULL if not needed
pPointer to struct in which the position of max pixel will be written (1-based positions); enter NULL if not needed

Definition at line 248 of file imgminmax.c.

257 {
258 int pi, yi, xi, fi;
259 float f, v;
260
261 if(img->status<IMG_STATUS_OCCUPIED) return(1);
262 if(maxvalue==NULL && p==NULL) return(2);
263 if(img->dimt<1 || img->dimz<1 || img->dimy<3 || img->dimx<3) return(3);
264 if(maxvalue!=NULL) *maxvalue=0.0;
265 if(p!=NULL) p->x=p->y=p->z=p->f=1;
266 f=-1.0E20;
267 for(pi=0; pi<img->dimz; pi++)
268 for(yi=1; yi<img->dimy-1; yi++)
269 for(xi=1; xi<img->dimx-1; xi++)
270 for(fi=0; fi<img->dimt; fi++) {
271 v=img->m[pi][yi-1][xi-1][fi]+
272 img->m[pi][yi-1][xi ][fi]+
273 img->m[pi][yi-1][xi+1][fi]+
274 img->m[pi][yi ][xi-1][fi]+
275 img->m[pi][yi ][xi ][fi]*2.0+
276 img->m[pi][yi ][xi+1][fi]+
277 img->m[pi][yi+1][xi-1][fi]+
278 img->m[pi][yi+1][xi ][fi]+
279 img->m[pi][yi+1][xi+1][fi];
280 v*=0.1;
281 if(v>f) {
282 f=v; if(p!=NULL) {p->x=xi+1; p->y=yi+1; p->z=pi+1; p->f=fi+1;}}
283 }
284 if(maxvalue!=NULL) *maxvalue=f;
285 return(0);
286}

◆ imgSS()

int imgSS ( IMG * img1,
IMG * img2,
double * ss )
extern

Calculates the sum-of-squares between pixels values of two images.

Precondition
Make sure that image pixel values are in the same units.
Returns
Returns <>0 in case of an error.
See also
imgMatchMatrix, imgMatchHeader, imgMaxDifference, imgConvertUnit
Parameters
img1Pointer to the first IMG data.
img2Pointer to the second IMG data.
ssPointer to the double variable to write the SS into.

Definition at line 412 of file imgcomp.c.

419 {
420 if(ss!=NULL) *ss=0.0;
421 if(img1==NULL || img2==NULL) return(1);
422 if(img1->dimz!=img2->dimz) return(2);
423 if(img1->dimy!=img2->dimy) return(3);
424 if(img1->dimx!=img2->dimx) return(4);
425 if(img1->dimt!=img2->dimt) return(5);
426
427 double sumsqr=0.0;
428 for(int z=0; z<img1->dimz; z++)
429 for(int y=0; y<img1->dimy; y++)
430 for(int x=0; x<img1->dimx; x++)
431 for(int i=0; i<img1->dimt; i++) {
432 double d=img1->m[z][y][x][i]-img2->m[z][y][x][i];
433 sumsqr+=d*d;
434 }
435 if(ss!=NULL) *ss=sumsqr;
436
437 return(0);
438}

◆ imgStatus()

char * imgStatus ( int status_index)
extern

Return pointer to string describing the image error status message

Parameters
status_indexindex of img_status_string
Returns
pointer to string

Definition at line 330 of file img.c.

330 {
331 int n=0;
332 while(imgmsg[n]!=0) n++;
333 if(status_index<0 || status_index>n-1) return((char*)imgmsg[STATUS_FAULT]);
334 else return((char*)imgmsg[status_index]);
335}

Referenced by ecatFixMatrixlist(), imgRead(), and imgWriteNifti().

◆ imgUnit()

char * imgUnit ( int dunit)
extern

Return pointer to string describing the calibrated image data unit

Returns
Pointer to string
Parameters
dunitUnit id number.

Definition at line 315 of file imgunits.c.

318 {
319 return(petCunit(dunit));
320}
char * petCunit(int cunit)
Definition petunits.c:211

Referenced by clusterTACs(), cunit_check_dft_vs_img(), dftAllocateWithIMG(), imgInfo(), and sif2dft().

◆ imgUnitFromEcat()

void imgUnitFromEcat ( IMG * img,
int ecat_unit )
extern

Set IMG calibration unit based on ECAT 6.3 unit.

See also
imgUnitFromEcat7, imgUnitId, imgUnitToEcat6, imgSetUnit
Parameters
imgPointer to target IMG structure.
ecat_unitCalibration unit code id.

Definition at line 95 of file imgunits.c.

100 {
101 switch(ecat_unit) {
102 case 0: /* Unknown */
103 img->unit=CUNIT_UNKNOWN; break;
104 case 1: /* MBq/mL */
105 img->unit=CUNIT_MBQ_PER_ML; break;
106 case 2: /* ECAT counts */
107 img->unit=CUNIT_COUNTS; break;
108 case 3: /* uCi/ml */
109 img->unit=CUNIT_UCI_PER_ML; break;
110 case 4: /* LMRGlu */
111 img->unit=CUNIT_UNKNOWN; break;
112 case 5: /* LMRUGlu umol/min/100g */
113 img->unit=CUNIT_UMOL_PER_MIN_PER_100G; break;
114 case 6: /* LMRUGlu mg/min/100g */
115 img->unit=CUNIT_MG_PER_MIN_PER_100G; break;
116 case 7: /* nCi/mL */
117 img->unit=CUNIT_NCI_PER_ML; break;
118 case 8: /* Well counts */
119 img->unit=CUNIT_CPS; break;
120 case 9: /* Bq/mL */
121 img->unit=CUNIT_BQ_PER_ML; break;
122 case 10: /* kBq/mL */
123 img->unit=CUNIT_KBQ_PER_ML; break;
124 case 11: /* 1/min */
125 img->unit=CUNIT_PER_MIN; break;
126 case 12: /* mL/min/100g */
127 img->unit=CUNIT_ML_PER_DL_PER_MIN; break;
128 case 13: /* sec*kBq/mL */
129 img->unit=CUNIT_SEC_KBQ_PER_ML; break;
130 case 14: /* sec*nCi/mL */
131 img->unit=CUNIT_UNKNOWN; break;
132 case 15: /* 1/sec */
133 img->unit=CUNIT_PER_SEC; break;
134 case 16: /* Unitless */
135 img->unit=CUNIT_UNITLESS; break;
136 case 17: /* Hounsfield Unit */
137 img->unit=CUNIT_HU; break;
138 case 18: /* Unknown */
139 default:
140 img->unit=CUNIT_UNKNOWN; break;
141 }
142}

Referenced by ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), imgGetEcat63MHeader(), and imgReadEcat63Header().

◆ imgUnitFromEcat7()

void imgUnitFromEcat7 ( IMG * img,
ECAT7_mainheader * h )
extern

Set IMG calibration unit based on ECAT7 main header.

See also
imgUnitFromEcat, imgUnitId, imgUnitToEcat7, imgSetUnit
Parameters
imgPointer to target IMG structure.
hPointer to source ECAT 7 main header structure.

Definition at line 149 of file imgunits.c.

154 {
155 if(h->calibration_units==0) { /* Not calibrated */
156 img->unit=1;
157 } else if(h->calibration_units==1) {
159 img->unit=CUNIT_BQ_PER_ML;
160 else
161 img->unit=imgUnitId(h->data_units);
162 } else if(h->calibration_units==2) {
163 img->unit=imgUnitId(h->data_units);
164 } else {
165 img->unit=CUNIT_UNKNOWN;
166 }
167}

Referenced by imgGetEcat7MHeader().

◆ imgUnitId()

int imgUnitId ( char * unit)
extern

Identify the specified unit string as IMG unit.

See also
imgSetUnit, imgUnitId, petCunitId
Returns
unit id number, -1 invalid input, -3 no match found
Parameters
unitPointer to string containing the unit to be identified.

Definition at line 14 of file imgunits.c.

17 {
18 if(unit==NULL) return(-1);
19 if(strlen(unit)==0) return CUNIT_UNKNOWN;
20 else if(strcasecmp(unit, "unknown")==0) return CUNIT_UNKNOWN;
21 else if(strcasecmp(unit, "cnts/sec")==0) return CUNIT_CPS;
22 else if(strcasecmp(unit, "counts/sec")==0) return CUNIT_CPS;
23 else if(strcasecmp(unit, "ECAT counts/sec")==0) return CUNIT_CPS;
24 else if(strcasecmp(unit, "cps")==0) return CUNIT_CPS;
25 else if(strcasecmp(unit, "counts")==0) return CUNIT_COUNTS;
26 else if(strcasecmp(unit, "cnts")==0) return CUNIT_COUNTS;
27 else if(strcasecmp(unit, "kBq/cc")==0) return CUNIT_KBQ_PER_ML;
28 else if(strcasecmp(unit, "kBqcc")==0) return CUNIT_KBQ_PER_ML;
29 else if(strcasecmp(unit, "kBq/mL")==0) return CUNIT_KBQ_PER_ML;
30 else if(strcasecmp(unit, "kBqmL")==0) return CUNIT_KBQ_PER_ML;
31 else if(strcasecmp(unit, "sec*kBq/cc")==0) return CUNIT_SEC_KBQ_PER_ML;
32 else if(strcasecmp(unit, "sec*kBq/mL")==0) return CUNIT_SEC_KBQ_PER_ML;
33 else if(strcasecmp(unit, "integral")==0) return CUNIT_SEC_KBQ_PER_ML;
34 else if(strcasecmp(unit, "1/sec")==0) return CUNIT_PER_SEC;
35 else if(strcasecmp(unit, "1/s")==0) return CUNIT_PER_SEC;
36 else if(strcasecmp(unit, "s-1")==0) return CUNIT_PER_SEC;
37 else if(strcasecmp(unit, "1/min")==0) return CUNIT_PER_MIN;
38 else if(strcasecmp(unit, "min-1")==0) return CUNIT_PER_MIN;
39 else if(strcasecmp(unit, "mL/mL")==0) return CUNIT_ML_PER_ML;
40 else if(strcasecmp(unit, "mL/cc")==0) return CUNIT_ML_PER_ML;
41 else if(strcasecmp(unit, "mL/dL")==0) return CUNIT_ML_PER_DL;
42 else if(strcasecmp(unit, "mL/100mL")==0) return CUNIT_ML_PER_DL;
43 else if(strcasecmp(unit, "mL/(mL*min)")==0) return CUNIT_ML_PER_ML_PER_MIN;
44 else if(strcasecmp(unit, "mL/(min*mL)")==0) return CUNIT_ML_PER_ML_PER_MIN;
45 else if(strcasecmp(unit, "mL/(cc*min)")==0) return CUNIT_ML_PER_ML_PER_MIN;
46 else if(strcasecmp(unit, "mL/(min*cc)")==0) return CUNIT_ML_PER_ML_PER_MIN;
47 else if(strcasecmp(unit, "mL/mL/min")==0) return CUNIT_ML_PER_ML_PER_MIN;
48 else if(strcasecmp(unit, "mL/min/mL")==0) return CUNIT_ML_PER_ML_PER_MIN;
49 else if(strcasecmp(unit, "mL/cc/min")==0) return CUNIT_ML_PER_ML_PER_MIN;
50 else if(strcasecmp(unit, "mL/min/cc")==0) return CUNIT_ML_PER_ML_PER_MIN;
51 else if(strcasecmp(unit, "mL/(dL*min)")==0) return CUNIT_ML_PER_DL_PER_MIN;
52 else if(strcasecmp(unit, "mL/(min*dL)")==0) return CUNIT_ML_PER_DL_PER_MIN;
53 else if(strcasecmp(unit, "mL/(100mL*min)")==0) return CUNIT_ML_PER_DL_PER_MIN;
54 else if(strcasecmp(unit, "mL/(min*100mL)")==0) return CUNIT_ML_PER_DL_PER_MIN;
55 else if(strcasecmp(unit, "mL/dL/min")==0) return CUNIT_ML_PER_DL_PER_MIN;
56 else if(strcasecmp(unit, "mL/min/dL")==0) return CUNIT_ML_PER_DL_PER_MIN;
57 else if(strcasecmp(unit, "mL/100mL/min")==0) return CUNIT_ML_PER_DL_PER_MIN;
58 else if(strcasecmp(unit, "mL/min/100mL")==0) return CUNIT_ML_PER_DL_PER_MIN;
59 else if(strcasecmp(unit, "unitless")==0) return CUNIT_UNITLESS;
60 else if(strcasecmp(unit, "Hounsfield Unit")==0) return CUNIT_HU;
61 else if(strcasecmp(unit, "HU")==0) return CUNIT_HU;
62 else if(strcasecmp(unit, "nCi/cc")==0) return CUNIT_NCI_PER_ML;
63 else if(strcasecmp(unit, "nCicc")==0) return CUNIT_NCI_PER_ML;
64 else if(strcasecmp(unit, "nCi/mL")==0) return CUNIT_NCI_PER_ML;
65 else if(strcasecmp(unit, "nCimL")==0) return CUNIT_NCI_PER_ML;
66 else if(strcasecmp(unit, "MBq/cc")==0) return CUNIT_MBQ_PER_ML;
67 else if(strcasecmp(unit, "MBqcc")==0) return CUNIT_MBQ_PER_ML;
68 else if(strcasecmp(unit, "MBq/mL")==0) return CUNIT_MBQ_PER_ML;
69 else if(strcasecmp(unit, "MBqmL")==0) return CUNIT_MBQ_PER_ML;
70 else if(strcasecmp(unit, "Bq/cc")==0) return CUNIT_BQ_PER_ML;
71 else if(strcasecmp(unit, "Bqcc")==0) return CUNIT_BQ_PER_ML;
72 else if(strcasecmp(unit, "Bq/mL")==0) return CUNIT_BQ_PER_ML;
73 else if(strcasecmp(unit, "BqmL")==0) return CUNIT_BQ_PER_ML;
74 else if(strcasecmp(unit, "uCi/cc")==0) return CUNIT_UCI_PER_ML;
75 else if(strcasecmp(unit, "uCicc")==0) return CUNIT_UCI_PER_ML;
76 else if(strcasecmp(unit, "uCi/mL")==0) return CUNIT_UCI_PER_ML;
77 else if(strcasecmp(unit, "uCimL")==0) return CUNIT_UCI_PER_ML;
78 else if(strcasecmp(unit, "umol/(100g*min)")==0) return CUNIT_UMOL_PER_MIN_PER_100G;
79 else if(strcasecmp(unit, "umol/(min*100g)")==0) return CUNIT_UMOL_PER_MIN_PER_100G;
80 else if(strcasecmp(unit, "umol/100g/min")==0) return CUNIT_UMOL_PER_MIN_PER_100G;
81 else if(strcasecmp(unit, "umol/min/100g")==0) return CUNIT_UMOL_PER_MIN_PER_100G;
82 else if(strcasecmp(unit, "mg/(100g*min)")==0) return CUNIT_MG_PER_MIN_PER_100G;
83 else if(strcasecmp(unit, "mg/(min*100g)")==0) return CUNIT_MG_PER_MIN_PER_100G;
84 else if(strcasecmp(unit, "mg/100g/min")==0) return CUNIT_MG_PER_MIN_PER_100G;
85 else if(strcasecmp(unit, "mg/min/100g")==0) return CUNIT_MG_PER_MIN_PER_100G;
86
87 return(-3);
88}

Referenced by imgConvertUnit(), imgSetUnit(), and imgUnitFromEcat7().

◆ imgUnitToEcat6()

int imgUnitToEcat6 ( IMG * img)
extern

Return ECAT 6.3 calibration unit based on IMG unit

See also
imgUnitFromEcat, imgUnitId, imgUnitToEcat7, imgSetUnit
Returns
calibration unit code number.
Parameters
imgPointer to IMG structure.

Definition at line 175 of file imgunits.c.

178 {
179 int ecat_unit;
180 switch(img->unit) {
181 case CUNIT_CPS: ecat_unit=9; break;
182 case CUNIT_COUNTS: ecat_unit=2; break;
183 case CUNIT_KBQ_PER_ML: ecat_unit=10; break;
184 case CUNIT_SEC_KBQ_PER_ML: ecat_unit=13; break;
185 case CUNIT_PER_SEC: ecat_unit=15; break;
186 case CUNIT_PER_MIN: ecat_unit=11; break;
187 case CUNIT_ML_PER_ML: ecat_unit=16; break;
188 case CUNIT_ML_PER_DL: ecat_unit=16; break;
189 case CUNIT_ML_PER_ML_PER_MIN: ecat_unit=11; break;
190 case CUNIT_ML_PER_DL_PER_MIN: ecat_unit=12; break;
191 case CUNIT_UNITLESS: ecat_unit=16; break;
192 case CUNIT_HU: ecat_unit=17; break;
193 case CUNIT_NCI_PER_ML: ecat_unit=7; break;
194 case CUNIT_MBQ_PER_ML: ecat_unit=1; break;
195 case CUNIT_BQ_PER_ML: ecat_unit=9; break;
196 case CUNIT_UCI_PER_ML: ecat_unit=3; break;
197 case CUNIT_UMOL_PER_MIN_PER_100G: ecat_unit=5; break;
198 case CUNIT_MG_PER_MIN_PER_100G: ecat_unit=6; break;
199 default: ecat_unit=0; break;
200 }
201 return(ecat_unit);
202}

Referenced by ecat63AddImg(), ecat63WriteAllImg(), imgSetEcat63MHeader(), and imgSetEcat63SHeader().

◆ imgUnitToEcat7()

void imgUnitToEcat7 ( IMG * img,
ECAT7_mainheader * h )
extern

Set ECAT 7 main header calibration units based on IMG unit.

See also
imgUnitFromEcat7, imgUnitId, imgUnitToEcat6, imgSetUnit
Parameters
imgPointer to source IMG structure.
hPointer to target ECAT 7 main header structure.

Definition at line 209 of file imgunits.c.

214 {
215 switch(img->unit) {
216 case CUNIT_CPS:
217 case CUNIT_COUNTS:
220 strcpy(h->data_units, "ECAT counts/sec");
221 break;
222 case CUNIT_KBQ_PER_ML:
225 strcpy(h->data_units, "kBq/cc");
226 break;
227 case CUNIT_SEC_KBQ_PER_ML:
230 strcpy(h->data_units, "sec*kBq/mL");
231 break;
232 case CUNIT_PER_SEC:
235 strcpy(h->data_units, "1/sec");
236 break;
237 case CUNIT_PER_MIN:
240 strcpy(h->data_units, "1/min");
241 break;
242 case CUNIT_ML_PER_ML:
245 strcpy(h->data_units, "mL/mL");
246 break;
247 case CUNIT_ML_PER_DL:
250 strcpy(h->data_units, "mL/dL");
251 break;
252 case CUNIT_ML_PER_ML_PER_MIN:
255 strcpy(h->data_units, "mL/(mL*min)");
256 break;
257 case CUNIT_ML_PER_DL_PER_MIN:
260 strcpy(h->data_units, "mL/(dL*min)");
261 break;
262 case CUNIT_UNITLESS:
265 strcpy(h->data_units, "unitless");
266 break;
267 case CUNIT_NCI_PER_ML:
270 strcpy(h->data_units, "nCi/cc");
271 break;
272 case CUNIT_MBQ_PER_ML:
275 strcpy(h->data_units, "MBq/cc");
276 break;
277 case CUNIT_BQ_PER_ML:
280 strcpy(h->data_units, "Bq/cc");
281 break;
282 case CUNIT_UCI_PER_ML:
285 strcpy(h->data_units, "uCi/cc");
286 break;
287 case CUNIT_UMOL_PER_MIN_PER_100G:
290 strcpy(h->data_units, "umol/min/100g");
291 break;
292 case CUNIT_MG_PER_MIN_PER_100G:
295 strcpy(h->data_units, "mg/min/100g");
296 break;
297 case CUNIT_HU:
300 strcpy(h->data_units, "HU");
301 break;
302 default:
305 strcpy(h->data_units, "");
306 break;
307 }
308}

Referenced by imgSetEcat7MHeader().

◆ imgWrite()

int imgWrite ( const char * fname,
IMG * img )
extern

Write an image or sinogram file.

Format depends on _fileFormat or file name extension.

See also
imgInit, imgEmpty, imgRead
Returns
0 if ok, 1 invalid input, 2 invalid image type or status, 5 failed to write file, sets IMG->statmsg in case of error
Parameters
fnameFile name for output image.
imgPointer to IMG data.

Definition at line 136 of file imgfile.c.

141 {
142 int ret;
143
144 if(IMG_TEST) printf("imgWrite(%s, *img)\n", fname);
145 /* Check the arguments */
146 if(fname==NULL) return(1);
147 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
148 imgSetStatus(img, STATUS_FAULT); return(2);}
149 if(img->type!=IMG_TYPE_RAW &&
150 img->type!=IMG_TYPE_IMAGE &&
151 img->type!=IMG_TYPE_POLARMAP) {
152 imgSetStatus(img, STATUS_FAULT); return(2);}
153
154 /* If _fileFormat is not defined, then determine it from the file name */
155 if(img->_fileFormat==IMG_UNKNOWN) {
156 if(IMG_TEST>1) printf(" file format determined based on file name\n");
157 imgFormatFromFName(img, fname);
158 if(IMG_TEST>1) printf(" _fileFormat := %d\n", img->_fileFormat);
159 }
160
161 /* Write */
162 if(img->_fileFormat==IMG_E63) {
163 ret=ecat63WriteAllImg(fname, img);
164 switch(ret) {
165 case 0: break;
166 case 4: imgSetStatus(img, STATUS_NOMEMORY); break;
167 case 3: imgSetStatus(img, STATUS_NOWRITEPERM); break;
168 case 9: imgSetStatus(img, STATUS_DISKFULL); break;
169 default: imgSetStatus(img, STATUS_FAULT);
170 }
171 if(ret) return(7);
172 } else if(img->_fileFormat==IMG_ANA || img->_fileFormat==IMG_ANA_L) {
173 ret=imgWriteAnalyze(fname, img); if(ret) return(5);
174 } else if(img->_fileFormat==IMG_NIFTI_1S || img->_fileFormat==IMG_NIFTI_1D) {
175 ret=imgWriteNifti(fname, img, 1, IMG_TEST-1); if(ret) return(5);
176 } else if(img->_fileFormat==IMG_E7_2D) {
177 ret=imgWrite2DEcat7(fname, img); if(ret) return(5);
178 } else if(img->_fileFormat==IMG_POLARMAP) {
179 ret=imgWritePolarmap(fname, img); if(ret) return(5);
180 } else {
181 ret=imgWriteEcat7(fname, img); if(ret) return(5);
182 }
183 imgSetStatus(img, STATUS_OK);
184 return(0);
185}
int imgWriteAnalyze(const char *dbname, IMG *img)
Definition img_ana.c:162
int ecat63WriteAllImg(const char *fname, IMG *img)
Definition img_e63.c:335
int imgWrite2DEcat7(const char *fname, IMG *img)
Definition img_e7.c:526
int imgWriteEcat7(const char *fname, IMG *img)
Definition img_e7.c:382
int imgWritePolarmap(const char *fname, IMG *img)
Definition img_e7.c:661
int imgWriteNifti(const char *dbname, IMG *img, int save_sif, int verbose)
Definition img_nii.c:811
void imgFormatFromFName(IMG *img, const char *fname)
Definition imgfile.c:483

Referenced by imgMicropetCTToEcat7().

◆ imgWrite2DEcat7()

int imgWrite2DEcat7 ( const char * fname,
IMG * img )
extern

Write ECAT 7 2D image or 2D sinogram.

Parameters
fnameoutput filename
imgpointer to image structure
Returns
0 if ok, 1 invalid input, 2 image status is not 'occupied', 3 failed to allocate memory for data, 6 faield to create file, 7 failed to write data, 8 image type not supported, sets IMG->statmsg in case of error

Definition at line 526 of file img_e7.c.

526 {
527 ECAT7_mainheader main_header;
528 ECAT7_imageheader image_header;
529 ECAT7_2Dscanheader scan2d_header;
530 FILE *fp;
531 int matrixId, ret;
532 float *fdata, *fptr;
533
534
535 if(IMG_TEST) printf("imgWrite2DEcat7(%s, *img)\n", fname);
536 if(IMG_TEST>1 && ECAT7_TEST==0) ECAT7_TEST=1;
537 /* Check the arguments */
538 if(fname==NULL) {return(1);}
539 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
540 imgSetStatus(img, STATUS_FAULT); return(2);}
541
542 /* Check image size */
543 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024) {
544 imgSetStatus(img, STATUS_INVALIDHEADER); return(2);}
545
546 /* Initiate headers */
547 memset(&main_header, 0, sizeof(ECAT7_mainheader));
548 memset(&image_header,0, sizeof(ECAT7_imageheader));
549 memset(&scan2d_header, 0, sizeof(ECAT7_2Dscanheader));
550
551 /* Set main header */
552 imgSetEcat7MHeader(img, &main_header);
553 main_header.bin_size=img->sampleDistance/10.0;
554 if(img->type==IMG_TYPE_RAW) main_header.file_type=ECAT7_2DSCAN;
555 else main_header.file_type=ECAT7_IMAGE16;
556 main_header.num_planes=img->dimz;
557
558 /* Allocate memory for matrix float data */
559 long long pxlNr=img->dimx*img->dimy;
560 fdata=(float*)malloc(pxlNr*sizeof(float));
561 if(fdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return(3);}
562
563 /* Open file, write main header and initiate matrix list */
564 fp=ecat7Create(fname, &main_header);
565 if(fp==NULL) {free(fdata); imgSetStatus(img, STATUS_NOWRITEPERM); return(6);}
566
567 /* Set (most of) subheader contents */
568 if(img->type==IMG_TYPE_RAW) {
569 scan2d_header.num_dimensions=2;
570 scan2d_header.num_z_elements=1;
571 scan2d_header.data_type=ECAT7_SUNI2;
572 scan2d_header.num_r_elements=img->dimx;
573 scan2d_header.num_angles=img->dimy;
574 } else if(img->type==IMG_TYPE_IMAGE) {
575 image_header.num_dimensions=2;
576 image_header.z_dimension=1;
577 image_header.data_type=ECAT7_SUNI2;
578 image_header.x_dimension=img->dimx;
579 image_header.y_dimension=img->dimy;
580 image_header.recon_zoom=img->zoom;
581 image_header.x_pixel_size=0.1*img->sizex;
582 image_header.y_pixel_size=0.1*img->sizey;
583 image_header.z_pixel_size=0.1*img->sizez;
584 image_header.x_resolution=0.1*img->resolutionx;
585 image_header.y_resolution=0.1*img->resolutiony;
586 image_header.z_resolution=0.1*img->resolutionz;
587 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
588 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
589 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
590 image_header.mt_1_1=img->mt[0];
591 image_header.mt_1_2=img->mt[1];
592 image_header.mt_1_3=img->mt[2];
593 image_header.mt_1_4=img->mt[3];
594 image_header.mt_2_1=img->mt[4];
595 image_header.mt_2_2=img->mt[5];
596 image_header.mt_2_3=img->mt[6];
597 image_header.mt_2_4=img->mt[7];
598 image_header.mt_3_1=img->mt[8];
599 image_header.mt_3_2=img->mt[9];
600 image_header.mt_3_3=img->mt[10];
601 image_header.mt_3_4=img->mt[11];
602 }
603
604 /* Write each matrix */
605 for(int fi=0; fi<img->dimt; fi++) for(int pi=0; pi<img->dimz; pi++) {
606
607 /* Create new matrix id (i.e. matnum) */
608 matrixId=ecat7_val_to_id(fi+1, img->planeNumber[pi], 1, 0, 0);
609
610 /* Copy matrix pixel values to fdata */
611 fptr=fdata;
612 for(int yi=0; yi<img->dimy; yi++)
613 for(int xi=0; xi<img->dimx; xi++)
614 if(isfinite(img->m[pi][yi][xi][fi])) *fptr++=img->m[pi][yi][xi][fi]; else *fptr++=0.0;
615
616 /* Write subheader and data */
617 fptr=fdata;
618 if(img->type==IMG_TYPE_RAW) {
619 scan2d_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
620 scan2d_header.frame_duration=
621 (int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
622 scan2d_header.prompts=temp_roundf(img->prompts[fi]);
623 scan2d_header.delayed=temp_roundf(img->randoms[fi]);
624 ret=ecat7Write2DScanMatrix(fp, matrixId, &scan2d_header, fptr);
625 } else if(img->type==IMG_TYPE_IMAGE) {
626 image_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
627 image_header.frame_duration=
628 (int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
630 image_header.decay_corr_fctr=img->decayCorrFactor[fi];
631 else
632 image_header.decay_corr_fctr=0.0;
633 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
634 } else {
635 free(fdata); fclose(fp); imgSetStatus(img, STATUS_UNSUPPORTED); return(8);
636 }
637 if(ret) {
638 if(IMG_TEST) {printf("matrixId=%d ret=%d\n", matrixId, ret);}
639 free(fdata); fclose(fp); imgSetStatus(img, STATUS_DISKFULL); return(7);
640 }
641
642 } /* next matrix */
643 free(fdata); fclose(fp);
644
645 imgSetStatus(img, STATUS_OK);
646 return(0);
647}
int ecat7WriteImageMatrix(FILE *fp, int matrix_id, ECAT7_imageheader *h, float *fdata)
Definition ecat7w.c:635
int ecat7Write2DScanMatrix(FILE *fp, int matrix_id, ECAT7_2Dscanheader *h, float *fdata)
Definition ecat7w.c:719
FILE * ecat7Create(const char *fname, ECAT7_mainheader *h)
Definition ecat7w.c:567
void imgSetEcat7MHeader(IMG *img, ECAT7_mainheader *h)
Definition img_e7.c:781

Referenced by imgWrite().

◆ imgWriteAnalyze()

int imgWriteAnalyze ( const char * dbname,
IMG * img )
extern

Write Analyze 7.5 image.

Analyze database name must be given with path. Path must exist. Image and header files with .img and .hdr extensions are created. Existing files are overwritten. anaFlipping() determines whether image is flipped in z-direction; image is always flipped in x,y-directions. Byte order is determined based on _fileFormat field.

Parameters
dbnameanalyze database name with path, without extension
imgpointer to IMG data
Returns
0 if ok, 1 invalid input, 2 invalid image status (image not occupied), 3 failed to resolve extreme values (min and max), 12 failed to allocate temp memory, 14 failed to open file for writing, 15 failed to write data, 21 failed to write header, and sets IMG->statmsg in case of error

Definition at line 162 of file img_ana.c.

162 {
163 FILE *fp;
164 int ret, little;
165 float g;
166 ANALYZE_DSR dsr;
167 char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
168 const char *cptr;
169 struct tm tm; //*st;
170 short int *sdata, *sptr, smin, smax;
171 SIF sif;
172
173
174 if(IMG_TEST) printf("imgWriteAnalyze(%s, *img)\n", dbname);
175
176 /* Check the arguments */
177 imgSetStatus(img, STATUS_OK);
178 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
179 imgSetStatus(img, STATUS_FAULT); return(2);}
180 if(dbname==NULL || !dbname[0]) {imgSetStatus(img, STATUS_FAULT); return(1);}
181
182 /* Make the image and header filenames */
183 strcpy(datfile, dbname); strcat(datfile, ".img");
184 strcpy(hdrfile, dbname); strcat(hdrfile, ".hdr");
185 strcpy(siffile, dbname); strcat(siffile, ".sif");
186
187
188 /*
189 * Fill Analyze header
190 */
191 if(img->_fileFormat==IMG_ANA_L) dsr.little=1; else dsr.little=0;
192 /* Header key */
193 memset(&dsr.hk, 0, sizeof(ANALYZE_HEADER_KEY));
194 memset(&dsr.dime, 0, sizeof(ANALYZE_HEADER_IMGDIM));
195 memset(&dsr.hist, 0, sizeof(ANALYZE_HEADER_HISTORY));
196 dsr.hk.sizeof_hdr=348;
197 strcpy(dsr.hk.data_type, "");
198 cptr=strrchr(dbname, '/'); if(cptr==NULL) cptr=strrchr(dbname, '\\');
199 if(cptr!=NULL) cptr++;
200 if(cptr==NULL) cptr=dbname;
201 strncpy(dsr.hk.db_name, cptr, 17);
202 dsr.hk.extents=16384;
203 dsr.hk.regular='r';
204 /* Image dimension */
205 dsr.dime.dim[0]=4;
206 dsr.dime.dim[1]=img->dimx;
207 dsr.dime.dim[2]=img->dimy;
208 dsr.dime.dim[3]=img->dimz;
209 dsr.dime.dim[4]=img->dimt;
211 dsr.dime.bitpix=16;
212 dsr.dime.pixdim[0]=0.0;
213 dsr.dime.pixdim[1]=img->sizex;
214 dsr.dime.pixdim[2]=img->sizey;
215 dsr.dime.pixdim[3]=img->sizez;
216 dsr.dime.pixdim[4]=0.0;
217 dsr.dime.funused1=0.0; /* Scale factor is set later */
218 /* dsr.dime.funused2=img->zoom; */ /* Reconstruction zoom */
220 /* Data history */
222 strcpy(dsr.hist.descrip, "Decay corrected.");
224 strcpy(dsr.hist.descrip, "No decay correction.");
225 else
226 strcpy(dsr.hist.descrip, "");
227 if(strlen(img->studyNr)>0 && strcmp(img->studyNr, ".")!=0)
228 memcpy(dsr.hist.scannum, img->studyNr, 10);
229 else
230 strcpy(dsr.hist.scannum, "");
231 gmtime_r((time_t*)&img->scanStart, &tm);
232 if(!strftime(dsr.hist.exp_date, 10, "%Y-%m-%d", &tm))
233 memcpy(dsr.hist.exp_date, "1900-01-01", 10);
234 if(!strftime(dsr.hist.exp_time, 10, "%H:%M:%S", &tm))
235 strlcpy(dsr.hist.exp_time, "00:00:00", 10);
236
237 /*
238 * Scale data to short int range
239 * Determine and set scale factor and cal_min & cal_max
240 */
241 if(IMG_TEST) printf("scaling data to short ints\n");
242 ret=imgMinMax(img, &dsr.dime.cal_min, &dsr.dime.cal_max);
243 if(ret) {imgSetStatus(img, STATUS_FAULT); return(3);}
244 if(IMG_TEST) printf("min=%g max=%g\n", dsr.dime.cal_min, dsr.dime.cal_max);
245 if(fabs(dsr.dime.cal_min)>fabs(dsr.dime.cal_max)) g=fabs(dsr.dime.cal_min);
246 else g=fabs(dsr.dime.cal_max);
247 if(isnan(g)) {imgSetStatus(img, STATUS_FAULT); return 3;}
248 if(g<1E-20) g=1.0; else g=32767./g; dsr.dime.funused1=1.0/g;
249 if(IMG_TEST) printf("scale_factor=%g\n", dsr.dime.funused1);
250
251 /* Allocate memory for short int array */
252 size_t pxlNr=(img->dimx)*(img->dimy)*(img->dimz);
253 sdata=malloc(pxlNr*sizeof(short int));
254 if(sdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return 12;}
255
256 /* Open image data file for write */
257 if((fp=fopen(datfile, "wb")) == NULL) {
258 imgSetStatus(img, STATUS_CANTWRITEIMGFILE);
259 free(sdata);
260 return 14;
261 }
262
263 /* Copy and write image matrix data to short int array */
264 /* Data is written one frame at a time */
265 smin=smax=temp_roundf(g*img->m[0][0][0][0]);
266 for(int fi=0; fi<img->dimt; fi++) {
267 sptr=sdata;
268 if(anaFlipping()==0) {
269 for(int pi=0; pi<img->dimz; pi++)
270 for(int yi=img->dimy-1; yi>=0; yi--)
271 for(int xi=img->dimx-1; xi>=0; xi--) {
272 *sptr=temp_roundf(g*img->m[pi][yi][xi][fi]);
273 if(*sptr>smax) smax=*sptr; else if(*sptr<smin) smin=*sptr;
274 sptr++;
275 }
276 } else {
277 for(int pi=img->dimz-1; pi>=0; pi--)
278 for(int yi=img->dimy-1; yi>=0; yi--)
279 for(int xi=img->dimx-1; xi>=0; xi--) {
280 *sptr=temp_roundf(g*img->m[pi][yi][xi][fi]);
281 if(*sptr>smax) smax=*sptr; else if(*sptr<smin) smin=*sptr;
282 sptr++;
283 }
284 }
285 /* Change byte order if necessary */
286 little=little_endian();
287 if(little!=dsr.little)
288 swabip(sdata, pxlNr*sizeof(short int));
289 /* Write image data */
290 if(fwrite(sdata, 2, pxlNr, fp) != pxlNr) {
291 imgSetStatus(img, STATUS_CANTWRITEIMGFILE);
292 free(sdata); fclose(fp);
293 return 15;
294 }
295 }
296 /* Done writing */
297 fclose(fp);
298 free(sdata);
299
300 if(IMG_TEST) printf("smin=%d smax=%d\n", smin, smax);
301
302 /* Set header glmin & glmax */
303 dsr.dime.glmin=smin; dsr.dime.glmax=smax;
304
305 /* Write Analyze header */
306 ret=anaWriteHeader(hdrfile, &dsr);
307 if(ret) {
308 imgSetStatus(img, STATUS_CANTWRITEHEADERFILE);
309 return 21;
310 }
311 imgSetStatus(img, STATUS_OK);
312
313 /* Otherwise ready, but check if SIF should/can be written */
314 sifInit(&sif);
315 /* Try to read existing SIF */
316 ret=sifRead(siffile, &sif);
317 if(ret==0) { // SIF could be read
318 if(sif.frameNr==img->dimt) {
319 /* If size matches, then update the contents, but keep counts, in case
320 previous SIF comes with actual count info from scanner */
321 ret=img2sif(img, &sif, 1, 1, 0, IMG_TEST-2);
322 } else {
323 /* otherwise create SIF contents */
324 ret=img2sif(img, &sif, 1, 1, 2, IMG_TEST-2);
325 }
326 } else {
327 /* otherwise create SIF contents */
328 ret=img2sif(img, &sif, 1, 1, 2, IMG_TEST-2);
329 }
330 if(ret!=0) {
331 /* SIF data could not be made: do not give error, just do not write it */
332 if(IMG_TEST>0) printf("SIF contents could not be filled.\n");
333 return 0;
334 }
335 /* Write SIF */
336 ret=sifWrite(&sif, siffile);
337 if(ret!=0) {
338 /* SIF could not be written: do not give error, just do not write it */
339 if(IMG_TEST>0)
340 fprintf(stderr, "Error: SIF could not be written (%d).\n", ret);
341 }
342
343 imgSetStatus(img, STATUS_OK);
344 return 0;
345}
int anaWriteHeader(char *filename, ANALYZE_DSR *h)
Definition analyze.c:282
int img2sif(IMG *img, SIF *sif, int copy_header, int copy_frames, int copy_counts, int verbose)
Definition img_sif.c:71
int sifWrite(SIF *data, char *filename)
Definition sifio.c:145

Referenced by imgWrite().

◆ imgWriteAnalyzeFrame()

int imgWriteAnalyzeFrame ( const char * dbname,
int frame_to_write,
IMG * img,
int frame_index,
float fmin,
float fmax )
extern

Write one PET frame from IMG data struct into Analyze 7.5 database file. This function can be called repeatedly to write all frames one at a time to conserve memory. This function does not write SIF.

Parameters
dbnamename of file where IMG contents will be written. If file does not exist, it is created. Make sure to delete existing file, unless you want to add data
frame_to_writePET frame number (1..frameNr) which will be written: If set to 0, frame data will be written to an existing or new PET file as a new frame, never overwriting existing data. If >0, then frame data is written as specified frame number, overwriting any data existing with the same frame number.
imgpointer to the IMG data struct
frame_indexIMG frame index (0..dimt-1) which will be written
fminminimum pixel value in all frames that will be written; used only when writing the first frame
fmaxmaximum pixel value in all frames that will be written; used only when writing the first frame
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 751 of file img_ana.c.

754 {
755 IMG test_img;
756 int ret=0, little;
757 FILE *fp;
758 short int *sdata=NULL, *sptr;
759 char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
760 ANALYZE_DSR dsr;
761 float scale_factor=1.0;
762
763
764 if(IMG_TEST) printf("\nimgWriteAnalyzeFrame(%s, %d, *img, %d, %g, %g)\n",
765 dbname, frame_to_write, frame_index, fmin, fmax);
766
767 /*
768 * Check the input
769 */
770 if(dbname==NULL) return STATUS_FAULT;
771 if(img==NULL) return STATUS_FAULT;
772 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
773 if(frame_to_write<0) return STATUS_FAULT;
774 if(frame_index<0 || frame_index>=img->dimt) return STATUS_FAULT;
775 if(img->_fileFormat!=IMG_ANA_L && img->_fileFormat!=IMG_ANA)
776 return STATUS_FAULT;
777
778 /*
779 * If database does not exist, then create it with new header,
780 * and if it does exist, then read and check header information.
781 * Create or edit header to contain correct frame nr.
782 * Determine the global scaling factor.
783 */
784 imgInit(&test_img);
785 if(anaDatabaseExists(dbname, hdrfile, datfile, siffile)==0) { // not existing
786
787 /* Create database filenames */
788 sprintf(hdrfile, "%s.hdr", dbname);
789 sprintf(datfile, "%s.img", dbname);
790 sprintf(siffile, "%s.sif", dbname);
791
792 /* Set main header */
793 imgSetAnalyzeHeader(img, dbname, &dsr, fmin, fmax);
794 if(frame_to_write==0) frame_to_write=1;
795 dsr.dime.dim[4]=frame_to_write;
796 scale_factor=dsr.dime.funused1;
797 if(fabs(scale_factor)>1.0E-20) scale_factor=1.0/scale_factor;
798
799 /* Write Analyze header */
800 ret=anaWriteHeader(hdrfile, &dsr);
801 if(ret && IMG_TEST) printf("anaWriteHeader() := %d\n", ret);
802 if(ret) return STATUS_CANTWRITEHEADERFILE;
803
804 /* Remove datafile if necessary */
805 if(access(datfile, 0) != -1) remove(datfile);
806
807 } else { /* database does exist */
808
809 /* Read header information for checking */
810 ret=imgReadAnalyzeHeader(dbname, &test_img);
811 if(ret!=0) {imgEmpty(&test_img); return ret;}
812 /* Check that file format is the same */
813 if(img->_fileFormat!=test_img._fileFormat || img->type!=test_img.type) {
814 imgEmpty(&test_img); return STATUS_WRONGFILETYPE;}
815 /* Check that matrix sizes are the same */
816 if(img->dimz!=test_img.dimz || img->dimx!=test_img.dimx ||
817 img->dimy!=test_img.dimy) {
818 imgEmpty(&test_img); return STATUS_VARMATSIZE;}
819 imgEmpty(&test_img);
820
821 /* Read the header, set new frame number, and write it back */
822 /* Get also the scale factor */
823 if((ret=anaReadHeader(hdrfile, &dsr))!=0) return STATUS_NOMAINHEADER;
824 scale_factor=1.0/dsr.dime.funused1;
825 if(frame_to_write==0) frame_to_write=dsr.dime.dim[4]+1;
826 if(dsr.dime.dim[4]<frame_to_write) {
827 if(dsr.dime.dim[4]+1<frame_to_write) return STATUS_MISSINGMATRIX;
828 dsr.dime.dim[4]=frame_to_write;
829 }
830 if((ret=anaWriteHeader(hdrfile, &dsr))!=0) return STATUS_NOWRITEPERM;
831 }
832 if(IMG_TEST>2) {
833 printf("frame_to_write := %d\n", frame_to_write);
834 printf("hdrfile := %s\n", hdrfile);
835 printf("datfile := %s\n", datfile);
836 printf("siffile := %s\n", siffile);
837 }
838
839 /* Allocate memory for matrix short int data (one plane) */
840 size_t pxlNr=img->dimx*img->dimy;
841 sdata=(short int*)malloc(pxlNr*sizeof(short int));
842 if(sdata==NULL) return STATUS_NOMEMORY;
843
844 /* Open datafile, not removing possible old contents */
845 if(frame_to_write==1) fp=fopen(datfile, "wb"); else fp=fopen(datfile, "r+b");
846 if(fp==NULL) {free(sdata); return STATUS_CANTWRITEIMGFILE;}
847 /* Move file pointer to the place of current frame */
848 if(fseeko(fp, (frame_to_write-1)*pxlNr*img->dimz*sizeof(short int),
849 SEEK_SET)!=0) {
850 free(sdata); fclose(fp); return STATUS_MISSINGMATRIX;}
851 little=little_endian();
852 /* Copy, scale and write data plane-by-plane */
853 if(anaFlipping()==0) {
854 for(int zi=0; zi<img->dimz; zi++) {
855 sptr=sdata;
856 /*printf("plane := %d\n scale_factor := %g\n", zi+1, scale_factor);*/
857 for(int yi=img->dimy-1; yi>=0; yi--)
858 for(int xi=img->dimx-1; xi>=0; xi--) {
859 *sptr=temp_roundf(scale_factor*img->m[zi][yi][xi][frame_index]);
860 sptr++;
861 }
862 /* Change byte order if necessary */
863 sptr=sdata; if(little!=dsr.little) swabip(sptr, pxlNr*sizeof(short int));
864 /* Write image data */
865 sptr=sdata;
866 if(fwrite(sptr, sizeof(short int), pxlNr, fp) != pxlNr) {
867 free(sdata); fclose(fp); return STATUS_CANTWRITEIMGFILE;
868 }
869 }
870 } else {
871 for(int zi=img->dimz-1; zi>=0; zi--) {
872 sptr=sdata;
873 for(int yi=img->dimy-1; yi>=0; yi--)
874 for(int xi=img->dimx-1; xi>=0; xi--) {
875 *sptr=temp_roundf(scale_factor*img->m[zi][yi][xi][frame_index]);
876 sptr++;
877 }
878 /* Change byte order if necessary */
879 sptr=sdata; if(little!=dsr.little) swabip(sptr, pxlNr*sizeof(short int));
880 /* Write image data */
881 sptr=sdata;
882 if(fwrite(sptr, sizeof(short int), pxlNr, fp) != pxlNr) {
883 free(sdata); fclose(fp); return STATUS_CANTWRITEIMGFILE;
884 }
885 }
886 }
887 free(sdata);
888 fclose(fp);
889
890 return STATUS_OK;
891}
int imgSetAnalyzeHeader(IMG *img, const char *dbname, ANALYZE_DSR *dsr, float fmin, float fmax)
Definition img_ana.c:486

◆ imgWriteEcat63Frame()

int imgWriteEcat63Frame ( const char * fname,
int frame_to_write,
IMG * img,
int frame_index )
extern

Write one PET frame from IMG data struct into ECAT 6.3 image or sinogram file; format is specified in IMG struct. This function can be called repeatedly to write all frames one at a time to conserve memory. However, file with just mainheader and matrix list without any previous frame is not accepted.

Parameters
fnamename of file where IMG contents will be written. If file does not exist, it is created. Make sure to delete existing file, unless you want to add data
frame_to_writePET frame number (1..frameNr) which will be written: If set to 0, frame data will be written to an existing or new PET file as a new frame, never overwriting existing data. If >0, then frame data is written as specified frame number, overwriting any data existing with the same frame number
imgpointer to the IMG data struct
frame_indexIMG frame index (0..dimt-1) which will be written
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 1711 of file img_e63.c.

1713 {
1714 IMG test_img;
1715 int ret=0, matrixId;
1716 ECAT63_mainheader main_header;
1717 ECAT63_imageheader image_header;
1718 ECAT63_scanheader scan_header;
1719 void *sub_header=NULL;
1720 FILE *fp;
1721 float *fdata=NULL, *fptr;
1722
1723
1724 if(IMG_TEST>0) printf("\nimgWriteEcat63Frame(%s, %d, *img, %d)\n",
1725 fname, frame_to_write, frame_index);
1727 if(IMG_TEST>4) {
1728 char buf[32];
1729 if(!ctime_r_int(&img->scanStart, buf)) strcpy(buf, "1900-01-01 00:00:00");
1730 fprintf(stdout, " scan_start_time := %s\n", buf);
1731 }
1732
1733 /*
1734 * Check the input
1735 */
1736 if(fname==NULL) return STATUS_FAULT;
1737 if(img==NULL) return STATUS_FAULT;
1738 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
1739 if(frame_to_write<0) return STATUS_FAULT;
1740 if(frame_index<0 || frame_index>=img->dimt) return STATUS_FAULT;
1741 if(img->_fileFormat!=IMG_E63) return STATUS_FAULT;
1742
1743 /* Check image size */
1744 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024) {
1745 strcpy(ecat63errmsg, "too large matrix size"); return(1);}
1746
1747 /* Initiate headers */
1748 memset(&main_header, 0, sizeof(ECAT63_mainheader));
1749 memset(&image_header,0, sizeof(ECAT63_imageheader));
1750 memset(&scan_header, 0, sizeof(ECAT63_scanheader));
1751 imgInit(&test_img);
1752
1753
1754 /*
1755 * If file does not exist, then create it with new mainheader,
1756 * and if it does exist, then read and check header information.
1757 * Create or edit mainheader to contain correct frame nr.
1758 * In any case, leave file pointer open for write.
1759 */
1760 if(access(fname, 0) == -1) { /* file does not exist*/
1761
1762 if(IMG_TEST>1) printf(" new file\n");
1763 /* Set main header */
1764 imgSetEcat63MHeader(img, &main_header);
1765 if(IMG_TEST>6) {
1766 ecat63PrintMainheader(&main_header, stdout);
1767 }
1768 if(frame_to_write==0) frame_to_write=1;
1769 main_header.num_frames=frame_to_write;
1770
1771 /* Open file, write main header and initiate matrix list */
1772 fp=ecat63Create(fname, &main_header); if(fp==NULL) return STATUS_NOWRITEPERM;
1773
1774 } else { /* file exists*/
1775
1776 if(IMG_TEST>1) printf(" existing file\n");
1777 /* Read header information for checking */
1778 ret=imgReadEcat63Header(fname, &test_img); if(ret!=0) return ret;
1779 if(IMG_TEST>1) {
1780 char buf[32];
1781 if(!ctime_r_int(&test_img.scanStart, buf))
1782 strcpy(buf, "1900-01-01 00:00:00");
1783 fprintf(stdout, "scan_start_time := %s\n", buf);
1784 }
1785 /* Check that file format is the same */
1786 if(img->_fileFormat!=test_img._fileFormat || img->type!=test_img.type)
1787 return STATUS_WRONGFILETYPE;
1788 /* Check that matrix sizes are the same */
1789 if(img->dimz!=test_img.dimz || img->dimx!=test_img.dimx ||
1790 img->dimy!=test_img.dimy)
1791 return STATUS_VARMATSIZE;
1792 imgEmpty(&test_img);
1793
1794 /* Open the file for read and write */
1795 if((fp=fopen(fname, "r+b"))==NULL) return STATUS_NOWRITEPERM;
1796
1797 /* Read the mainheader, set new frame number, and write it back */
1798 if((ret=ecat63ReadMainheader(fp, &main_header))!=0)
1799 return STATUS_NOMAINHEADER;
1800 if(frame_to_write==0) frame_to_write=main_header.num_frames+1;
1801 if(main_header.num_frames<frame_to_write)
1802 main_header.num_frames=frame_to_write;
1803 if((ret=ecat63WriteMainheader(fp, &main_header))!=0)
1804 return STATUS_NOWRITEPERM;
1805 if(IMG_TEST>0) {
1806 char tmp[32];
1807 printf(" scan_start_time := %s\n", ecat63ScanstarttimeInt(&main_header, tmp));
1808 }
1809
1810 }
1811 if(IMG_TEST>2) {
1812 printf("frame_to_write := %d\n", frame_to_write);
1813 }
1814
1815 /* Allocate memory for matrix float data */
1816 size_t pxlNr=img->dimx*img->dimy*img->dimz;
1817 fdata=(float*)malloc(pxlNr*sizeof(float));
1818 if(fdata==NULL) {fclose(fp); return STATUS_NOMEMORY;}
1819
1820 /* Set matrix subheader */
1821 if(img->type==IMG_TYPE_RAW) sub_header=(void*)&scan_header;
1822 else if(img->type==IMG_TYPE_IMAGE) sub_header=&image_header;
1823 else {fclose(fp); return STATUS_FAULT;}
1824 imgSetEcat63SHeader(img, sub_header);
1825
1826 /* Copy matrix pixel values to fdata */
1827 fptr=fdata;
1828 for(int zi=0; zi<img->dimz; zi++)
1829 for(int yi=0; yi<img->dimy; yi++)
1830 for(int xi=0; xi<img->dimx; xi++)
1831 *fptr++=img->m[zi][yi][xi][frame_index];
1832
1833 /* Write subheader and data, and set the rest of subheader contents */
1834 fptr=fdata; ret=-1;
1835 for(int zi=0; zi<img->dimz; zi++, fptr+=img->dimx*img->dimy) {
1836 /* Create new matrix id (i.e. matnum) */
1837 matrixId=mat_numcod(frame_to_write, img->planeNumber[zi], 1, 0, 0);
1838 if(img->type==IMG_TYPE_RAW) {
1839 scan_header.frame_start_time=
1840 (int)temp_roundf(1000.*img->start[frame_index]);
1841 scan_header.frame_duration=
1842 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1843 scan_header.prompts=temp_roundf(img->prompts[frame_index]);
1844 scan_header.delayed=temp_roundf(img->randoms[frame_index]);
1845 ret=ecat63WriteScanMatrix(fp, matrixId, &scan_header, fptr);
1846 } else {
1847 image_header.frame_start_time=
1848 (int)temp_roundf(1000.*img->start[frame_index]);
1849 image_header.frame_duration=
1850 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1852 image_header.decay_corr_fctr=img->decayCorrFactor[frame_index];
1853 else
1854 image_header.decay_corr_fctr=0.0;
1855 ret=ecat63WriteImageMatrix(fp, matrixId, &image_header, fptr);
1856 }
1857 if(ret!=0) break;
1858 } /* next plane*/
1859 free(fdata); fclose(fp);
1860 if(ret) return STATUS_DISKFULL;
1861
1862 return STATUS_OK;
1863}
int ecat63WriteScanMatrix(FILE *fp, int matnum, ECAT63_scanheader *h, float *fdata)
Definition ecat63w.c:781
int ecat63WriteImageMatrix(FILE *fp, int matnum, ECAT63_imageheader *h, float *fdata)
Definition ecat63w.c:697
void imgSetEcat63SHeader(IMG *img, void *h)
Definition img_e63.c:1872
void imgSetEcat63MHeader(IMG *img, ECAT63_mainheader *h)
Definition img_e63.c:1223

Referenced by imgWriteFrame().

◆ imgWriteEcat7()

int imgWriteEcat7 ( const char * fname,
IMG * img )
extern

Write ECAT 7 3D image volume or 3D sinogram.

Parameters
fnameoutput filename
imgpointer to IMG data
Returns
0 if ok, 1 invalid input, 2 image status is not 'occupied', 3 failed to allocate memory for data, 6 failed to create file, 7 failed to write data, 8 unsupported image type sets IMG->statmsg in case of error

Definition at line 382 of file img_e7.c.

382 {
383 ECAT7_mainheader main_header;
384 ECAT7_imageheader image_header;
385 ECAT7_scanheader scan_header;
386 FILE *fp;
387 int matrixId, ret;
388 float *fdata, *fptr;
389
390
391 if(IMG_TEST) printf("imgWriteEcat7(%s, *img)\n", fname);
392 if(IMG_TEST>1 && ECAT7_TEST==0) ECAT7_TEST=1;
393 /* Check the arguments */
394 if(fname==NULL) return(1);
395 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
396 imgSetStatus(img, STATUS_FAULT); return(2);}
397 if(img->type!=IMG_TYPE_RAW && img->type!=IMG_TYPE_IMAGE) {
398 imgSetStatus(img, STATUS_FAULT); return(2);}
399
400 /* Check image size */
401 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024) {
402 imgSetStatus(img, STATUS_INVALIDHEADER); return(2);}
403
404 /* Initiate headers */
405 memset(&main_header, 0, sizeof(ECAT7_mainheader));
406 memset(&image_header,0, sizeof(ECAT7_imageheader));
407 memset(&scan_header, 0, sizeof(ECAT7_scanheader));
408
409 /* Set main header */
410 imgSetEcat7MHeader(img, &main_header);
411 main_header.bin_size=img->sampleDistance/10.0;
412
413 /* Allocate memory for matrix float data */
414 long long pxlNr=img->dimx*img->dimy*img->dimz;
415 fdata=(float*)malloc(pxlNr*sizeof(float));
416 if(fdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return(3);}
417
418 /* Open file, write main header and initiate matrix list */
419 fp=ecat7Create(fname, &main_header);
420 if(fp==NULL) {free(fdata); imgSetStatus(img, STATUS_NOWRITEPERM); return(6);}
421
422 /* Set (most of) subheader contents */
423 if(img->type==IMG_TYPE_RAW) {
424 scan_header.x_resolution=img->sampleDistance/10.0;
425 scan_header.num_dimensions=4;
426 if(img->dimz==239) {
427 scan_header.num_z_elements[0]=63;
428 scan_header.num_z_elements[1]=106;
429 scan_header.num_z_elements[2]=70;
430 } else {
431 scan_header.num_z_elements[0]=img->dimz;
432 }
433 scan_header.storage_order=1;
434 scan_header.data_type=ECAT7_SUNI2;
435 scan_header.num_r_elements=img->dimx;
436 scan_header.num_angles=img->dimy;
437 } else if(img->type==IMG_TYPE_IMAGE) {
438 image_header.num_dimensions=3;
439 image_header.z_dimension=img->dimz;
440 image_header.data_type=ECAT7_SUNI2;
441 image_header.x_dimension=img->dimx;
442 image_header.y_dimension=img->dimy;
443 image_header.recon_zoom=img->zoom;
444 image_header.x_pixel_size=0.1*img->sizex;
445 image_header.y_pixel_size=0.1*img->sizey;
446 image_header.z_pixel_size=0.1*img->sizez;
447 image_header.x_resolution=0.1*img->resolutionx;
448 image_header.y_resolution=0.1*img->resolutiony;
449 image_header.z_resolution=0.1*img->resolutionz;
450 img->quatern[6]=img->sizex; img->quatern[9]=img->sizex;
451 img->quatern[11]=img->sizey; img->quatern[13]=img->sizey;
452 img->quatern[16]=img->sizez; img->quatern[17]=img->sizez;
453 image_header.mt_1_1=img->mt[0];
454 image_header.mt_1_2=img->mt[1];
455 image_header.mt_1_3=img->mt[2];
456 image_header.mt_1_4=img->mt[3];
457 image_header.mt_2_1=img->mt[4];
458 image_header.mt_2_2=img->mt[5];
459 image_header.mt_2_3=img->mt[6];
460 image_header.mt_2_4=img->mt[7];
461 image_header.mt_3_1=img->mt[8];
462 image_header.mt_3_2=img->mt[9];
463 image_header.mt_3_3=img->mt[10];
464 image_header.mt_3_4=img->mt[11];
465 }
466
467 /* Write each matrix */
468 for(int fi=0; fi<img->dimt; fi++) {
469
470 /* Create new matrix id (i.e. matnum) */
471 matrixId=ecat7_val_to_id(fi+1, 1, 1, 0, 0);
472
473 /* Copy matrix pixel values to fdata */
474 fptr=fdata;
475 for(int pi=0; pi<img->dimz; pi++)
476 for(int yi=0; yi<img->dimy; yi++)
477 for(int xi=0; xi<img->dimx; xi++)
478 if(isfinite(img->m[pi][yi][xi][fi])) *fptr++=img->m[pi][yi][xi][fi]; else *fptr++=0.0;
479
480 /* Write subheader and data */
481 fptr=fdata;
482 if(img->type==IMG_TYPE_RAW) {
483 scan_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
484 scan_header.frame_duration=
485 (int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
486 scan_header.prompts=temp_roundf(img->prompts[fi]);
487 scan_header.delayed=temp_roundf(img->randoms[fi]);
488 /*ecat7PrintScanheader(&scan_header, stdout);*/
489 ret=ecat7WriteScanMatrix(fp, matrixId, &scan_header, fptr);
490 } else if(img->type==IMG_TYPE_IMAGE) {
491 image_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
492 image_header.frame_duration=(int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
494 image_header.decay_corr_fctr=img->decayCorrFactor[fi];
495 else
496 image_header.decay_corr_fctr=0.0;
497 /*ecat7PrintImageheader(&image_header, stdout);*/
498 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
499 } else {
500 free(fdata); fclose(fp); imgSetStatus(img, STATUS_UNSUPPORTED); return(8);
501 }
502 if(ret) {
503 if(IMG_TEST) {printf("matrixId=%d ret=%d\n", matrixId, ret);}
504 free(fdata); fclose(fp); imgSetStatus(img, STATUS_DISKFULL); return(7);
505 }
506
507 } /* next matrix */
508 free(fdata); fclose(fp);
509
510 imgSetStatus(img, STATUS_OK);
511 return(0);
512}
int ecat7WriteScanMatrix(FILE *fp, int matrix_id, ECAT7_scanheader *h, float *fdata)
Definition ecat7w.c:802

Referenced by imgWrite().

◆ imgWriteEcat7Frame()

int imgWriteEcat7Frame ( const char * fname,
int frame_to_write,
IMG * img,
int frame_index )
extern

Write one PET frame from IMG data struct into ECAT 7 image or sinogram file; format is specified in IMG struct. This function can be called repeatedly to write all frames one at a time to conserve memory. However, file with just mainheader and matrix list without any previous frame is not accepted.

Parameters
fnamename of file where IMG contents will be written. If file does not exist, it is created. Make sure to delete existing file, unless you want to add data
frame_to_writePET frame number (1..frameNr) which will be written: If set to 0, frame data will be written to an existing or new PET file as a new frame, never overwriting existing data. If >0, then frame data is written as specified frame number, overwriting any data existing with the same frame number
imgpointer to the IMG data struct
frame_indexIMG frame index (0..dimt-1) which will be written
Returns
errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.

Definition at line 1295 of file img_e7.c.

1297 {
1298 IMG test_img;
1299 int ret=0, matrixId;
1300 ECAT7_mainheader main_header;
1301 ECAT7_imageheader image_header;
1302 ECAT7_scanheader scan_header;
1303 ECAT7_2Dscanheader scan2d_header;
1304 ECAT7_polmapheader polmap_header;
1305 void *sub_header=NULL;
1306 FILE *fp;
1307 float *fdata=NULL, *fptr;
1308
1309
1310 if(IMG_TEST) printf("\nimgWriteEcat7Frame(%s, %d, *img, %d)\n",
1311 fname, frame_to_write, frame_index);
1312
1313 /*
1314 * Check the input
1315 */
1316 if(fname==NULL) return STATUS_FAULT;
1317 if(img==NULL) return STATUS_FAULT;
1318 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
1319 if(frame_to_write<0) return STATUS_FAULT;
1320 if(frame_index<0 || frame_index>=img->dimt) return STATUS_FAULT;
1321 if(img->_fileFormat!=IMG_E7 &&
1322 img->_fileFormat!=IMG_POLARMAP &&
1323 img->_fileFormat!=IMG_E7_2D) return STATUS_FAULT;
1324
1325 /* Check image size */
1326 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024)
1327 return STATUS_INVALIDHEADER;
1328
1329 /* Initiate headers */
1330 memset(&main_header, 0, sizeof(ECAT7_mainheader));
1331 memset(&image_header,0, sizeof(ECAT7_imageheader));
1332 memset(&scan_header, 0, sizeof(ECAT7_scanheader));
1333 memset(&scan2d_header, 0, sizeof(ECAT7_2Dscanheader));
1334 memset(&polmap_header,0, sizeof(ECAT7_polmapheader));
1335 imgInit(&test_img);
1336
1337
1338 /*
1339 * If file does not exist, then create it with new mainheader,
1340 * and if it does exist, then read and check header information.
1341 * Create or edit mainheader to contain correct frame nr.
1342 * In any case, leave file pointer open for write.
1343 */
1344 if(access(fname, 0) == -1) { /* file does not exist */
1345
1346 /* Set main header */
1347 imgSetEcat7MHeader(img, &main_header);
1348 main_header.bin_size=img->sampleDistance/10.0;
1349 if(frame_to_write==0) frame_to_write=1;
1350 main_header.num_frames=frame_to_write;
1351
1352 /* Open file, write main header and initiate matrix list */
1353 fp=ecat7Create(fname, &main_header); if(fp==NULL) return STATUS_NOWRITEPERM;
1354
1355 } else { /* file exists */
1356
1357 /* Read header information for checking */
1358 ret=imgReadEcat7Header(fname, &test_img); if(ret!=0) return ret;
1359 /* Check that file format is the same */
1360 if(img->_fileFormat!=test_img._fileFormat || img->type!=test_img.type)
1361 return STATUS_WRONGFILETYPE;
1362 /* Check that matrix sizes are the same */
1363 if(img->dimz!=test_img.dimz || img->dimx!=test_img.dimx ||
1364 img->dimy!=test_img.dimy)
1365 return STATUS_VARMATSIZE;
1366 imgEmpty(&test_img);
1367
1368 /* Open the file for read and write */
1369 if((fp=fopen(fname, "r+b"))==NULL) return STATUS_NOWRITEPERM;
1370
1371 /* Read the mainheader, set new frame number, and write it back */
1372 if((ret=ecat7ReadMainheader(fp, &main_header))!=0)
1373 return STATUS_NOMAINHEADER;
1374 if(frame_to_write==0) frame_to_write=main_header.num_frames+1;
1375 if(main_header.num_frames<frame_to_write)
1376 main_header.num_frames=frame_to_write;
1377 if((ret=ecat7WriteMainheader(fp, &main_header))!=0)
1378 return STATUS_NOWRITEPERM;
1379
1380 }
1381 if(IMG_TEST>2) {
1382 printf("frame_to_write := %d\n", frame_to_write);
1383 }
1384
1385 /* Allocate memory for matrix float data */
1386 long long pxlNr=img->dimx*img->dimy*img->dimz; /* for 2D too! */
1387 fdata=(float*)malloc(pxlNr*sizeof(float));
1388 if(fdata==NULL) {fclose(fp); return STATUS_NOMEMORY;}
1389
1390 /* Set matrix subheader */
1391 if(img->_fileFormat==IMG_E7) {
1392 if(img->type==IMG_TYPE_RAW) sub_header=(void*)&scan_header;
1393 else sub_header=&image_header;
1394 } else if(img->_fileFormat==IMG_E7_2D) {
1395 if(img->type==IMG_TYPE_RAW) sub_header=(void*)&scan_header;
1396 else sub_header=(void*)&image_header;
1397 } else if(img->_fileFormat==IMG_POLARMAP) {
1398 sub_header=(void*)&polmap_header;
1399 } else {fclose(fp); return STATUS_FAULT;}
1400 imgSetEcat7SHeader(img, sub_header);
1401
1402 /* Copy matrix pixel values to fdata */
1403 fptr=fdata;
1404 for(int zi=0; zi<img->dimz; zi++)
1405 for(int yi=0; yi<img->dimy; yi++)
1406 for(int xi=0; xi<img->dimx; xi++)
1407 if(isfinite(img->m[zi][yi][xi][frame_index])) *fptr++=img->m[zi][yi][xi][frame_index]; else *fptr++=0.0;
1408
1409 /* Write subheader and data, and set the rest of subheader contents */
1410 fptr=fdata; ret=-1;
1411 if(img->_fileFormat==IMG_E7) {
1412 /* Create new matrix id (i.e. matnum) */
1413 matrixId=ecat7_val_to_id(frame_to_write, 1, 1, 0, 0);
1414 if(img->type==IMG_TYPE_RAW) {
1415 scan_header.frame_start_time=
1416 (int)temp_roundf(1000.*img->start[frame_index]);
1417 scan_header.frame_duration=
1418 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1419 scan_header.prompts=temp_roundf(img->prompts[frame_index]);
1420 scan_header.delayed=temp_roundf(img->randoms[frame_index]);
1421 ret=ecat7WriteScanMatrix(fp, matrixId, &scan_header, fptr);
1422 } else {
1423 image_header.frame_start_time=
1424 (int)temp_roundf(1000.*img->start[frame_index]);
1425 image_header.frame_duration=
1426 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1428 image_header.decay_corr_fctr=img->decayCorrFactor[frame_index];
1429 else
1430 image_header.decay_corr_fctr=0.0;
1431 /*ecat7PrintImageheader(&image_header, stdout);*/
1432 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
1433 }
1434 } else if(img->_fileFormat==IMG_E7_2D) {
1435 for(int zi=0; zi<img->dimz; zi++, fptr+=img->dimx*img->dimy) {
1436 /* Create new matrix id (i.e. matnum) */
1437 matrixId=ecat7_val_to_id(frame_to_write, img->planeNumber[zi], 1, 0, 0);
1438 if(img->type==IMG_TYPE_RAW) {
1439 scan2d_header.frame_start_time=
1440 (int)temp_roundf(1000.*img->start[frame_index]);
1441 scan2d_header.frame_duration=
1442 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1443 scan2d_header.prompts=temp_roundf(img->prompts[frame_index]);
1444 scan2d_header.delayed=temp_roundf(img->randoms[frame_index]);
1445 ret=ecat7Write2DScanMatrix(fp, matrixId, &scan2d_header, fptr);
1446 } else {
1447 image_header.frame_start_time=
1448 (int)temp_roundf(1000.*img->start[frame_index]);
1449 image_header.frame_duration=
1450 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1452 image_header.decay_corr_fctr=img->decayCorrFactor[frame_index];
1453 else
1454 image_header.decay_corr_fctr=0.0;
1455 ret=ecat7WriteImageMatrix(fp, matrixId, &image_header, fptr);
1456 }
1457 if(ret!=0) break;
1458 } /* next plane */
1459 } else if(img->_fileFormat==IMG_POLARMAP) {
1460 /* Create new matrix id (i.e. matnum) */
1461 matrixId=ecat7_val_to_id(frame_to_write, 1, 1, 0, 0);
1462 polmap_header.frame_start_time=
1463 (int)temp_roundf(1000.*img->start[frame_index]);
1464 polmap_header.frame_duration=
1465 (int)temp_roundf(1000.*(img->end[frame_index]-img->start[frame_index]));
1466 ret=ecat7WritePolarmapMatrix(fp, matrixId, &polmap_header, fptr);
1467 }
1468 free(fdata); fclose(fp);
1469 if(ret) return STATUS_DISKFULL;
1470
1471 return STATUS_OK;
1472}
int ecat7WritePolarmapMatrix(FILE *fp, int matrix_id, ECAT7_polmapheader *h, float *fdata)
Definition ecat7w.c:888
void imgSetEcat7SHeader(IMG *img, void *h)
Definition img_e7.c:1482

Referenced by imgWriteFrame().

◆ imgWriteFrame()

int imgWriteFrame ( const char * fname,
int frame_to_write,
IMG * img,
int frame_index )
extern

Write one PET frame from IMG data struct into a supported PET image or sinogram file.

This function can be called repeatedly to write all frames one at a time to conserve memory.

Currently supported file formats are ECAT 6.3 images and sinograms, and ECAT 7.x 2D and 3D images and sinograms, and NIfTI-1 images. Analyze 7.5 images are NOT supported (because global min and max would be needed). SIF for NIfTI-1 files is not written by this function.

See also
imgReadFrame, imgReadHeader, imgWrite
Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
Parameters
fnameName of file where IMG contents will be written. If file exists, data is either overwritten or catenated as a new frame, depending on the following arguments. If file does not exist, it is created.
frame_to_writePET frame number (1..frameNr) which will be written: If set to 0, frame data will be written to an existing or new PET file as a new frame, never overwriting existing data. If >0, then frame data is written as specified frame number, overwriting any data existing with the same frame number
imgPointer to the IMG data structure.
frame_indexIMG frame index (0..dimt-1) which will be written.

Definition at line 392 of file imgfile.c.

408 {
409 int ret=0;
410
411 if(IMG_TEST>0) {
412 printf("\nimgWriteFrame(%s, %d, *img, %d)\n", fname, frame_to_write, frame_index);
413 fflush(stdout);
414 }
415 if(IMG_TEST>3) {
416 char buf[32];
417 if(!ctime_r_int(&img->scanStart, buf)) strcpy(buf, "1900-01-01 00:00:00");
418 fprintf(stdout, " scan_start_time := %s\n", buf);
419 }
420
421 /*
422 * Check the input
423 */
424 if(fname==NULL) return STATUS_FAULT;
425 if(img==NULL) return STATUS_FAULT;
426 if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
427 if(frame_to_write<0) return STATUS_FAULT;
428 if(frame_index<0 || frame_index>=img->dimt) return STATUS_FAULT;
429
430
431 /*
432 * Call separate function for each supported file format
433 */
434 imgFormatFromFName(img, fname);
435 switch(img->_fileFormat) {
436 case IMG_E7:
437 case IMG_E7_2D:
438 case IMG_POLARMAP:
439 ret=imgWriteEcat7Frame(fname, frame_to_write, img, frame_index);
440 break;
441 case IMG_E63:
442 ret=imgWriteEcat63Frame(fname, frame_to_write, img, frame_index);
443 break;
444 case IMG_ANA:
445 case IMG_ANA_L:
446 ret=STATUS_UNSUPPORTED;
447 /* Not supported because would require global min&max values
448 * if saved in short ints which is now the only possibility
449 * ret=imgWriteAnaFrame(fname, frame_to_write, img, frame_index);
450 */
451 break;
452 case IMG_NIFTI_1D:
453 case IMG_NIFTI_1S:
454#if(0)
455 /* Not supported because would require global min&max values
456 * if saved in short ints which is now the only possibility
457 */
458 ret=STATUS_UNSUPPORTED;
459#endif
460 /* Nifti is currently always written as floats, therefore
461 global min and max pixel values are not yet needed */
462 ret=imgWriteNiftiFrame(fname, frame_to_write, img, frame_index, 0, 0, IMG_TEST-2);
463 break;
464 default:
465 ret=STATUS_UNSUPPORTED;
466 }
467 imgSetStatus(img, ret);
468 return ret;
469}
int imgWriteEcat63Frame(const char *fname, int frame_to_write, IMG *img, int frame_index)
Definition img_e63.c:1711
int imgWriteEcat7Frame(const char *fname, int frame_to_write, IMG *img, int frame_index)
Definition img_e7.c:1295
int imgWriteNiftiFrame(const char *dbname, int frame_to_write, IMG *img, int frame_index, float fmin, float fmax, int verbose)
Definition img_nii.c:594

Referenced by imgAnalyzeToEcat(), imgMicropetPETToEcat7(), and imgNiftiToEcat().

◆ imgWriteNifti()

int imgWriteNifti ( const char * dbname,
IMG * img,
int save_sif,
int verbose )
extern

Write NIfTI-1 image.

Nifti database name can be given with path, however, path is not created in here. IMG field _fileFormat determines whether NIfTI is written in single file format (*.nii) or dual file format (*.hdr and *.img). Optionally SIF file with .sif extension is saved to store frame times.

Returns
0 if ok, and otherwise IMG status code (<>0); sets IMG->statmsg in case of an error.
See also
imgInit, imgReadNiftiFirstFrame, imgReadNiftiHeader, imgReadNifti
Parameters
dbnameNifti database name with path, with or without extension
imgPointer to IMG structure containing the image data to be written
save_sifSave (1) or do not save (0) SIF
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 811 of file img_nii.c.

820 {
821 int ret;
822 char imgfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
823 float fmin, fmax;
824 SIF sif;
825
826 if(verbose>0) {
827 printf("imgWriteNifti(%s, *img, %d, ...)\n", dbname, save_sif);
828 fflush(stdout);
829 }
830
831 /*
832 * Check the input
833 */
834 if(dbname==NULL || !dbname[0]) {
835 imgSetStatus(img, STATUS_FAULT);
836 if(verbose>0) fprintf(stderr, "Error: invalid filename\n");
837 return(STATUS_FAULT);
838 }
839 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
840 if(img!=NULL) imgSetStatus(img, STATUS_FAULT);
841 if(verbose>0) fprintf(stderr, "Error: invalid IMG argument\n");
842 return(STATUS_FAULT);
843 }
845 imgSetStatus(img, STATUS_FAULT);
846 if(verbose>0) fprintf(stderr, "Error: invalid file format setting\n");
847 return STATUS_FAULT;
848 }
849
850 /* Create the NIfTI filename(s) */
851 ret=niftiCreateFNames(dbname, hdrfile, imgfile, siffile, img->_fileFormat);
852 if(ret!=0) {
853 if(verbose>0) fprintf(stderr, " Error: invalid NIfTI name %s\n", dbname);
854 imgSetStatus(img, STATUS_FAULT);
855 return STATUS_FAULT;
856 }
857 /* Delete previous NIfTI */
858 ret=niftiRemove(dbname, 0, verbose-1);
859 if(ret!=0) {
860 if(verbose>0) fprintf(stderr, " Error: cannot delete previous NIfTI.\n");
861 imgSetStatus(img, STATUS_CANNOTERASE);
862 return STATUS_CANNOTERASE;
863 }
864
865 /*
866 * Get the global min and max pixel values;
867 * those are currently only saved in header, but may be later
868 * needed for scaling pixels to short ints
869 */
870 if(verbose>1) {fprintf(stdout, " searching min and max\n"); fflush(stdout);}
871 ret=imgMinMax(img, &fmin, &fmax);
872 if(ret) {
873 if(verbose>0) fprintf(stderr, " Error: %s\n", imgStatus(ret));
874 imgSetStatus(img, STATUS_NOIMGDATA);
875 return STATUS_NOIMGDATA;
876 }
877 if(verbose>1) {
878 printf(" global_min := %g\n global_max := %g\n", fmin, fmax);
879 fflush(stdout);
880 }
881 /*
882 * Write the image frames
883 */
884 for(int fi=0, ret=0; fi<img->dimt; fi++) {
885 ret=imgWriteNiftiFrame(dbname, fi+1, img, fi, fmin, fmax, verbose-2);
886 if(ret!=STATUS_OK) break;
887 if(verbose>4) {printf(" frame written.\n"); fflush(stdout);}
888 } // next frame
889 //printf("ret := %d\n", ret);
890 if(ret!=STATUS_OK) {
891 niftiRemove(dbname, img->_fileFormat, verbose-3);
892 if(verbose>0) fprintf(stderr, "Error: %s.\n", imgStatus(ret));
893 return ret;
894 }
895
896 /* If SIF is not needed, then that's it */
897 if(save_sif==0) {
898 imgSetStatus(img, STATUS_OK);
899 return 0;
900 }
901
902 /* Copy contents from IMG to SIF and save SIF */
903 sifInit(&sif);
904 /* Try to read existing SIF */
905 ret=sifRead(siffile, &sif);
906 if(ret==0) { // SIF could be read
907 if(sif.frameNr==img->dimt) {
908 /* If size matches, then update the contents, but keep counts, in case
909 previous SIF comes with actual count info from scanner */
910 ret=img2sif(img, &sif, 1, 1, 0, verbose-3);
911 } else {
912 /* otherwise create SIF contents */
913 ret=img2sif(img, &sif, 1, 1, 2, verbose-3);
914 }
915 } else {
916 /* otherwise create SIF contents */
917 ret=img2sif(img, &sif, 1, 1, 2, verbose-3);
918 }
919 if(ret!=0) {
920 if(verbose>0) fprintf(stderr, " Error: cannot create SIF contents.\n");
921 imgSetStatus(img, STATUS_CANNOTWRITE);
922 sifEmpty(&sif);
923 return STATUS_CANNOTWRITE;
924 }
925 /* Write SIF */
926 ret=sifWrite(&sif, siffile);
927 if(ret!=0) {
928 if(verbose>0) fprintf(stderr, " Error: cannot write %s\n", siffile);
929 imgSetStatus(img, STATUS_CANNOTWRITE);
930 sifEmpty(&sif);
931 return STATUS_CANNOTWRITE;
932 }
933 sifEmpty(&sif);
934
935 imgSetStatus(img, STATUS_OK);
936 return 0;
937}
int niftiCreateFNames(const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
Definition nifti.c:44
int niftiRemove(const char *dbname, int fileformat, int verbose)
Definition nifti.c:100

Referenced by imgWrite().

◆ imgWriteNiftiFrame()

int imgWriteNiftiFrame ( const char * dbname,
int frame_to_write,
IMG * img,
int frame_index,
float fmin,
float fmax,
int verbose )
extern

Write one PET frame from IMG data struct into NIfTI file.

This function can be called repeatedly to write all frames one at a time to conserve memory. This function does not write SIF. Single or dual file format is determined based on _fileFormat field in IMG struct. Byte order is the not changed.

Returns
Returns errstatus, which is STATUS_OK (0) when call was successful, and >0 in case of an error.
See also
imgReadNiftiFrame
Parameters
dbnameName of NIfTI file where IMG contents will be written. If file does not exist, it is created. Make sure to delete existing file, unless you want to add data.
frame_to_writePET frame number (1..frameNr) which will be written: If set to 0, frame data will be written to an existing or new PET file as a new additional frame, never overwriting existing data. If >0, then frame data is written as specified frame number, overwriting any data existing with the same frame number
imgpointer to the IMG data struct.
frame_indexIMG frame index (0..dimt-1) which will be written.
fminminimum pixel value in all frames that will be written; used only when writing the first frame.
fmaxmaximum pixel value in all frames that will be written; used only when writing the first frame.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 594 of file img_nii.c.

617 {
618 IMG test_img;
619 NIFTI_DSR dsr;
620 int ret=0, fileis=0;
621 char imgfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
622 char tmp[256];
623 FILE *fp;
624 float *fdata=NULL, *fptr;
625
626
627 if(verbose>0) {
628 printf("\nimgWriteNiftiFrame(%s, %d, *img, %d, %g, %g, ...)\n",
629 dbname, frame_to_write, frame_index, fmin, fmax);
630 fflush(stdout);
631 }
632 /*
633 * Check the input
634 */
635 if(dbname==NULL || !dbname[0]) {
636 imgSetStatus(img, STATUS_FAULT);
637 if(verbose>0) fprintf(stderr, "Error: invalid filename\n");
638 return(STATUS_FAULT);
639 }
640 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
641 if(img!=NULL) imgSetStatus(img, STATUS_FAULT);
642 if(verbose>0) fprintf(stderr, "Error: invalid IMG argument\n");
643 return(STATUS_FAULT);
644 }
645 if(frame_index<0 || frame_index>img->dimt-1 || frame_to_write<0) {
646 imgSetStatus(img, STATUS_FAULT);
647 if(verbose>0) fprintf(stderr, "Error: invalid frame settings\n");
648 return STATUS_FAULT;
649 }
651 imgSetStatus(img, STATUS_FAULT);
652 if(verbose>0) fprintf(stderr, "Error: invalid file format setting\n");
653 return STATUS_FAULT;
654 }
655
656 /*
657 * If NIfTI does not exist, then create it with new header,
658 * and if it does exist, then read and check header information.
659 * Create or edit header to contain correct frame nr.
660 * Determine the global scaling factors.
661 */
662 imgInit(&test_img);
663 fileis=niftiExists(dbname, hdrfile, imgfile, siffile, &dsr, verbose-2, NULL);
664 if(fileis==0) { // not existing
665 if(verbose>1) {
666 printf(" writing 1st frame to a new file\n"); fflush(stdout);}
667
668 /* Create database filenames */
669 niftiCreateFNames(dbname, hdrfile, imgfile, siffile, img->_fileFormat);
670
671 /* Set main header */
672 ret=imgSetNiftiHeader(img, dbname, &dsr, fmin, fmax, verbose-1);
673 if(ret!=0) {
674 if(verbose>0) fprintf(stderr, "Error: cannot read NIfTI header\n");
675 return STATUS_INVALIDHEADER;
676 }
677 if(frame_to_write==0) frame_to_write=1;
678 dsr.h.dim[4]=1;
679
680 /* Write NIfTI header */
681 ret=niftiWriteHeader(hdrfile, &dsr, verbose-1, tmp);
682 if(ret!=0) {
683 if(verbose>0) fprintf(stderr, "Error in niftiWriteHeader(): %s\n", tmp);
684 return STATUS_CANTWRITEHEADERFILE;
685 }
686
687 /* Remove dual format datafile if necessary */
688 if(img->_fileFormat==IMG_NIFTI_1D)
689 if(access(imgfile, 0) != -1) {
690 if(verbose>0) printf(" removing %s\n", imgfile);
691 remove(imgfile);
692 }
693
694 } else { /* NIfTI exists */
695 if(verbose>1) printf(" adding frame to an existing file\n");
696
697 /* Read header information for checking */
698 ret=imgGetNiftiHeader(&test_img, &dsr, verbose-1);
699 if(ret!=0) {
700 if(verbose>0) fprintf(stderr, "Error: cannot read NIfTI header\n");
701 imgEmpty(&test_img); return ret;
702 }
703 /* Check that file format is the same */
704 if(img->_fileFormat!=test_img._fileFormat) {
705 if(verbose>0) {
706 fprintf(stderr, "Error: different file format\n");
707 printf(" new._fileFormat:=%d\n", img->_fileFormat);
708 printf(" prev._fileFormat:=%d\n", test_img._fileFormat);
709 }
710 imgEmpty(&test_img); return STATUS_WRONGFILETYPE;
711 }
712 /* Check also data type, if available */
713 if(img->_dataType>0 && test_img._dataType>0 &&
714 img->_dataType!=test_img._dataType)
715 {
716 if(verbose>0) {
717 fprintf(stderr, "Error: different datatype\n");
718 printf(" new._dataType:=%d\n", img->_dataType);
719 printf(" prev._dataType:=%d\n", test_img._dataType);
720 }
721 imgEmpty(&test_img); return STATUS_WRONGFILETYPE;
722 }
723 /* Check that matrix sizes are the same */
724 if(img->dimz!=test_img.dimz || img->dimx!=test_img.dimx ||
725 img->dimy!=test_img.dimy) {
726 if(verbose>0) fprintf(stderr, "Error: different matrix size\n");
727 imgEmpty(&test_img); return STATUS_VARMATSIZE;}
728 imgEmpty(&test_img);
729
730 /* Set new frame number in NIfTI header */
731 if(frame_to_write==0) frame_to_write=dsr.h.dim[4]+1;
732 if(dsr.h.dim[4]<frame_to_write) {
733 if(dsr.h.dim[4]+1<frame_to_write) {
734 if(verbose>0) fprintf(stderr, "Error: missing matrix\n");
735 return STATUS_MISSINGMATRIX;
736 }
737 dsr.h.dim[4]=frame_to_write;
738 }
739 /* and save the updated header */
740 if((ret=niftiWriteHeader(hdrfile, &dsr, verbose-1, tmp))!=0) {
741 if(verbose>0) fprintf(stderr, "Error: %s.\n", tmp);
742 return STATUS_NOWRITEPERM;
743 }
744 }
745 if(verbose>2) {
746 printf("frame_to_write := %d\n", frame_to_write);
747 printf("vox_offset := %d\n", (int)dsr.h.vox_offset);
748 printf("hdrfile := %s\n", hdrfile);
749 printf("imgfile := %s\n", imgfile);
750 printf("siffile := %s\n", siffile);
751 printf("magic := %s\n", dsr.h.magic);
752 }
753
754 /* Open voxel data file, not removing possible old contents like header */
755 if(img->_fileFormat==IMG_NIFTI_1D && frame_to_write==1)
756 fp=fopen(imgfile, "wb");
757 else
758 fp=fopen(imgfile, "r+b");
759 if(fp==NULL) {
760 if(verbose>0) fprintf(stderr, "Error: cannot open %s for write.\n",imgfile);
761 return STATUS_CANTWRITEIMGFILE;
762 }
763
764 /* Move file pointer to the place of current frame */
765 long long voxNr=img->dimz*img->dimy*img->dimx;
766 if(fseeko(fp, (int)dsr.h.vox_offset+(frame_to_write-1)*voxNr*sizeof(float),
767 SEEK_SET)!=0)
768 {
769 if(verbose>0) fprintf(stderr, "Error: invalid file write position.\n");
770 fclose(fp); return STATUS_MISSINGMATRIX;
771 }
772
773 /* Allocate memory for matrix float data (one plane) */
774 fdata=(float*)calloc(voxNr, sizeof(float));
775 if(fdata==NULL) {
776 if(verbose>0) fprintf(stderr, "Error: out of memory.\n");
777 fclose(fp); return STATUS_NOMEMORY;
778 }
779
780 /* Write voxel values as floats */
781 fptr=fdata;
782 for(int zi=0; zi<img->dimz; zi++)
783 for(int yi=0; yi<img->dimy; yi++)
784 for(int xi=0; xi<img->dimx; xi++, fptr++)
785 *fptr=img->m[zi][yi][xi][frame_index];
786 fptr=fdata;
787 if(fwrite(fptr, sizeof(float), voxNr, fp) != (unsigned int)voxNr) {
788 if(verbose>0) fprintf(stderr, "Error: disk full or no write permission.\n");
789 free(fdata); fclose(fp); return STATUS_CANTWRITEIMGFILE;
790 }
791 free(fdata);
792 fclose(fp);
793
794 return STATUS_OK;
795}
int imgSetNiftiHeader(IMG *img, const char *dbname, NIFTI_DSR *dsr, float fmin, float fmax, int verbose)
Definition img_nii.c:471
int niftiWriteHeader(char *filename, NIFTI_DSR *dsr, int verbose, char *status)
Definition nifti.c:844

Referenced by imgWriteFrame(), and imgWriteNifti().

◆ imgWritePolarmap()

int imgWritePolarmap ( const char * fname,
IMG * img )
extern

Write ECAT 7 polar map.

Parameters
fnameoutput filename
imgpointer to image structure
Returns
0 if ok, 1 invalid input, 2 image status is not 'occupied', 3 failed to allocate memory for data, 6 faield to create file, 7 failed to write data, 8 image type not supported, sets IMG->statmsg in case of error

Definition at line 661 of file img_e7.c.

661 {
662 ECAT7_mainheader main_header;
663 ECAT7_polmapheader polmap_header;
664 FILE *fp;
665 int matrixId, ret;
666 float *fdata, *fptr;
667
668
669 if(IMG_TEST) printf("imgWritePolarmap(%s, *img)\n", fname);
670 if(IMG_TEST>1 && ECAT7_TEST==0) ECAT7_TEST=1;
671 /* Check the arguments */
672 if(fname==NULL) return(1);
673 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) {
674 imgSetStatus(img, STATUS_FAULT); return(2);}
675 if(img->type!=IMG_TYPE_POLARMAP) {
676 imgSetStatus(img, STATUS_FAULT); return(2);}
677
678 /* Check image size */
679 if(img->dimt>511 || img->dimz>255 || img->dimx>1024 || img->dimy>1024) {
680 imgSetStatus(img, STATUS_INVALIDHEADER); return(2);}
681
682 /* Initiate headers */
683 memset(&main_header, 0, sizeof(ECAT7_mainheader));
684 memset(&polmap_header,0, sizeof(ECAT7_polmapheader));
685
686 /* Set main header */
687 imgSetEcat7MHeader(img, &main_header);
688 main_header.bin_size=img->sampleDistance/10.0;
689
690 /* Allocate memory for matrix float data */
691 long long pxlNr=img->dimx*img->dimy*img->dimz;
692 fdata=(float*)malloc(pxlNr*sizeof(float));
693 if(fdata==NULL) {imgSetStatus(img, STATUS_NOMEMORY); return(3);}
694
695 /* Open file, write main header and initiate matrix list */
696 fp=ecat7Create(fname, &main_header);
697 if(fp==NULL) {free(fdata); imgSetStatus(img, STATUS_NOWRITEPERM); return(6);}
698
699 /* Set (most of) subheader contents */
700 imgSetEcat7SHeader(img, &polmap_header);
701
702 /* Write each matrix */
703 for(int fi=0; fi<img->dimt; fi++) {
704
705 /* Create new matrix id (i.e. matnum) */
706 matrixId=ecat7_val_to_id(fi+1, 1, 1, 0, 0);
707
708 /* Copy matrix pixel values to fdata */
709 fptr=fdata;
710 for(int pi=0; pi<img->dimz; pi++)
711 for(int yi=0; yi<img->dimy; yi++)
712 for(int xi=0; xi<img->dimx; xi++)
713 if(isfinite(img->m[pi][yi][xi][fi])) *fptr++=img->m[pi][yi][xi][fi]; else *fptr++=0.0;
714
715 /* Write subheader and data */
716 fptr=fdata;
717 polmap_header.frame_start_time=(int)temp_roundf(1000.*img->start[fi]);
718 polmap_header.frame_duration=
719 (int)temp_roundf(1000.*(img->end[fi]-img->start[fi]));
720 /*ecat7PrintImageheader(&image_header, stdout);*/
721 ret=ecat7WritePolarmapMatrix(fp, matrixId, &polmap_header, fptr);
722 if(ret) {
723 if(IMG_TEST) {printf("matrixId=%d ret=%d\n", matrixId, ret);}
724 free(fdata); fclose(fp); imgSetStatus(img, STATUS_DISKFULL); return(7);
725 }
726
727 } /* next matrix */
728 free(fdata); fclose(fp);
729
730 imgSetStatus(img, STATUS_OK);
731 return(0);
732}

Referenced by imgWrite().

◆ interfile_read()

int interfile_read ( char headerName[256],
char searchWord[256],
char returnValue[256],
char errorMessage[300] )
extern

The function searches the keyword in the header and passes the value belonging to that value back to the main program. The name of the header (string 'headerName') and the requested keyword (string 'searchWord') are passed to the function. It passes back the value of the keyword (string 'returnValue') and possibly an error message or warning (string 'errorMessage'). So the values are passed back as strings. The interpretation (conversion to integer, float, time etc) is up to the programmer.

The interfile header has to comply to the following rules:

  • first line in the file is '!INTERFILE'
  • maximal length of a line is 512 characters
  • A line has two fields sperated by ':=' (keyword := value)
  • maximal length of keyword and value is 256 characters.
  • no header entries after a line '!END OF INTERFILE'
  • a line starting with a semicolon ';' is a comment
Parameters
headerNameheader file name
searchWordkeyword to look for
returnValuevalue for keyword in header
errorMessageerror message/warnings. In case there is a error message it will be returnd as string in the variable 'errmsg'.
Returns
0 if ok, 1 keyword appears more than once in the interfile header (value of last occurence of keyword is returned), 2 keyword not found in interfile header (returned value is empty (i.e. contains '/0's only)), 3 interfile header cold not be opened for reading (returned value is empty (i.e. contains '/0's only)), 4 wrong file format?! (No '!INTERFILE' in the first line) (returned value is empty (i.e. contains '/0's only))
Author
Roman Krais

Definition at line 43 of file interfile.c.

45 {
46 short int i, pos;
47 short int count=0; /* counter: How often appears keyword in the header? */
48 int n;
49 char *c[1];
50 char keyword[256], value[256];
51 char line[512]; /* max length of a line accepted in interfile header */
52 FILE *interfileHeader;
53
54 /* initialise strings */
55 for (i=0;i<256;i++) returnValue[i] = '\0';
56 for (i=0;i<300;i++) errorMessage[i] = '\0';
57
58 /* open interfile header for reading */
59 if ((interfileHeader = fopen(headerName,"r"))==NULL) {
60 strcpy(errorMessage,headerName);
61 strcat(errorMessage," could not be opened for reading");
62 return 3;
63 }
64
65 /* check from first line if file is really interfile header */
66 n=fread(&c,1,1,interfileHeader); if(n<1) {
67 strcpy(errorMessage,"wrong file header format?! No '!INTERFILE' at start of ");
68 strcat(errorMessage,headerName);
69 fclose(interfileHeader);
70 return 4;
71 }
72 i=0;
73 memcpy(&line[i],c,1);
74 while (memcmp(c,"\n",1) && memcmp(c,"\r",1)) {
75 i++;
76 n=fread(&c,1,1,interfileHeader); if(n<1) {
77 strcpy(errorMessage,"wrong file header format?! No '!INTERFILE' at start of ");
78 strcat(errorMessage,headerName);
79 fclose(interfileHeader);
80 return 4;
81 }
82 memcpy(&line[i],c,1);
83 }
84 if (memcmp(line,"!INTERFILE",10)) {
85 strcpy(errorMessage,"wrong file header format?! No '!INTERFILE' at start of ");
86 strcat(errorMessage,headerName);
87 fclose(interfileHeader);
88 return 4;
89 }
90
91 /* read file line by line */
92 while (fread(&c,1,1,interfileHeader) == 1) {
93 for (i=0;i<512;i++) line[i] = '\0'; /* initialise line */
94 for (i=0;i<256;i++) keyword[i] = '\0'; /* initialise keyword */
95 for (i=0;i<256;i++) value[i] = '\0'; /* initialise value */
96 i=0;
97 /* \n = end of line, \r = carriage return. Lines in ASCII files */
98 /* on Sun-Solaris end with \n, on Intel-Windows with \r\n */
99 while (memcmp(c,"\r",1) && memcmp(c,"\n",1) && i<512) {
100 memcpy(&line[i],c,1);
101 n=fread(&c,1,1,interfileHeader); if(n<1) {
102 strcpy(errorMessage,"wrong file header format: ");
103 strcat(errorMessage,headerName);
104 fclose(interfileHeader);
105 return 4;
106 }
107 i++;
108 }
109 /* comments are not processed */
110 if (strncmp(&line[0],";",1)) {
111 /* get keyword and value from line */
112 /* find position of the field seperator ':=' */
113 for (pos=1; pos<512; pos++)
114 if (line[pos] == '=' && line[pos-1] == ':') break;
115 /* now get the first and the second field */
116 for (i=0;i<pos-2 && i<256;i++) keyword[i] = line[i];
117 for (i=pos+2;i<256+pos+2 && i<512;i++) {
118 if (!memcmp(&line[i],"\0",1) || !memcmp(&line[i],"\r",1) || !memcmp(&line[i],"\n",1))
119 break; /* stop at the end of "line" */
120 value[i-pos-2] = line[i];
121 }
122 if (!memcmp(keyword,"!END OF INTERFILE",17)) break; /* are we done? */
123 /* check if we found the keyword */
124 else if (!strcmp(keyword,searchWord)) {
125 strcpy(returnValue,value);
126 count++;
127 }
128 }
129 }
130 fclose(interfileHeader); /* done with reading */
131 if (count == 0) {
132 strcpy(errorMessage,"keyword '");
133 strcat(errorMessage,searchWord);
134 strcat(errorMessage,"' not found in header");
135 return 2;
136 }
137 if (count > 1) {
138 strcpy(errorMessage,"keyword '");
139 strcat(errorMessage,searchWord);
140 strcat(errorMessage,"' appears more than once in header");
141 return 1;
142 }
143 return 0;
144}

◆ interfileExists()

int interfileExists ( const char * fname,
char * hdrfile,
char * imgfile,
int verbose )
extern

Check if specified image file name is a Interfile data.

Returns
Returns 0 if it is not, 1 if it is, and both image and header is found.
See also
interfileIsHeader
Author
Vesa Oikonen
Parameters
fnameFile name, either header file, image file, or base name without extensions.
hdrfileIf fname is Interfile, then header file name will be written in this char pointer (space needs to allocated by caller); NULL if not needed.
imgfileIf fname is Interfile, then image file name will be written in this char pointer (space needs to allocated by caller); NULL if not needed. Note that file name is stored without path.
verboseVerbose level; if zero, then nothing is printed into stdout or stderr

Definition at line 193 of file interfile.c.

205 {
206 char *cptr, basefile[FILENAME_MAX], temp[FILENAME_MAX], temp2[FILENAME_MAX];
207
208 if(fname==NULL || strlen(fname)==0) return(0);
209 if(verbose>0) printf("\n%s(%s, *str, *str, %d)\n", __func__, fname, verbose);
210
211 /* Construct the base file name wo extensions */
212 strcpy(basefile, fname);
213 cptr=strrchr(basefile, '.');
214 if(cptr!=NULL) {
215 if(strcasecmp(cptr, ".HDR")==0 || strcasecmp(cptr, ".I")==0 )
216 *cptr=(char)0;
217 }
218 cptr=strrchr(basefile, '.');
219 if(cptr!=NULL) {
220 if(strcasecmp(cptr, ".I")==0)
221 *cptr=(char)0;
222 }
223 if(verbose>1) printf("\n basefile := %s\n", basefile);
224
225 /* Header file exists? */
226 strcpy(temp, basefile); strcat(temp, ".i.hdr");
227 if(access(temp, 0) == -1) {
228 strcpy(temp, basefile); strcat(temp, ".hdr");
229 if(access(temp, 0) == -1) {
230 if(verbose>0) printf("\n hdr file not found or accessible.\n");
231 return(0);
232 }
233 }
234 /* Is this Interfile header file? */
235 if(interfileIsHeader(temp, temp2) < 2) {
236 if(verbose>0)
237 printf("\n %s was not identified as Interfile header file.\n", temp);
238 return(0);
239 }
240 /* Preserve header filename */
241 if(hdrfile!=NULL) strcpy(hdrfile, temp);
242
243 /* Image file exists? Add path from hdr file */
244 cptr=strrchr(temp, '/'); if(cptr==NULL) cptr=strrchr(temp, '\\');
245 if(cptr!=NULL) {
246 cptr++; *cptr=(char)0; strcat(temp, temp2); strcpy(temp2, temp);}
247 if(strlen(temp2)<1 || access(temp2, 0) == -1) {
248 if(verbose>0) printf("\n %s not found or accessible.\n", temp2);
249 return(0);
250 }
251 /* Preserve image filename */
252 if(imgfile!=NULL) strcpy(imgfile, temp2);
253
254 return 1;
255}
int interfileIsHeader(const char *hdrfile, char *imgfile)
Definition interfile.c:154

Referenced by imgFormatDetermine().

◆ interfileIsHeader()

int interfileIsHeader ( const char * hdrfile,
char * imgfile )
extern

Verify that given file is a valid Interfile header file.

Returns
Returns 0 if not, and 1 if it is a valid header file. If image data file name is requested and found in header, then 2 is returned.
See also
interfileExists
Author
Vesa Oikonen
Parameters
hdrfileInterfile header file name, with correct extension
imgfilePointer to allocated string where Interfile image data file name is written if found in header; enter NULL if not needed.

Definition at line 154 of file interfile.c.

160 {
161 char /*key[256], value[256],*/ temp[FILENAME_MAX];
162 IFT ift;
163 int li, ret;
164
165 //printf("\n%s(%s, *imgfile)\n", __func__, hdrfile);
166 if(hdrfile==NULL || strlen(hdrfile)<1) return 0;
167 if(imgfile!=NULL) strcpy(imgfile, "");
168 iftInit(&ift); strcpy(temp, hdrfile);
169 ret=iftRead(&ift, temp, 0, 0);
170 if(ret!=0 || ift.keyNr<2) {iftEmpty(&ift); return(0);}
171 /* Check that file starts with !INTERFILE */
172 //iftWriteItem(&ift, 0, stdout);
173 if(ift.item[0].type!='!') {iftEmpty(&ift); return(0);}
174 if(strcasecmp(ift.item[0].value, "INTERFILE")!=0) {iftEmpty(&ift); return(0);}
175 /* If imgfile was not requested, then we are done */
176 if(imgfile==NULL) {iftEmpty(&ift); return(1);}
177 /* Find filename for image data */
178 //iftWriteItem(&ift, 1, stdout);
179 li=iftGetFrom(&ift, 1, "name of data file", 0);
180 if(li<0 || strlen(ift.item[li].value)<1) {iftEmpty(&ift); return(1);}
181 strcpy(imgfile, ift.item[li].value);
182 iftEmpty(&ift);
183 return(2);
184}
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Definition iftfile.c:24
int iftGetFrom(IFT *ift, int si, const char *key, int verbose)
Definition iftsrch.c:156

Referenced by interfileExists().

◆ irdCheck()

int irdCheck ( IMG_RANGE * r,
IMG * img )
extern

Check that image range definition is inside image data. If time frames are zero, then fix those to image frame range.

See also
irdReorder, irdRead
Returns
Returns 0 if successful.
Parameters
rPointer to image volume range data.
imgPointer to image data.

Definition at line 152 of file ird.c.

157 {
158 if(r==NULL || img==NULL) return(1);
159 if(img->dimx<1 || img->dimy<1 || img->dimz<1 || img->dimt<1) return(2);
160
161 if(r->x1<1 || r->x1>img->dimx) return(11);
162 if(r->x2<1 || r->x2>img->dimx) return(12);
163
164 if(r->y1<1 || r->y1>img->dimy) return(21);
165 if(r->y2<1 || r->y2>img->dimy) return(22);
166
167 if(r->z1<1 || r->z1>img->dimz) return(31);
168 if(r->z2<1 || r->z2>img->dimz) return(32);
169
170 /* If time frame range is not set, then set it now */
171 if(r->f1<1 && r->f2<1) {
172 r->f1=1; r->f2=img->dimt;
173 return(0);
174 }
175 /* else check as usual */
176 if(r->f1<1 || r->f1>img->dimt) return(41);
177 if(r->f2<1 || r->f2>img->dimt) return(42);
178 return(0);
179}

◆ irdRead()

int irdRead ( char * irdfile,
IMG_RANGE * img_range,
char * status )
extern

Read Image Range Definition File.

Returns
Returns 0 if successful.
See also
irdCheck, string_to_xyzf, irdReorder
Parameters
irdfileImage Range Definition File name, which contains 4D image volume corners (x y z f) in IFT format: corner1 = x y z f corner2 = x y z f; If time frames (f) are missing, then frame coordinate is set to 0.
img_rangeImage volume range
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed

Definition at line 75 of file ird.c.

86 {
87 int ret, ii;
88 IFT ift;
89 char key[256];
90 IMG_PIXEL v;
91
92 /* Check that input is ok */
93 if(irdfile==NULL || strnlen(irdfile, 2)<1 || img_range==NULL) {
94 if(status!=NULL) strcpy(status, "program error");
95 return 1;
96 }
97 /* Read IDF as IFT file */
98 iftInit(&ift); ret=iftRead(&ift, irdfile, 1, 0); if(ret) {
99 if(status!=NULL) strcpy(status, ift.status);
100 iftEmpty(&ift); return 2;
101 }
102 /* Try to find keys 'corner1' and 'corner2' */
103 strcpy(key, "corner1"); ii=iftGet(&ift, key, 0);
104 if(ii>=0) {
105 ret=string_to_xyzf(ift.item[ii].value, &v);
106 if(ret==0) {
107 img_range->x1=v.x; img_range->y1=v.y; img_range->z1=v.z; img_range->f1=v.f;
108 strcpy(key, "corner2"); ii=iftGet(&ift, key, 0);
109 if(ii>=0) {
110 ret=string_to_xyzf(ift.item[ii].value, &v);
111 img_range->x2=v.x; img_range->y2=v.y; img_range->z2=v.z; img_range->f2=v.f;
112 if(ret==0) {
113 irdReorder(img_range);
114 if(status!=NULL) strcpy(status, "ok");
115 iftEmpty(&ift); return 0;
116 }
117 }
118 }
119 }
120 /* We are here only if keys were not found */
121 /* Lets not care about keys at all */
122 for(ii=0, ret=0; ii<ift.keyNr; ii++) {
123 if(ret==0 && string_to_xyzf(ift.item[ii].value, &v)==0)
124 {
125 img_range->x1=v.x; img_range->y1=v.y; img_range->z1=v.z; img_range->f1=v.f;
126 ret++; continue;
127 }
128 if(ret==1 && string_to_xyzf(ift.item[ii].value, &v)==0)
129 {
130 img_range->x2=v.x; img_range->y2=v.y; img_range->z2=v.z; img_range->f2=v.f;
131 ret++; break;
132 }
133 }
134 if(ret<2) {
135 if(status!=NULL) strcpy(status, "volume definitions not found");
136 iftEmpty(&ift); return 2;
137 }
138
139 irdReorder(img_range);
140 if(status!=NULL) strcpy(status, "ok");
141 iftEmpty(&ift);
142 return 0;
143}
int irdReorder(IMG_RANGE *img_range)
Definition ird.c:44
int string_to_xyzf(const char *str, IMG_PIXEL *v)
Definition ird.c:14
const char * status
Definition libtpcmisc.h:277

◆ irdReorder()

int irdReorder ( IMG_RANGE * img_range)
extern

Reorder Image Range Definition.

See also
vrdReorder

Function name was previously ifrReorder

Returns
Returns 0 if successful.
Parameters
img_rangeImage volume range; start and end range are set in correct order

Definition at line 44 of file ird.c.

47 {
48 int i;
49
50 /* Check that input is ok */
51 if(img_range==NULL) return 1;
52 /* Change the order if necessary */
53 if(img_range->x1<0 || img_range->x2<0) return 2;
54 if(img_range->x2<img_range->x1) {
55 i=img_range->x1; img_range->x1=img_range->x2; img_range->x2=i;}
56 if(img_range->y1<0 || img_range->y2<0) return 3;
57 if(img_range->y2<img_range->y1) {
58 i=img_range->y1; img_range->y1=img_range->y2; img_range->y2=i;}
59 if(img_range->z1<0 || img_range->z2<0) return 4;
60 if(img_range->z2<img_range->z1) {
61 i=img_range->z1; img_range->z1=img_range->z2; img_range->z2=i;}
62 if(img_range->f1<0 || img_range->f2<0) return 5;
63 if(img_range->f2<img_range->f1) {
64 i=img_range->f1; img_range->f1=img_range->f2; img_range->f2=i;}
65
66 return 0;
67}

Referenced by irdRead().

◆ mat_numcod()

int mat_numcod ( int frame,
int plane,
int gate,
int data,
int bed )
extern

Returns the matrix identifier

Parameters
frameframe number [0..4096]
planeplane number [0..256]
gategate number [0..64]
datadata number [0..8]
bedbed position [0..16]
Returns
matrix identifier coding

Definition at line 242 of file ecat63ml.c.

244 {
245 return((frame&0xFFF)|((bed&0xF)<<12)|((plane&0xFF)<<16)|
246 ((gate&0x3F)<<24)|((data&0x3)<<30));
247}

Referenced by atnMake(), ecat63AddImg(), ecat63GatherMatlist(), ecat63WriteAllImg(), and imgWriteEcat63Frame().

◆ mat_numdoc()

void mat_numdoc ( int matnum,
Matval * matval )
extern

Conversion of matrix identifier to numerical values

Parameters
matnummatrix identifier coding
matvaltarget matrix value structure

Definition at line 254 of file ecat63ml.c.

256 {
257 matval->frame = matnum&0xFFF;
258 matval->plane = (matnum>>16)&0xFF;
259 matval->gate = (matnum>>24)&0x3F;
260 matval->data = (matnum>>30)&0x3;
261 matval->bed = (matnum>>12)&0xF;
262}

Referenced by atnMake(), ecat63AddImg(), ecat63DeleteLateFrames(), ecat63GatherMatlist(), ecat63GetNums(), ecat63GetPlaneAndFrameNr(), ecat63PrintMatlist(), ecat63ReadAllToImg(), ecat63ReadPlaneToImg(), ecat63SortMatlistByFrame(), ecat63SortMatlistByPlane(), ecat6PrintSubheader(), imgReadEcat63Frame(), roi_mframe(), and roi_mplane().

◆ niftiCreateFNames()

int niftiCreateFNames ( const char * filename,
char * hdrfile,
char * imgfile,
char * siffile,
int fileformat )
extern

Construct the file names for NIfTI image.

Returns
Returns 0 if successful, otherwise <>0.
See also
niftiExists
Parameters
filenameFilename, either header file, image file, or base name without extensions, but possibly with path name. This string is never modified.
hdrfileHeader filename will be written in this char pointer (space needs to allocated by caller); If header and image are combined, then this will be the name of combined file; enter NULL if not needed.
imgfileImage filename will be written in this char pointer (space needs to allocated by caller); If header and image are combined, then this will be the name of combined file; enter NULL if not needed.
siffileSIF filename will be written in this char pointer (space needs to allocated by caller); enter NULL if not needed.
fileformatNIfTI file format, either IMG_NIFTI_1D (31) or IMG_NIFTI_1S (32).

Definition at line 44 of file nifti.c.

63 {
64 int n;
65 char basename[FILENAME_MAX];
66
67 if(hdrfile!=NULL) strcpy(hdrfile, "");
68 if(imgfile!=NULL) strcpy(imgfile, "");
69 if(siffile!=NULL) strcpy(siffile, "");
70 n=strlen(filename); if(n<1 || n>=FILENAME_MAX) {return(1);}
71 strlcpy(basename, filename, FILENAME_MAX);
73
74 /* Create database filenames */
75 if(fileformat==IMG_NIFTI_1D) {
76 if(hdrfile!=NULL) snprintf(hdrfile, FILENAME_MAX, "%s.hdr", basename);
77 if(imgfile!=NULL) snprintf(imgfile, FILENAME_MAX, "%s.img", basename);
78 } else if(fileformat==IMG_NIFTI_1S) {
79 if(hdrfile!=NULL) snprintf(hdrfile, FILENAME_MAX, "%s.nii", basename);
80 if(imgfile!=NULL) snprintf(imgfile, FILENAME_MAX, "%s.nii", basename);
81 } else
82 return(2);
83 if(siffile!=NULL) snprintf(siffile, FILENAME_MAX, "%s.sif", basename);
84 return(0);
85}
void niftiRemoveFNameExtension(char *fname)
Definition nifti.c:23

Referenced by imgWriteNifti(), imgWriteNiftiFrame(), and niftiRemove().

◆ niftiExists()

int niftiExists ( const char * filename,
char * hdrfile,
char * imgfile,
char * siffile,
NIFTI_DSR * header,
int verbose,
char * status )
extern

Verify if specified filename is a NIfTI file.

Returns
Returns 0 if it is not, 1 if header and image data are found (either as one combined file or as separate files, and 2, if SIF is found too.
See also
niftiRemove
Parameters
filenameFilename, either header file, image file, or base name without extensions. This string is never modified.
hdrfileIf filename refers to a Nifti file, then header filename will be written in this char pointer (space needs to allocated by caller); If header and image are combined, then this will be the name of combined file; enter NULL if not needed.
imgfileIf filename refers to a Nifti file, then image filename will be written in this char pointer (space needs to allocated by caller); If header and image are combined, then this will be the name of combined file; enter NULL if not needed.
siffileIf filename refers to a Nifti file, and if SIF exists, then SIF filename will be written in this char pointer (space needs to allocated by caller); NULL if not needed.
headerPointer to Nifti header, which is filled in this function; enter NULL, if not needed.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed.

Definition at line 160 of file nifti.c.

185 {
186 char basefile[FILENAME_MAX], temp[FILENAME_MAX], localhdrfile[FILENAME_MAX];
187 NIFTI_DSR *dsr, local_dsr;
188 int ret, combined=0;
189
190 if(filename==NULL || strlen(filename)==0) return(0);
191 if(verbose>0) {printf("\nniftiExists(%s, ...)\n", filename); fflush(stdout);}
192 if(status!=NULL) strcpy(status, "OK");
193 if(header==NULL) dsr=&local_dsr; else dsr=header;
194
195 localhdrfile[0]=(char)0;
196
197 /* Construct the base file name wo extensions */
198 strlcpy(basefile, filename, FILENAME_MAX);
200 if(verbose>1) printf("\n basefile := %s\n", basefile);
201
202 /* Combined header and image file exists? */
203 strcpy(temp, basefile); strcat(temp, ".nii");
204 if(access(temp, 0) == -1) {
205 if(verbose>0) printf(" %s not found or accessible.\n", temp);
206 } else {
207 /* Preserve header and image filenames */
208 strcpy(localhdrfile, temp);
209 if(hdrfile!=NULL) strcpy(hdrfile, temp);
210 if(imgfile!=NULL) strcpy(imgfile, temp);
211 combined=1;
212 if(verbose>1) printf(" %s is accessible.\n", temp);
213 }
214
215 /* If not, then check if header file exists */
216 if(combined==0) {
217 strcpy(temp, basefile); strcat(temp, ".hdr");
218 if(access(temp, 0) == -1) {
219 strcpy(temp, basefile); strcat(temp, ".img.hdr");
220 if(access(temp, 0) == -1) {
221 if(verbose>0) printf(" hdr file not found or accessible.\n");
222 if(status!=NULL) strcpy(status, "file not accessible");
223 return(0);
224 }
225 }
226 /* Preserve header filename */
227 strcpy(localhdrfile, temp);
228 if(hdrfile!=NULL) strcpy(hdrfile, temp);
229 if(verbose>1) printf(" %s is accessible.\n", temp);
230 }
231
232 /* If not combined, then does image file exists? */
233 if(combined==0) {
234 strcpy(temp, basefile); strcat(temp, ".img");
235 if(access(temp, 0) == -1) {
236 if(verbose>0) printf(" %s not found or accessible.\n", temp);
237 if(status!=NULL) strcpy(status, "file not accessible");
238 return(0);
239 }
240 /* Preserve image filename */
241 if(imgfile!=NULL) strcpy(imgfile, temp);
242 if(verbose>1) printf(" %s is accessible.\n", temp);
243 }
244
245 /* Is this Nifti file? */
246 if((ret=niftiReadHeader(localhdrfile, dsr, verbose, temp))!=0) {
247 if(status!=NULL) strcpy(status, "file is not Nifti");
248 if(verbose>0) {
249 printf(" %s was not identified as Nifti header file (%d).\n", localhdrfile, ret);
250 printf(" %s\n", temp);
251 }
252 return(0);
253 }
254 if(verbose>1) printf(" %s is identified as Nifti.\n", localhdrfile);
255 if(verbose>10) niftiPrintHeader(dsr, stdout);
256
257 /* SIF exists? */
258 strcpy(temp, basefile); strcat(temp, ".sif");
259 if(verbose>3) printf(" checking if %s exists\n", temp);
260 if(access(temp, 0) == -1) {
261 strcpy(temp, basefile); strcat(temp, ".img.sif");
262 if(verbose>3) printf(" checking if %s exists\n", temp);
263 if(access(temp, 0) == -1) {
264 strcpy(temp, basefile); strcat(temp, ".nii.sif");
265 if(verbose>3) printf(" checking if %s exists\n", temp);
266 if(access(temp, 0) == -1) {
267 if(verbose>0) printf("\n SIF not found or accessible.\n");
268 if(siffile!=NULL) strcpy(siffile, "");
269 if(status!=NULL) {
270 if(combined) strcpy(status, "combined Nifti file is accessible");
271 else strcpy(status, "Nifti files are accessible");
272 }
273 return(1); // but otherwise ok
274 }
275 }
276 }
277 /* Preserve SIF filename */
278 if(siffile!=NULL) strcpy(siffile, temp);
279 if(verbose>1) printf(" %s is accessible.\n", temp);
280 if(status!=NULL) {
281 if(combined) strcpy(status, "combined Nifti file and SIF are accessible");
282 else strcpy(status, "Nifti files and SIF are accessible");
283 }
284 return(2);
285}
int niftiReadHeader(char *filename, NIFTI_DSR *dsr, int verbose, char *status)
Definition nifti.c:293
int niftiPrintHeader(NIFTI_DSR *dsr, FILE *fp)
Definition nifti.c:501

Referenced by imgFormatDetermine(), imgRead(), imgReadNiftiFrame(), imgReadNiftiHeader(), and imgWriteNiftiFrame().

◆ niftiPrintHeader()

int niftiPrintHeader ( NIFTI_DSR * dsr,
FILE * fp )
extern

Print the contents of Nifti header to specified file pointer.

Returns
Returns 0 if ok, 1 if invalid input.
Parameters
dsrPointer to combined Nifti header.
fpFile pointer where header information is printed.

Definition at line 501 of file nifti.c.

506 {
507 int i;
508 char *cptr, tmp[256];
509
510 /* Check input */
511 if(fp==NULL || dsr==NULL) return(1);
512
513 fprintf(fp, "Nifti header:\n");
514
515 /* Byte order */
516 if(dsr->byte_order==0) strcpy(tmp, "big"); else strcpy(tmp, "little");
517 fprintf(fp, "byte_order := %s endian\n", tmp);
518 /* sizeof_hdr */
519 fprintf(fp, "sizeof_hdr := %d\n", dsr->h.sizeof_hdr);
520 /* data_type */
521 strncpy(tmp, dsr->h.data_type, 10); tmp[10]=(char)0;
522 cptr=tmp; while(*cptr) {if(!isprint(cptr[0])) cptr[0]=' '; cptr++;}
523 fprintf(fp, "data_type := %s\n", tmp);
524 /* db_name */
525 strncpy(tmp, dsr->h.db_name, 18); tmp[18]=(char)0;
526 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
527 fprintf(fp, "db_name := %s\n", tmp);
528 /* extents */
529 fprintf(fp, "extents := %d\n", dsr->h.extents);
530 /* session_error */
531 fprintf(fp, "session_error := %d\n", dsr->h.session_error);
532 /* regular */
533 fprintf(fp, "regular := %d\n", dsr->h.regular);
534 /* dim_info */
535 fprintf(fp, "dim_info := %d\n", dsr->h.dim_info);
536
537 /* Data array dimensions */
538 i=0; fprintf(fp, "dim := {%d", dsr->h.dim[i]);
539 for(i=1; i<8; i++) fprintf(fp, ", %d", dsr->h.dim[i]);
540 fprintf(fp, "}\n");
541
542 /* Intent parameters */
543 fprintf(fp, "intent_p1 := %g\n", dsr->h.intent_p1);
544 fprintf(fp, "intent_p2 := %g\n", dsr->h.intent_p2);
545 fprintf(fp, "intent_p3 := %g\n", dsr->h.intent_p3);
546 fprintf(fp, "intent_code := %d\n", dsr->h.intent_code);
547
548 /* */
549 fprintf(fp, "datatype := %d\n", dsr->h.datatype);
550 fprintf(fp, "bitpix := %d\n", dsr->h.bitpix);
551 fprintf(fp, "slice_start := %d\n", dsr->h.slice_start);
552 i=0; fprintf(fp, "pixdim := {%g", dsr->h.pixdim[i]);
553 for(i=1; i<8; i++) fprintf(fp, ", %g", dsr->h.pixdim[i]);
554 fprintf(fp, "}\n");
555 fprintf(fp, "vox_offset := %g\n", dsr->h.vox_offset);
556 fprintf(fp, "scl_slope := %g\n", dsr->h.scl_slope);
557 fprintf(fp, "scl_inter := %g\n", dsr->h.scl_inter);
558 fprintf(fp, "slice_end := %d\n", dsr->h.slice_end);
559 fprintf(fp, "slice_code := %d\n", dsr->h.slice_code);
560 fprintf(fp, "xyzt_units := %d\n", dsr->h.xyzt_units);
561 fprintf(fp, "cal_max := %g\n", dsr->h.cal_max);
562 fprintf(fp, "cal_min := %g\n", dsr->h.cal_min);
563 fprintf(fp, "slice_duration := %g\n", dsr->h.slice_duration);
564 fprintf(fp, "toffset := %g\n", dsr->h.toffset);
565 fprintf(fp, "glmax := %d\n", dsr->h.glmax);
566 fprintf(fp, "glmin := %d\n", dsr->h.glmin);
567
568 /* Study description */
569 strncpy(tmp, dsr->h.descrip, 80); tmp[80]=(char)0;
570 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
571 fprintf(fp, "descrip := %s\n", tmp);
572 strncpy(tmp, dsr->h.aux_file, 24); tmp[24]=(char)0;
573 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
574 fprintf(fp, "aux_file := %s\n", tmp);
575
576 /* Transformation parameters */
577 fprintf(fp, "qform_code := %d\n", dsr->h.qform_code);
578 fprintf(fp, "sform_code := %d\n", dsr->h.sform_code);
579 fprintf(fp, "quatern_b := %g\n", dsr->h.quatern_b);
580 fprintf(fp, "quatern_c := %g\n", dsr->h.quatern_c);
581 fprintf(fp, "quatern_d := %g\n", dsr->h.quatern_d);
582 fprintf(fp, "qoffset_x := %g\n", dsr->h.qoffset_x);
583 fprintf(fp, "qoffset_y := %g\n", dsr->h.qoffset_y);
584 fprintf(fp, "qoffset_z := %g\n", dsr->h.qoffset_z);
585 i=0; fprintf(fp, "srow_x := {%g", dsr->h.srow_x[i]);
586 for(i=1; i<4; i++) fprintf(fp, ", %g", dsr->h.srow_x[i]);
587 fprintf(fp, "}\n");
588 i=0; fprintf(fp, "srow_y := {%g", dsr->h.srow_y[i]);
589 for(i=1; i<4; i++) fprintf(fp, ", %g", dsr->h.srow_y[i]);
590 fprintf(fp, "}\n");
591 i=0; fprintf(fp, "srow_z := {%g", dsr->h.srow_z[i]);
592 for(i=1; i<4; i++) fprintf(fp, ", %g", dsr->h.srow_z[i]);
593 fprintf(fp, "}\n");
594
595 strncpy(tmp, dsr->h.intent_name, 16); tmp[16]=(char)0;
596 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
597 fprintf(fp, "intent_name := %s\n", tmp);
598
599 /* Nifti magic number */
600 fprintf(fp, "magic := %s\n", dsr->h.magic);
601
602 /* Nifti header extender */
603 i=0; fprintf(fp, "extension := {%d", dsr->e.extension[i]);
604 for(i=1; i<4; i++) fprintf(fp, ", %d", dsr->e.extension[i]);
605 fprintf(fp, "}\n");
606
607 fflush(fp);
608 return(0);
609}
short int session_error

Referenced by niftiExists().

◆ niftiReadHeader()

int niftiReadHeader ( char * filename,
NIFTI_DSR * dsr,
int verbose,
char * status )
extern

Read Nifti header contents. Currently, does not read Nifti-1 header extension.

Returns
Returns 0, if successful, otherwise >0.
See also
niftiReadImagedata, niftiWriteHeader, niftiExists
Parameters
filenameName of file to read (including path and extension)
dsrPointer to previously allocated header structure
verboseVerbose level; if zero, then nothing is printed to stderr or stdout
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed

Definition at line 293 of file nifti.c.

303 {
304 FILE *fp;
305 int little; // 1 if current platform is little endian (x86), else 0
306 int same_order, extender=0;
307 unsigned char buf[NIFTI_HEADER_SIZE];
308 short int s;
309
310 /* Check arguments */
311 if(filename==NULL || strlen(filename)==0 || dsr==NULL) return(1);
312 if(verbose>0) {
313 printf("\nniftiReadHeader(%s, ...)\n", filename); fflush(stdout);}
314 if(status!=NULL) strcpy(status, "OK");
315 little=little_endian(); if(verbose>3) printf(" little := %d\n", little);
316
317 /* Open file */
318 fp=fopen(filename, "rb"); if(fp==NULL) {
319 if(status!=NULL) strcpy(status, "cannot open file");
320 if(verbose>0) fprintf(stderr, "Error: cannot open file %s\n", filename);
321 return(2);
322 }
323
324 /* Read Nifti header */
325 if(fread(buf, NIFTI_HEADER_SIZE, 1, fp)<1) {
326 if(status!=NULL) strcpy(status, "complete Nifti header not found");
327 if(verbose>0)
328 fprintf(stderr, "Error: invalid Nifti header file %s\n", filename);
329 return(3);
330 }
331 /* Read nifti1 extender */
332 for(int n=0; n<4; n++) dsr->e.extension[n]=(char)0;
333 if(fread(dsr->e.extension, 4, 1, fp)<1) {
334 if(status!=NULL) strcpy(status, "complete Nifti header not found");
335 if(verbose>1)
336 fprintf(stdout, "Nifti header extender not found in %s\n", filename);
337 extender=0;
338 } else {
339 extender=1;
340 }
341 /* Close file */
342 fclose(fp);
343
344 /* Read Nifti Magic number */
345 memcpy(dsr->h.magic, buf+344, 4);
346 if(strcasecmp(dsr->h.magic, "ni1")==0) {
347 if(verbose>1) {printf(" separate hdr and img files.\n"); fflush(stdout);}
348 } else if(strcasecmp(dsr->h.magic, "n+1")==0) {
349 if(verbose>1) printf(" combined hdr and img data.\n");
350 } else {
351 if(status!=NULL) strcpy(status, "Nifti magic number not found");
352 if(verbose>0) {
353 fprintf(stderr, "Error: not a Nifti header file %s\n", filename);
354 fflush(stderr);
355 }
356 if(verbose>2) {
357 printf("magic := {%d, %d, %d, %d}\n", dsr->h.magic[0], dsr->h.magic[1],
358 dsr->h.magic[2], dsr->h.magic[3]);
359 }
360 return(4);
361 }
362 if(verbose>1) printf(" Nifti Magic number := %s\n", dsr->h.magic);
363 /* Check that 4-byte header extender was found, if magic number is n+1 */
364 if(strcasecmp(dsr->h.magic, "n+1")==0 && extender==0) {
365 if(status!=NULL) strcpy(status, "Nifti header extender not found");
366 if(verbose>0) {
367 fprintf(stderr, "Error: not valid Nifti n+1 header file %s\n", filename);
368 fflush(stderr);
369 }
370 return(5);
371 }
372
373 /* Determine from dim[0] if file is big or little endian */
374 memcpy(&s, buf+40, 2); if(verbose>10) printf(" s := %d\n", s);
375 if(s>0 && s<8) { // same order in file and current machine
376 dsr->byte_order=little;
377 same_order=1;
378 } else {
379 swabip(&s, 2); if(verbose>10) printf(" s := %d\n", s);
380 if(s>0 && s<8) { // opposite order in file and in current machine
381 if(little==1) dsr->byte_order=0; else dsr->byte_order=1;
382 same_order=0;
383 } else {
384 if(status!=NULL) strcpy(status, "invalid Nifti byte order");
385 if(verbose>0)
386 fprintf(stderr, "Error: not a valid Nifti header file %s\n", filename);
387 return(6);
388 }
389 }
390 if(verbose>1) printf(" Nifti byte order := %d\n", dsr->byte_order);
391
392 /* Size of header */
393 {
394 int n=0;
395 memcpy(&n, buf+0, 4); if(!same_order) swawbip(&n, 4);
396 if(n!=348) {
397 if(status!=NULL) strcpy(status, "invalid Nifti sizeof_hdr");
398 if(verbose>0)
399 fprintf(stderr, "Error: not a valid Nifti header file %s\n", filename);
400 return(7);
401 }
402 dsr->h.sizeof_hdr=n;
403 }
404
405 /* */
406 memcpy(&dsr->h.data_type, buf+4, 10);
407 memcpy(&dsr->h.db_name, buf+14, 18);
408 if(!same_order) swawbip(buf+32, 4);
409 memcpy(&dsr->h.extents, buf+32, 4);
410 if(!same_order) swabip(buf+36, 2);
411 memcpy(&dsr->h.session_error, buf+36, 2);
412 memcpy(&dsr->h.regular, buf+38, 1);
413 memcpy(&dsr->h.dim_info, buf+39, 1);
414
415 /* dim */
416 if(!same_order) swabip(buf+40, 16);
417 memcpy(dsr->h.dim, buf+40, 16);
418 /* intent parameters */
419 if(!same_order) swawbip(buf+56, 4);
420 memcpy(&dsr->h.intent_p1, buf+56, 4);
421 if(!same_order) swawbip(buf+60, 4);
422 memcpy(&dsr->h.intent_p2, buf+60, 4);
423 if(!same_order) swawbip(buf+64, 4);
424 memcpy(&dsr->h.intent_p3, buf+64, 4);
425 if(!same_order) swabip(buf+68, 2);
426 memcpy(&dsr->h.intent_code, buf+68, 2);
427
428 /* */
429 if(!same_order) swabip(buf+70, 2);
430 memcpy(&dsr->h.datatype, buf+70, 2);
431 if(!same_order) swabip(buf+72, 2);
432 memcpy(&dsr->h.bitpix, buf+72, 2);
433 if(!same_order) swabip(buf+74, 2);
434 memcpy(&dsr->h.slice_start, buf+74, 2);
435 if(!same_order) swawbip(buf+76, 32);
436 memcpy(dsr->h.pixdim, buf+76, 32);
437 if(!same_order) swawbip(buf+108, 4);
438 memcpy(&dsr->h.vox_offset, buf+108, 4);
439 if(!same_order) swawbip(buf+112, 4);
440 memcpy(&dsr->h.scl_slope, buf+112, 4);
441 if(!same_order) swawbip(buf+116, 4);
442 memcpy(&dsr->h.scl_inter, buf+116, 4);
443 if(!same_order) swabip(buf+120, 2);
444 memcpy(&dsr->h.slice_end, buf+120, 2);
445 memcpy(&dsr->h.slice_code, buf+122, 1);
446 memcpy(&dsr->h.xyzt_units, buf+123, 1);
447 if(!same_order) swawbip(buf+124, 4);
448 memcpy(&dsr->h.cal_max, buf+124, 4);
449 if(!same_order) swawbip(buf+128, 4);
450 memcpy(&dsr->h.cal_min, buf+128, 4);
451 if(!same_order) swawbip(buf+132, 4);
452 memcpy(&dsr->h.slice_duration,buf+132,4);
453 if(!same_order) swawbip(buf+136, 4);
454 memcpy(&dsr->h.toffset, buf+136, 4);
455 if(!same_order) swawbip(buf+140, 4);
456 memcpy(&dsr->h.glmax, buf+140, 4);
457 if(!same_order) swawbip(buf+144, 4);
458 memcpy(&dsr->h.glmin, buf+144, 4);
459
460 /* study description */
461 memcpy(&dsr->h.descrip, buf+148, 80);
462 /* Auxiliary filename */
463 memcpy(&dsr->h.aux_file, buf+228, 24);
464
465 /* Transformation parameters */
466 if(!same_order) swabip(buf+252, 2);
467 memcpy(&dsr->h.qform_code, buf+252, 2);
468 if(!same_order) swabip(buf+254, 2);
469 memcpy(&dsr->h.sform_code, buf+254, 2);
470 if(!same_order) swawbip(buf+256, 4);
471 memcpy(&dsr->h.quatern_b, buf+256, 4);
472 if(!same_order) swawbip(buf+260, 4);
473 memcpy(&dsr->h.quatern_c, buf+260, 4);
474 if(!same_order) swawbip(buf+264, 4);
475 memcpy(&dsr->h.quatern_d, buf+264, 4);
476 if(!same_order) swawbip(buf+268, 4);
477 memcpy(&dsr->h.qoffset_x, buf+268, 4);
478 if(!same_order) swawbip(buf+272, 4);
479 memcpy(&dsr->h.qoffset_y, buf+272, 4);
480 if(!same_order) swawbip(buf+276, 4);
481 memcpy(&dsr->h.qoffset_z, buf+276, 4);
482 if(!same_order) swawbip(buf+280, 16);
483 memcpy(dsr->h.srow_x, buf+280, 16);
484 if(!same_order) swawbip(buf+296, 16);
485 memcpy(dsr->h.srow_y, buf+296, 16);
486 if(!same_order) swawbip(buf+312, 16);
487 memcpy(dsr->h.srow_z, buf+312, 16);
488
489 memcpy(&dsr->h.intent_name, buf+328, 16);
490
491 if(status!=NULL) strcpy(status, "complete Nifti header was read");
492 if(verbose>0) fflush(stdout);
493 return(0);
494}

Referenced by niftiExists().

◆ niftiReadImagedata()

int niftiReadImagedata ( FILE * fp,
NIFTI_DSR * dsr,
int frame,
float * data,
int verbose,
char * status )
extern

Read Nifti image data, convert byte order if necessary, and scale values to floats. Reads only one frame at a time!

Returns
Returns 0 if successful, >1 in case of an error, and specifically -1 in case that contents after the last image frame was requested.
See also
niftiReadHeader
Parameters
fpFile pointer to start of image data file, opened previously in binary mode.
dsrPointer to previously filled Nifti header structure
frameFrame number to read [1..number of frames].
dataPointer to image float data allocated previously for dimz*dimy*dimx floats.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed.

Definition at line 619 of file nifti.c.

633 {
634 int dimNr, dimx, dimy, dimz=1, dimt=1;
635 int little;
636 char *mdata, *mptr;
637 float *fptr, ss, si;
638 short int *sptr;
639 int *iptr;
640 double d;
641
642
643 if(verbose>0) {
644 printf("niftiReadImagedata(fp, h, %d, data, %d)\n", frame, verbose);
645 fflush(stdout);
646 }
647 /* Check the arguments */
648 if(status!=NULL) sprintf(status, "invalid function input");
649 if(frame<=0 || fp==NULL || dsr==NULL || data==NULL) return(1);
650
651 /* Get the image data start location from header, in case of single file
652 format */
653 long long start_pos;
654 {
655 long long int s=0;
656 if(strcasecmp(dsr->h.magic, "n+1")==0) s=(int)dsr->h.vox_offset;
657 if(s<0) start_pos=-s; else start_pos=s;
658 }
659 if(verbose>2) printf(" image_start_pos := %llu\n", start_pos);
660 /* edit it later to move to the correct frame */
661
662 /* Get the image dimensions from header */
663 if(status!=NULL) sprintf(status, "invalid image dimensions");
664 dimNr=dsr->h.dim[0]; if(dimNr<2 || dimNr>4) return(2);
665 dimx=dsr->h.dim[1];
666 dimy=dsr->h.dim[2];
667 if(dimNr>2) dimz=dsr->h.dim[3];
668 if(dimNr>3) dimt=dsr->h.dim[4];
669 if(frame>dimt) return(-1);
670 long long pxlNr=dimx*dimy*dimz; if(pxlNr<1) return(4);
671
672 // data_type is unused in Nifti
673 /* Check that datatype is supported */
674 if(verbose>1) printf(" verifying datatype %d\n", dsr->h.datatype);
675 {
676 int n=0;
677 if(dsr->h.datatype & NIFTI_DT_RGB) n+=NIFTI_DT_RGB;
680 if(dsr->h.datatype==NIFTI_DT_UNKNOWN) n+=512;
681 if(n!=0) {
682 if(verbose>0) printf("datatype error %d\n", n);
683 if(status!=NULL) sprintf(status, "unsupported pixel datatype %d", dsr->h.datatype);
684 return(6);
685 }
686 }
687
688 /* Allocate memory for the binary data */
689 if(verbose>1) printf(" allocating memory for binary data\n");
690 if(status!=NULL) sprintf(status, "invalid pixel data format");
691 if(dsr->h.bitpix==0) { // Carimas Nifti Writer does not set bitpix
692 if(dsr->h.datatype==NIFTI_DT_UNSIGNED_SHORT) dsr->h.bitpix=16;
693 }
694 if(dsr->h.bitpix<8) return(5); // We don't support bit data
695 long long rawSize=pxlNr*(dsr->h.bitpix/8); if(rawSize<1) return(6);
696 if(verbose>1) printf(" pxlNr=%lld rawSize=%lld\n", pxlNr, rawSize);
697 if(status!=NULL) sprintf(status, "out of memory");
698 mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11);
699
700 /* Seek the start of current frame data */
701 if(verbose>1) printf(" seeking file position\n");
702 start_pos+=(frame-1)*rawSize;
703 if(verbose>2) printf("start_pos=%lld\n", start_pos);
704 fseeko(fp, start_pos, SEEK_SET);
705 if(ftello(fp)!=start_pos) {
706 if(status!=NULL) sprintf(status, "could not move to start_pos %lld", start_pos);
707 free(mdata); return(7);
708 }
709
710 /* Read the data */
711 if(verbose>1) printf(" reading binary data\n");
712 mptr=mdata;
713 {
714 size_t n=fread(mptr, rawSize, 1, fp);
715 if(n<1) {
716 if(status!=NULL)
717 sprintf(status, "could read only %zu bytes when request was %lld", n, rawSize);
718 free(mdata); return(8);
719 }
720 }
721
722 /* Convert byte order if necessary */
723 little=little_endian(); mptr=mdata;
724 if(little!=dsr->byte_order) {
725 if(verbose>0) printf("byte conversion\n");
726 switch(dsr->h.bitpix) {
727 case 8: /* no conversion needed */ break;
728 case 16: swabip(mptr, rawSize); break;
729 case 32: swawbip(mptr, rawSize); break;
730 case 64: swawbip(mptr, rawSize); break;
731 default:
732 if(verbose>5) printf("unsupported nifti bitpix := %d\n", dsr->h.bitpix);
733 sprintf(status, "unsupported nifti bitpix := %d", dsr->h.bitpix);
734 free(mdata); return(5);
735 }
736 }
737
738 /* Get scaling factors */
739 ss=dsr->h.scl_slope; if(ss==0) ss=1.0;
740 si=dsr->h.scl_inter;
741
742 /* Copy data to float pixel values */
743 if(verbose>1) printf(" conversion to floating point voxel values\n");
744 mptr=mdata;
745 switch(dsr->h.datatype) {
747 if(dsr->h.bitpix!=8) {
748 if(status!=NULL)
749 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
750 dsr->h.datatype, dsr->h.bitpix);
751 free(mdata); return(5);
752 }
753 fptr=data;
754 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
755 *fptr=si+ss*(float)(*mptr);
756 break;
758 if(dsr->h.bitpix!=16) {
759 if(status!=NULL)
760 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
761 dsr->h.datatype, dsr->h.bitpix);
762 free(mdata); return(5);
763 }
764 fptr=data;
765 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
766 unsigned short int *uptr=(unsigned short int*)mptr; *fptr=si+ss*(float)(*uptr);
767 }
768 break;
770 if(dsr->h.bitpix!=16) {
771 if(status!=NULL)
772 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
773 dsr->h.datatype, dsr->h.bitpix);
774 free(mdata); return(5);
775 }
776 fptr=data;
777 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
778 sptr=(short int*)mptr; *fptr=si+ss*(float)(*sptr);
779 }
780 break;
782 if(dsr->h.bitpix!=16 && dsr->h.bitpix!=32) {
783 if(status!=NULL)
784 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
785 dsr->h.datatype, dsr->h.bitpix);
786 free(mdata); return(5);
787 }
788 fptr=data;
789 if(dsr->h.bitpix==16) {
790 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
791 iptr=(int*)mptr; *fptr=si+ss*(float)(*iptr);
792 }
793 } else if(dsr->h.bitpix==32) {
794 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
795 iptr=(int*)mptr; *fptr=si+ss*(float)(*iptr);
796 }
797 }
798 break;
799 case NIFTI_DT_FLOAT: // 16
800 if(dsr->h.bitpix==32) {
801 fptr=data; memcpy(fptr, mptr, pxlNr*4);
802 fptr=data; for(long long i=0; i<pxlNr; i++, fptr++) *fptr*=ss;
803 fptr=data; for(long long i=0; i<pxlNr; i++, fptr++) *fptr+=si;
804 } else {
805 if(status!=NULL)
806 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
807 dsr->h.datatype, dsr->h.bitpix);
808 free(mdata); return(5);
809 }
810 break;
811 case NIFTI_DT_DOUBLE:
812 if(dsr->h.bitpix!=64) {
813 if(status!=NULL)
814 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
815 dsr->h.datatype, dsr->h.bitpix);
816 free(mdata); return(5);
817 }
818 fptr=data;
819 for(long long i=0; i<pxlNr; i++, mptr+=8, fptr++) {
820 memcpy(&d, mptr, 8); *fptr=si+ss*d;
821 }
822 break;
823 default:
824 if(status!=NULL)
825 sprintf(status, "unsupported pixel datatype %d", dsr->h.datatype);
826 free(mdata); return(5);
827 }
828
829 if(verbose>1) {printf(" data read successfully.\n"); fflush(stdout);}
830 free(mdata);
831 if(status!=NULL) sprintf(status, "ok");
832 return 0;
833}
#define NIFTI_DT_RGB
#define NIFTI_DT_BINARY
#define NIFTI_DT_UNSIGNED_SHORT
#define NIFTI_DT_SIGNED_SHORT
#define NIFTI_DT_SIGNED_INT
#define NIFTI_DT_UNSIGNED_CHAR
#define NIFTI_DT_COMPLEX
#define NIFTI_DT_UNKNOWN
#define NIFTI_DT_DOUBLE

Referenced by imgReadNiftiFrame().

◆ niftiRemove()

int niftiRemove ( const char * dbname,
int fileformat,
int verbose )
extern

Remove header and voxel data files or the single .nii file belonging to specified NIfTI database.

SIF is not deleted in any case. Validity of NIfTI is not verified, therefore this can be used to delete any files with similar name as NIfTI would have.

Returns
Returns 0 when call was successful, otherwise <>0. Call is considered successful, if files do not exist initially.
See also
niftiExists, niftiRemoveFNameExtension
Parameters
dbnameNIfTI database name with path, possibly with filename extension
fileformatNIfTI file format, either IMG_NIFTI_1D (31) or IMG_NIFTI_1S (32), or IMG_UNKNOWN (0) in case both are to be deleted.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 100 of file nifti.c.

108 {
109 if(verbose>0) {
110 printf("niftiRemove(%s, %d, ...)\n", dbname, fileformat);
111 fflush(stdout);
112 }
113
114 char imgfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
115 int errNr=0;
116 int ret=niftiCreateFNames(dbname, hdrfile, imgfile, siffile, fileformat);
117 if(ret==0 && fileformat==IMG_NIFTI_1D) { // dual format
118 if(access(hdrfile, 0)!=-1) {
119 if(verbose>1) {printf(" removing %s\n", hdrfile); fflush(stdout);}
120 if(remove(hdrfile)!=0) errNr++;
121 }
122 if(access(imgfile, 0)!=-1) {
123 if(verbose>1) {printf(" removing %s\n", imgfile); fflush(stdout);}
124 if(remove(imgfile)!=0) errNr++;
125 }
126 } else if(ret==0 && fileformat==IMG_NIFTI_1S) { // single format
127 if(access(imgfile, 0)!=-1) {
128 if(verbose>1) {printf(" removing %s\n", imgfile); fflush(stdout);}
129 if(remove(imgfile)!=0) errNr++;
130 }
131 } else { // dual and single formats
132 ret=niftiCreateFNames(dbname, hdrfile, imgfile, siffile, IMG_NIFTI_1D);
133 if(ret!=0) return 1;
134 if(access(hdrfile, 0)!=-1) {
135 if(verbose>1) {printf(" removing %s\n", hdrfile); fflush(stdout);}
136 if(remove(hdrfile)!=0) errNr++;
137 }
138 if(access(imgfile, 0)!=-1) {
139 if(verbose>1) {printf(" removing %s\n", imgfile); fflush(stdout);}
140 if(remove(imgfile)!=0) errNr++;
141 }
142
143 ret=niftiCreateFNames(dbname, hdrfile, imgfile, siffile, IMG_NIFTI_1S);
144 if(ret!=0) return 1;
145 if(access(imgfile, 0)!=-1) {
146 if(verbose>1) {printf(" removing %s\n", imgfile); fflush(stdout);}
147 if(remove(imgfile)!=0) errNr++;
148 }
149 }
150 return errNr;
151}
int niftiCreateFNames(const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
Definition nifti.c:44

Referenced by imgWriteNifti().

◆ niftiRemoveFNameExtension()

void niftiRemoveFNameExtension ( char * fname)
extern

Remove any extensions from Nifti file name, leaving only base file name.

See also
niftiCreateFNames, niftiExists, niftiRemove
Parameters
fnameFull name of file.

Definition at line 23 of file nifti.c.

26 {
27 char *cptr;
28 cptr=strrchr(fname, '.'); if(cptr==NULL) return;
29 if(strcasecmp(cptr, ".")==0 || strcasecmp(cptr, ".img")==0 ||
30 strcasecmp(cptr, ".hdr")==0 || strcasecmp(cptr, ".sif")==0 ||
31 strcasecmp(cptr, ".nii")==0)
32 *cptr=(char)0;
33 /* Remove also double extensions, e.g. from data.img.hdr */
34 cptr=strrchr(fname, '.'); if(cptr==NULL) return;
35 if(strcasecmp(cptr, ".img")==0 || strcasecmp(cptr, ".nii")==0) *cptr=(char)0;
36}

Referenced by imgReadNiftiFrame(), imgReadNiftiHeader(), niftiCreateFNames(), and niftiExists().

◆ niftiWriteHeader()

int niftiWriteHeader ( char * filename,
NIFTI_DSR * dsr,
int verbose,
char * status )
extern

Write NIfTI-1 header contents.

Currently, does not write header extension. Header field 'byte_order' is used to determine the required byte order.

Returns
Returns 0, if successful, otherwise >0.
See also
niftiReadHeader, imgWriteNifti
Parameters
filenameName of file to write (including path and extension).
dsrPointer to previously allocated header structure.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed.

Definition at line 844 of file nifti.c.

854 {
855 FILE *fp;
856 int little; // 1 if current platform is little endian (x86), else 0
857 int same_order;
858 unsigned char buf1[NIFTI_HEADER_SIZE];
859 unsigned char buf2[NIFTI_HEADER_EXTENDER_SIZE];
860 unsigned char *bptr;
861
862
863 if(verbose>0) {
864 printf("\nniftiWriteHeader(%s, ...)\n", filename); fflush(stdout);
865 }
866
867 /* Check arguments */
868 if(status!=NULL) strcpy(status, "invalid function input");
869 if(filename==NULL || strlen(filename)==0 || dsr==NULL) return(1);
870 /* Check magic number */
871 if(strcmp(dsr->h.magic, "ni1")!=0 && strcmp(dsr->h.magic, "n+1")!=0)
872 return(1);
873
874 /* Check if byte swapping is needed */
875 little=little_endian(); if(verbose>3) printf(" little := %d\n", little);
876 if(little==dsr->byte_order) same_order=1; else same_order=0;
877
878 /* Make sure that buffers are all zeroes to begin with */
879 memset(buf1, 0, sizeof(NIFTI_HEADER_SIZE));
880 memset(buf2, 0, sizeof(NIFTI_HEADER_EXTENDER_SIZE));
881
882 /* Copy header contents into buffer */
883 if(verbose>2) printf(" setting write buffer\n");
884 bptr=buf1+0;
885 memcpy(bptr, &dsr->h.sizeof_hdr, 4); if(!same_order) swawbip(bptr, 4);
886 bptr=buf1+4;
887 memcpy(bptr, &dsr->h.data_type, 10);
888 bptr=buf1+14;
889 memcpy(bptr, &dsr->h.db_name, 18);
890 bptr=buf1+32;
891 memcpy(bptr, &dsr->h.extents, 4); if(!same_order) swawbip(bptr, 4);
892 bptr=buf1+36;
893 memcpy(bptr, &dsr->h.session_error, 2); if(!same_order) swabip(bptr, 2);
894 bptr=buf1+38;
895 memcpy(bptr, &dsr->h.regular, 1);
896 bptr=buf1+39;
897 memcpy(bptr, &dsr->h.dim_info, 1);
898
899 bptr=buf1+40;
900 memcpy(bptr, dsr->h.dim, 16); if(!same_order) swabip(bptr, 16);
901 bptr=buf1+56;
902 memcpy(bptr, &dsr->h.intent_p1, 4); if(!same_order) swawbip(bptr, 4);
903 bptr=buf1+60;
904 memcpy(bptr, &dsr->h.intent_p2, 4); if(!same_order) swawbip(bptr, 4);
905 bptr=buf1+64;
906 memcpy(bptr, &dsr->h.intent_p3, 4); if(!same_order) swawbip(bptr, 4);
907 bptr=buf1+68;
908 memcpy(bptr, &dsr->h.intent_code, 2); if(!same_order) swabip(bptr, 2);
909 bptr=buf1+70;
910 memcpy(bptr, &dsr->h.datatype, 2); if(!same_order) swabip(bptr, 2);
911 bptr=buf1+72;
912 memcpy(bptr, &dsr->h.bitpix, 2); if(!same_order) swabip(bptr, 2);
913 bptr=buf1+74;
914 memcpy(bptr, &dsr->h.slice_start, 2); if(!same_order) swabip(bptr, 2);
915 bptr=buf1+76;
916 memcpy(bptr, dsr->h.pixdim, 32); if(!same_order) swawbip(bptr, 32);
917 bptr=buf1+108;
918 memcpy(bptr, &dsr->h.vox_offset, 4); if(!same_order) swawbip(bptr, 4);
919 bptr=buf1+112;
920 memcpy(bptr, &dsr->h.scl_slope, 4); if(!same_order) swawbip(bptr, 4);
921 bptr=buf1+116;
922 memcpy(bptr, &dsr->h.scl_inter, 4); if(!same_order) swawbip(bptr, 4);
923 bptr=buf1+120;
924 memcpy(bptr, &dsr->h.slice_end, 2); if(!same_order) swabip(bptr, 2);
925 bptr=buf1+122;
926 memcpy(bptr, &dsr->h.slice_code, 1);
927 bptr=buf1+123;
928 memcpy(bptr, &dsr->h.xyzt_units, 1);
929 bptr=buf1+124;
930 memcpy(bptr, &dsr->h.cal_max, 4); if(!same_order) swawbip(bptr, 4);
931 bptr=buf1+128;
932 memcpy(bptr, &dsr->h.cal_min, 4); if(!same_order) swawbip(bptr, 4);
933 bptr=buf1+132;
934 memcpy(bptr, &dsr->h.slice_duration, 4); if(!same_order) swawbip(bptr, 4);
935 bptr=buf1+136;
936 memcpy(bptr, &dsr->h.toffset, 4); if(!same_order) swawbip(bptr, 4);
937 bptr=buf1+140;
938 memcpy(bptr, &dsr->h.glmax, 4); if(!same_order) swawbip(bptr, 4);
939 bptr=buf1+144;
940 memcpy(bptr, &dsr->h.glmin, 4); if(!same_order) swawbip(bptr, 4);
941
942 bptr=buf1+148;
943 memcpy(bptr, dsr->h.descrip, 80);
944 bptr=buf1+228;
945 memcpy(bptr, dsr->h.aux_file, 24);
946 bptr=buf1+252;
947 memcpy(bptr, &dsr->h.qform_code, 2); if(!same_order) swabip(bptr, 2);
948 bptr=buf1+254;
949 memcpy(bptr, &dsr->h.sform_code, 2); if(!same_order) swabip(bptr, 2);
950 bptr=buf1+256;
951 memcpy(bptr, &dsr->h.quatern_b, 4); if(!same_order) swawbip(bptr, 4);
952 bptr=buf1+260;
953 memcpy(bptr, &dsr->h.quatern_c, 4); if(!same_order) swawbip(bptr, 4);
954 bptr=buf1+264;
955 memcpy(bptr, &dsr->h.quatern_d, 4); if(!same_order) swawbip(bptr, 4);
956 bptr=buf1+268;
957 memcpy(bptr, &dsr->h.qoffset_x, 4); if(!same_order) swawbip(bptr, 4);
958 bptr=buf1+272;
959 memcpy(bptr, &dsr->h.qoffset_y, 4); if(!same_order) swawbip(bptr, 4);
960 bptr=buf1+276;
961 memcpy(bptr, &dsr->h.qoffset_z, 4); if(!same_order) swawbip(bptr, 4);
962 bptr=buf1+280;
963 memcpy(bptr, dsr->h.srow_x, 16); if(!same_order) swawbip(bptr, 16);
964 bptr=buf1+296;
965 memcpy(bptr, dsr->h.srow_y, 16); if(!same_order) swawbip(bptr, 16);
966 bptr=buf1+312;
967 memcpy(bptr, dsr->h.srow_z, 16); if(!same_order) swawbip(bptr, 16);
968 bptr=buf1+328;
969 memcpy(bptr, dsr->h.intent_name, 16);
970 bptr=buf1+344;
971 memcpy(bptr, dsr->h.magic, 4);
972
973 /* Open header file for write; do not delete old contents, since this
974 function may be called to update single format NIfTI */
975 if(strcmp(dsr->h.magic, "ni1")==0) { // dual file format
976 if(verbose>2) printf(" creating NIfTI header %s\n", filename);
977 fp=fopen(filename, "wb");
978 } else if(access(filename, 0)==-1) { // single file format, not exists
979 if(verbose>2) printf(" creating NIfTI header %s\n", filename);
980 fp=fopen(filename, "wb");
981 } else { // single file format, exists already
982 if(verbose>2) printf(" opening NIfTI header %s\n", filename);
983 fp=fopen(filename, "r+b");
984 }
985 if(fp==NULL) {
986 if(status!=NULL) strcpy(status, "cannot open Nifti header for write");
987 return(2);
988 }
989
990 /* Write header */
991 if(verbose>2) printf(" writing NIfTI header\n");
992 if(fwrite(buf1, 1, NIFTI_HEADER_SIZE, fp) != NIFTI_HEADER_SIZE) {
993 if(status!=NULL) strcpy(status, "cannot write Nifti header");
994 fclose(fp); return(3);
995 }
996
997 /* Write extender, if necessary (leave the contents 0 0 0 0 for now) */
998 if(verbose>2) printf(" writing NIfTI extender\n");
999 if(fwrite(buf2, 1, NIFTI_HEADER_EXTENDER_SIZE, fp)!= NIFTI_HEADER_EXTENDER_SIZE) {
1000 if(status!=NULL) strcpy(status, "cannot write Nifti header extender");
1001 fclose(fp); return(3);
1002 }
1003
1004 fclose(fp);
1005
1006 if(verbose>2) {printf(" complete Nifti header was written\n"); fflush(stdout);}
1007 if(status!=NULL) strcpy(status, "complete Nifti header was written");
1008 return(0);
1009}
#define NIFTI_HEADER_EXTENDER_SIZE

Referenced by imgWriteNiftiFrame().

◆ pxlAdd()

int pxlAdd ( IMG_PIXELS * list,
IMG_PIXEL * pxl )
extern

Add given pixel into IMG_PIXELS data.

Returns
0 if successful.
Author
Vesa Oikonen
See also
pxlInit, pxlFree, pxlAllocate, pxlMakeRoom, pxlRm, pxlRead, pxlWrite
Parameters
listPointer to IMG_PIXELS struct, which must be initiated. Memory is added if needed, and pxlNr increased.
pxlPointer to IMG_PIXEL struct to add.

Definition at line 139 of file pixel.c.

145 {
146 if(list==NULL || pxl==NULL) return(1);
147 int ret;
148 if((ret=pxlAllocateMore(list, 1))!=0) return(ret);
149 list->p[list->pxlNr].x=pxl->x;
150 list->p[list->pxlNr].y=pxl->y;
151 list->p[list->pxlNr].z=pxl->z;
152 list->p[list->pxlNr].f=pxl->f;
153 list->pxlNr++;
154 return(0);
155}
int pxlAllocateMore(IMG_PIXELS *pxl, long long int pxlNr)
Definition pixel.c:74
IMG_PIXEL * p
long long int pxlNr

Referenced by imgMaskFloodFill().

◆ pxlAddFromMask()

long long int pxlAddFromMask ( IMG_PIXELS * list,
IMG * img )
extern

Add pixel(s) from mask image into IMG_PIXELS data.

Returns
the nr of added pixels.
See also
pxlInit, pxlFree, pxlAdd
Author
Vesa Oikonen
Parameters
listPointer to IMG_PIXELS struct, which must be initiated. Memory is added if needed, and pxlNr increased.
imgPointer to mask image.

Definition at line 185 of file pixel.c.

191 {
192 if(list==NULL || img==NULL) return(1);
193 if(img->dimz<1 || img->dimy<1 || img->dimx<1 || img->dimt<1) return(0);
194 long long int n=0;
195 for(int zi=0; zi<img->dimz; zi++)
196 for(int yi=0; yi<img->dimy; yi++)
197 for(int xi=0; xi<img->dimx; xi++)
198 if(fabs(img->m[zi][yi][xi][0])>=0.5) n++;
199 if(n==0) return(0);
200 if(pxlAllocateMore(list, n)!=0) return(0);
201 for(int zi=0; zi<img->dimz; zi++)
202 for(int yi=0; yi<img->dimy; yi++)
203 for(int xi=0; xi<img->dimx; xi++)
204 if(fabs(img->m[zi][yi][xi][0])>=0.5) {
205 list->p[list->pxlNr].x=1+xi;
206 list->p[list->pxlNr].y=1+yi;
207 list->p[list->pxlNr].z=1+zi;
208 list->p[list->pxlNr].f=0;
209 list->pxlNr++;
210 }
211 return(n);
212}

◆ pxlAllocate()

int pxlAllocate ( IMG_PIXELS * pxl,
long long int pxlNr )
extern

Allocate memory for IMG_PIXELS data. Any previous contents are deleted. Return Returns 0 when successful.

See also
pxlInit, pxlAllocateMore, pxlFree
Parameters
pxlPointer to initiated IMG_PIXELS struct data; any old contents are deleted. pxlNr inside the struct is set to or kept at zero.
pxlNrNr of pixels to allocate

Definition at line 44 of file pixel.c.

50 {
51 if(pxl==NULL) return(1);
52 /* Delete any previous contents */
53 pxlFree(pxl);
54 /* If no memory is requested, then just return */
55 if(pxlNr<1) return(0);
56
57 /* Allocate memory for IMG_PIXEL data */
58 pxl->p=(IMG_PIXEL*)malloc(pxlNr*sizeof(IMG_PIXEL));
59 if(pxl->p==NULL) return(2);
60 for(long long int i=0; i<pxlNr; i++) {
61 pxl->p[i].x=pxl->p[i].y=pxl->p[i].z=pxl->p[i].f=0;
62 }
63 pxl->_pxlNr=pxlNr;
64 return(0);
65}
void pxlFree(IMG_PIXELS *pxl)
Definition pixel.c:28
long long int _pxlNr

Referenced by pxlAllocateMore().

◆ pxlAllocateMore()

int pxlAllocateMore ( IMG_PIXELS * pxl,
long long int pxlNr )
extern

Allocate memory for more IMG_PIXELS data. Any previous contents are preserved. Return Returns 0 when successful.

See also
pxlInit, pxlFree, pxlAllocate, pxlMakeRoom
Parameters
pxlPointer to initiated IMG_PIXELS struct data; any old contents are preserved, but existing data is not required. pxlNr inside the struct is set to or kept at zero.
pxlNrNr of additional pixels to allocate; if struct contains unused space for requested pixels already, then nothing is done.

Definition at line 74 of file pixel.c.

82 {
83 if(pxl==NULL) return(1);
84 /* If no memory is requested, then just return */
85 if(pxlNr<1) return(0);
86 /* If none allocated previously then use pxlAllocate */
87 if(pxl->_pxlNr==0) return(pxlAllocate(pxl, pxlNr));
88 /* Check if there is enough space already */
89 long long int newPxlNr, addPxlNr;
90 newPxlNr=pxl->pxlNr+pxlNr; addPxlNr=newPxlNr-pxl->_pxlNr;
91 if(addPxlNr<=0) return(0);
92 /* Reallocate */
93 IMG_PIXEL *pxlPtr;
94 pxlPtr=realloc(pxl->p, sizeof(IMG_PIXEL)*newPxlNr);
95 if(pxlPtr==NULL) return(2);
96 pxl->p=pxlPtr;
97 for(int i=pxl->_pxlNr; i<newPxlNr; i++)
98 pxl->p[i].x=pxl->p[i].y=pxl->p[i].z=pxl->p[i].f=0;
99 pxl->_pxlNr=newPxlNr;
100 return(0);
101}
int pxlAllocate(IMG_PIXELS *pxl, long long int pxlNr)
Definition pixel.c:44

Referenced by pxlAdd(), pxlAddFromMask(), pxlMakeRoom(), and pxlRead().

◆ pxlFree()

void pxlFree ( IMG_PIXELS * pxl)
extern

Free memory allocated for IMG_PIXELS. All data is cleared.

See also
pxlInit, pxlAllocate
Parameters
pxlPointer to IMG_PIXELS struct

Definition at line 28 of file pixel.c.

31 {
32 if(pxl==NULL) return;
33 free(pxl->p);
34 pxlInit(pxl);
35}
void pxlInit(IMG_PIXELS *pxl)
Definition pixel.c:14

Referenced by imgMaskFloodFill(), and pxlAllocate().

◆ pxlGet()

int pxlGet ( IMG_PIXELS * list,
long long int i,
IMG_PIXEL * pxl )
extern

Get a pixel from IMG_PIXELS list.

See also
pxlInit, pxlFree, pxlAllocate, pxlMakeRoom, pxlAdd, pxlRead
Returns
0 if successful.
Parameters
listPointer to IMG_PIXELS struct, containing the list of pixels.
iPixel list index [0..list->pxlNr-1].
pxlPointer to IMG_PIXEL struct into which pixel coordinates are written.

Definition at line 163 of file pixel.c.

170 {
171 if(list==NULL || pxl==NULL || i<0 || i>=list->pxlNr) return(1);
172 pxl->x=list->p[i].x;
173 pxl->y=list->p[i].y;
174 pxl->z=list->p[i].z;
175 return(0);
176}

Referenced by imgMaskFloodFill().

◆ pxlInit()

void pxlInit ( IMG_PIXELS * pxl)
extern

Initiate the IMG_PIXELS struct before any use.

See also
pxlAllocate, pxlFree
Author
Vesa Oikonen
Parameters
pxlPointer to IMG_PIXELS

Definition at line 14 of file pixel.c.

17 {
18 if(pxl==NULL) return;
19 pxl->pxlNr=pxl->_pxlNr=0;
20 pxl->p=NULL;
21}

Referenced by imgMaskFloodFill(), and pxlFree().

◆ pxlMakeRoom()

int pxlMakeRoom ( IMG_PIXELS * list,
long long int i,
long long int n )
extern

Make room for new pixels in the IMG_PIXELS list, allocating more memory if needed. Previous contents are preserved but moved in the list.

See also
pxlAllocateMore
Returns
0 if successful.
Parameters
listPointer to IMG_PIXELS struct with existing contents.
iIndex [0..pxlNr] of the new room start position.
nNr of empty list items to add.

Definition at line 110 of file pixel.c.

117 {
118 if(list==NULL || i>list->pxlNr) return(1);
119 /* Check whether anything needs to be added */
120 if(n<1) return(0);
121 /* If user wanted room in the end, then just add the memory */
122 if(i==list->pxlNr) return(pxlAllocateMore(list, n));
123 /* Otherwise, first add the space */
124 if(pxlAllocateMore(list, n)!=0) return(2);
125 /* and the move previous data forward in the list */
126 for(long long int li=list->pxlNr-1; li>=i; li--) list->p[li+n]=list->p[li];
127 /* and add pxlNr */
128 list->pxlNr+=n;
129 return(0);
130}

Referenced by imgMaskFloodFill().

◆ pxlMove()

void pxlMove ( IMG_PIXELS * list,
long long int from,
long long int to )
extern

Move pixel from one slot to another inside IMG_PIXELS data, changing the position of others accordingly.

See also
pxlInit, pxlFree, pxlAllocate, pxlRm, pxlMakeRoom
Parameters
listPointer to IMG_PIXELS struct, which must be initiated.
fromIndex [0.._pxlNr-1] of source position.
toIndex [0.._pxlNr-1] of target position.

Definition at line 220 of file pixel.c.

227 {
228 if(list==NULL || from<0 || to<0) return;
229 if(from>=list->_pxlNr || to>=list->_pxlNr) return;
230 if(from==to) return;
231 long long int i=from;
232 IMG_PIXEL tmp=list->p[from];
233 if(from>to) {
234 for(long long int i=from; i>to; i--) list->p[i]=list->p[i-1];
235 } else {
236 for(long long int i=from; i<to; i++) list->p[i]=list->p[i+1];
237 }
238 list->p[i]=tmp;
239 return;
240}

Referenced by pxlRm().

◆ pxlRead()

int pxlRead ( IMG_PIXELS * pxl,
const char * fname,
char * status )
extern

Read IMG_PIXELS data from specified file.

See also
pxlInit, pxlFree, pxlWrite
Returns
0 if successful.
Author
Vesa Oikonen
Parameters
pxlPointer to IMG_PIXELS struct, into which contents of file are to be added; call pxlInit() once before using this function.
fnamePointer to the file name; this string is not modified.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed

Definition at line 331 of file pixel.c.

340 {
341 if(pxl==NULL) {
342 if(status!=NULL) strcpy(status, "program error");
343 return(1);
344 }
345 int i, c, n, longest, ret;
346
347 /* Try to read the file */
348 FILE *fp;
349 fp=fopen(fname, "r");
350 if(fp==NULL) {
351 if(status!=NULL) strcpy(status, "cannot open file");
352 return(2);
353 }
354 /* Get the length of the longest line */
355 i=longest=0;
356 while((c=fgetc(fp))!=EOF) {
357 if(c==10 || c==13) {if(i>longest) longest=i; i=0;} else i++;
358 }
359 if(i>longest) longest=i;
360 rewind(fp); longest+=1;
361 /* and allocate memory for string of that length */
362 char *line, buf[20];
363 line=(char*)malloc((longest+1)*sizeof(char));
364 if(line==NULL) {
365 if(status!=NULL) strcpy(status, "out of memory");
366 fclose(fp); return(3);
367 }
368 /* Allocate space for a few pixels */
369 if(pxlAllocateMore(pxl, 10)!=0) {
370 if(status!=NULL) strcpy(status, "out of memory");
371 fclose(fp); free(line); return(3);
372 }
373 /* Read data lines */
374 while(fgets(line, longest, fp)!=NULL) {
375 /* forget comment lines */
376 if(line[0]=='#') continue;
377 /* get nr of tokens on this line */
378 n=strTokenNr(line, " ,;\t\n\r"); if(n==0) continue;
379 if(n<3 || n>4) {
380 if(status!=NULL) strcpy(status, "invalid format");
381 fclose(fp); free(line); return(4);
382 }
383 /* Allocate more memory if necessary */
384 if(pxl->pxlNr==pxl->_pxlNr) {
385 if(pxlAllocateMore(pxl, 10)!=0) {
386 if(status!=NULL) strcpy(status, "out of memory");
387 fclose(fp); free(line); return(3);
388 }
389 }
390 /* Read the pixel coordinates */
391 ret=0; //printf("line := %s", line); printf("n := %d\n", n);
392 for(i=0; i<n; i++) {
393 if(strTokenNCpy(line, " ,;\t\n\r", 1+i, buf, 20)<1) {ret=1; break;}
394 //printf(" buf := %s\n", buf);
395 if((ret=atoi_with_check(buf, &c))!=0) break;
396 if(i==0) pxl->p[pxl->pxlNr].x=c;
397 else if(i==1) pxl->p[pxl->pxlNr].y=c;
398 else if(i==2) pxl->p[pxl->pxlNr].z=c;
399 else if(i==3) pxl->p[pxl->pxlNr].f=c;
400 }
401 if(ret) {
402 if(status!=NULL) strcpy(status, "invalid coordinate");
403 fclose(fp); free(line); return(4);
404 }
405 pxl->pxlNr++;
406 }
407 fclose(fp); free(line);
408 return(0);
409}
int atoi_with_check(const char *int_as_string, int *result_value)
Definition decpoint.c:238
int strTokenNCpy(const char *str1, const char *str2, int i, char *str3, int count)
Definition strext.c:45
int strTokenNr(const char *str1, const char *str2)
Definition strext.c:17

◆ pxlRm()

int pxlRm ( IMG_PIXELS * list,
long long int index )
extern

Remove specified pixel from IMG_PIXELS data.

Returns
0 if successful.
Author
Vesa Oikonen
See also
pxlInit, pxlFree, pxlRmDuplicates, pxlAdd, pxlAllocate, pxlMakeRoom, pxlGet
Parameters
listPointer to IMG_PIXELS struct, which must be initiated. Allocated memory is not reduced, but pxlNr is decreased.
indexIndex [0..pxlNr-1] of pixel to delete.

Definition at line 249 of file pixel.c.

255 {
256 if(list==NULL || index<0) return(1);
257 if(index>=list->pxlNr) return(0);
258 /* If last one, then just decrease the pxlNr */
259 if(index==list->pxlNr-1) {list->pxlNr--; return(0);}
260 /* Otherwise move it to the last place and then decrease the pxlNr */
261 pxlMove(list, index, list->pxlNr-1);
262 list->pxlNr--;
263 return(0);
264}
void pxlMove(IMG_PIXELS *list, long long int from, long long int to)
Definition pixel.c:220

Referenced by pxlRmDuplicates().

◆ pxlRmDuplicates()

long long int pxlRmDuplicates ( IMG_PIXELS * list)
extern

Remove duplicates from IMG_PIXELS data.

Returns
the nr of removed pixels.
Author
Vesa Oikonen
See also
pxlInit, pxlFree, pxlRm, pxlAdd, pxlAllocate, pxlMakeRoom, pxlGet
Parameters
listPointer to IMG_PIXELS struct, which must be initiated. Allocated memory is not reduced, but pxlNr is decreased.

Definition at line 273 of file pixel.c.

277 {
278 if(list==NULL || list->pxlNr<2) return(0);
279 long long int i=list->pxlNr-1, j, n=0;
280 while(i>0) {
281 for(j=0; j<i; j++) {
282 if(list->p[i].z!=list->p[j].z) continue;
283 if(list->p[i].x!=list->p[j].x) continue;
284 if(list->p[i].y!=list->p[j].y) continue;
285 pxlRm(list, i); n++; break;
286 }
287 i--;
288 }
289 return(n);
290}
int pxlRm(IMG_PIXELS *list, long long int index)
Definition pixel.c:249

◆ pxlWrite()

int pxlWrite ( IMG_PIXELS * pxl,
FILE * fp,
char * status )
extern

Write IMG_PIXELS data into specified file.

Returns
0 if successful.
Author
Vesa Oikonen
See also
pxlRead, pxlFree, pxlGet, pxlAdd
Parameters
pxlPointer to IMG_PIXELS struct, contents of which are to be written
fpOutput file pointer
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed

Definition at line 299 of file pixel.c.

307 {
308 if(pxl==NULL || pxl->pxlNr<1 || pxl->p==NULL) {
309 if(status!=NULL) strcpy(status, "no pixels to write");
310 return(1);
311 }
312 int n=7;
313 for(long long i=0; i<pxl->pxlNr && n>6; i++)
314 n=fprintf(fp, "%d,%d,%d,%d\n",
315 pxl->p[i].x, pxl->p[i].y, pxl->p[i].z, pxl->p[i].f);
316 if(n<7) {
317 if(status!=NULL) strcpy(status, "cannot write pixels into file");
318 return(2);
319 }
320 if(status!=NULL) strcpy(status, "ok");
321 return(0);
322}

◆ sif2img()

int sif2img ( SIF * sif,
IMG * img,
int copy_header,
int copy_frames,
int copy_counts,
int verbose )
extern

Set IMG contents based on data in SIF.

Returns
Returns 0 if successful.
Parameters
sifPointer to SIF struct from which content is copied to IMG.
imgPointer to IMG. Must be initiated with imgInit(), and allocated if frame time or count information is to be copied.
copy_headerSelect whether SIF header contents are copied (1) or not (0)
copy_framesSelect whether SIF frame times are copied (1) or not (0).
copy_countsSelect whether SIF count contents are copied (1) or not (0).
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 13 of file img_sif.c.

27 {
28 if(verbose>0)
29 printf("sif2img(sif, img, %d, %d, %d, ...)\n", copy_header, copy_frames, copy_counts);
30 if(img==NULL || sif==NULL) return 1;
31
32 if(copy_header) {
33 if(verbose>1) printf(" copying header.\n");
34 img->scanStart=sif->scantime;
36 if(strlen(sif->studynr)>0 && strcmp(sif->studynr, ".")!=0)
38 else
39 strcpy(img->studyNr, "");
40 }
41
42 if(copy_frames) {
43 if(verbose>1) printf(" copying frame times.\n");
44 if(sif->frameNr!=img->dimt) return(3);
45 for(int fi=0; fi<img->dimt; fi++) {
46 img->start[fi]=sif->x1[fi];
47 img->end[fi]=sif->x2[fi];
48 img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
49 }
50 }
51
52 if(copy_counts) {
53 if(verbose>1) printf(" copying count data.\n");
54 if(sif->frameNr!=img->dimt) return(3);
55 if(sif->colNr<4) return(4);
56 for(int fi=0; fi<img->dimt; fi++) {
57 img->prompts[fi]=sif->prompts[fi];
58 img->randoms[fi]=sif->randoms[fi];
59 img->weight[fi]=sif->weights[fi];
60 }
61 }
62
63 return 0;
64}

Referenced by imgReadAnalyze().

◆ sifEmpty()

void sifEmpty ( SIF * data)
extern

Free memory allocated for SIF. All contents are destroyed.

See also
sifInit, sifSetmem
Parameters
dataPointer to sif data struct.

Definition at line 33 of file sif.c.

36 {
37 if(SIF_TEST) printf("sifEmpty()\n");
38 if(data==NULL) return;
39 if(data->frameNr>0) {
40 free((char*)(data->x1)); free((char*)(data->x2));
41 free((char*)(data->prompts)); free((char*)(data->randoms));
42 free((char*)(data->trues)); free((char*)(data->weights));
43 data->frameNr=data->colNr=0;
44 }
45 data->scantime=(time_t)0; data->version=0;
46 strcpy(data->studynr, ""); strcpy(data->isotope_name, "");
47}
int SIF_TEST
Definition sif.c:6

Referenced by imgReadAnalyze(), imgReadAnalyzeFrame(), imgReadAnalyzeHeader(), imgReadModelingData(), imgReadNiftiFrame(), imgReadNiftiHeader(), imgSetWeights(), imgWriteNifti(), sifAllocateWithIMG(), sifRead(), and sifSetmem().

◆ sifExistentCounts()

int sifExistentCounts ( SIF * sif)
extern

Verify that SIF contains prompts and randoms.

Returns
Returns 0 if neither prompts or randoms can be found, 1 or 2 if prompts or randoms can be found, and 3 if both prompts and randoms are there.
See also
sifInit, sifRead, sifWeight
Parameters
sifPointer to SIF struct

Definition at line 207 of file weight.c.

210 {
211 int fi, p=0, r=0;
212 double v1, v2;
213 if(sif==NULL || sif->frameNr<1) return 0;
214 /* If just one frame, then value > 0 is fine */
215 if(sif->frameNr==1) {
216 if(sif->prompts[0]>0.00000001) p=1;
217 if(sif->randoms[0]>0.00000001) r=2;
218 return(p+r);
219 }
220 /* Otherwise, check also that frames have different count level */
221 for(fi=1; fi<sif->frameNr; fi++) {
222 v1=sif->prompts[fi]-sif->prompts[fi-1]; if(fabs(v1)>0.001) p=1;
223 v2=sif->randoms[fi]-sif->randoms[fi-1]; if(fabs(v2)>0.001) r=2;
224 if((p+r)>2) break;
225 }
226 return(p+r);
227}

◆ sifInit()

void sifInit ( SIF * data)
extern

Initiate SIF structure. This should be called once before first use.

See also
sifEmpty, sifRead, sifSetmem
Parameters
dataPointer to sif data struct.

Definition at line 17 of file sif.c.

20 {
21 if(SIF_TEST) printf("sifInit()\n");
22 if(data==NULL) return;
23 memset(data, 0, sizeof(SIF));
24 data->frameNr=data->colNr=0;
25}

Referenced by imgReadAnalyze(), imgReadAnalyzeFrame(), imgReadAnalyzeHeader(), imgReadModelingData(), imgReadNiftiFrame(), imgReadNiftiHeader(), imgSetWeights(), imgWriteAnalyze(), and imgWriteNifti().

◆ sifModerateTrues()

void sifModerateTrues ( SIF * sif,
double limit )
extern

Moderate the trues in SIF.

True values in SIF are used to calculate weight factors for time frames. If trues are very low in certain frames, the weight factors in other frames may become very low. This function finds the maximum trues, and adds max/limit to each trues value, if min trues < max trues / limit. Negative trues are always eliminated.

See also
sifWeight, sifModerateWeights, sifRead, sifWrite, sifWeightNorm
Parameters
sifPointer to SIF in which the trues are moderated
limitMax trues / limit is added to all trues values; 100.0 might be good

Definition at line 131 of file weight.c.

136 {
137 if(SIF_TEST) printf("sifModerateTrues(*sif, %g)\n", limit);
138
139 if(sif==NULL || sif->frameNr<2) return;
140 if(limit<=1.0) return;
141
142 int fi;
143 double w, f;
144 for(w=f=sif->trues[0], fi=1; fi<sif->frameNr; fi++) {
145 if(sif->trues[fi]>w) w=sif->trues[fi];
146 else if(sif->trues[fi]<f) f=sif->trues[fi];
147 }
148 if(f*limit<w) {
149 for(w/=limit, fi=0; fi<sif->frameNr; fi++)
150 if(sif->trues[fi]>0.0) sif->trues[fi]+=w; else sif->trues[fi]=w;
151 } else {
152 for(fi=0; fi<sif->frameNr; fi++)
153 if(sif->trues[fi]<0.0) sif->trues[fi]=0.0;
154 }
155}
int SIF_TEST
Definition sif.c:6

Referenced by imgSetWeights().

◆ sifModerateWeights()

void sifModerateWeights ( SIF * sif,
double limit )
extern

Moderate the weights in SIF.

This function finds the maximum weight, and adds max/limit to each weight value (except if weight is 0), if min weight < max/limit. Negative weights are set to zero.

See also
sifWeight, sifModerateTrues, sifRead, sifWrite, sifWeightNorm
Parameters
sifPointer to SIF in which the weights are moderated
limitMax weight / limit is added to all weights; 100.0 might be good

Definition at line 167 of file weight.c.

172 {
173 if(SIF_TEST) printf("sifModerateWeights(*sif, %g)\n", limit);
174
175 if(sif==NULL || sif->frameNr<2) return;
176 if(limit<=1.0) return;
177
178 int fi;
179 double w, f;
180 w=f=nan("");
181 for(fi=0; fi<sif->frameNr; fi++) {
182 if(isnan(sif->weights[fi])) continue;
183 if(sif->weights[fi]<=0.0) {sif->weights[fi]=0.0; continue;}
184 if(isnan(w)) w=sif->weights[fi];
185 if(isnan(f)) f=sif->weights[fi];
186 if(sif->weights[fi]>w) w=sif->weights[fi];
187 if(sif->weights[fi]<f) f=sif->weights[fi];
188 }
189 if(isnan(w) || isnan(f)) return;
190
191 if(f*limit<w) {
192 for(w/=limit, fi=0; fi<sif->frameNr; fi++)
193 if(sif->weights[fi]>0.0) sif->weights[fi]+=w;
194 }
195}

◆ sifPrint()

void sifPrint ( SIF * data)
extern

Prints to stdout the contents of SIF data structure.

See also
sifWrite, sifRead
Parameters
dataPointer to SIF structure.

Definition at line 234 of file sifio.c.

237 {
238 char buf[32];
239
240 if(!ctime_r_int((time_t*)&data->scantime, buf))
241 strcpy(buf, "1900-01-01 00:00:00");
242 printf("Scan time: %s\n", buf);
243 printf("Isotope: %s\n", data->isotope_name);
244 printf("Frame start end Prompts Randoms Trues Weight\n");
245 for(int i=0; i<data->frameNr; i++) {
246 printf(" %03d %6.1f %6.1f %10.0f %10.0f %10.0f %8.6f\n", i+1,
247 data->x1[i], data->x2[i], data->prompts[i], data->randoms[i],
248 data->trues[i], data->weights[i]);
249 }
250 return;
251}

Referenced by imgSetWeights(), and sifAllocateWithIMG().

◆ sifRead()

int sifRead ( char * filename,
SIF * data )
extern

Reads SIF file contents to the specified data structure.

Weights are set to 1.

Returns
Returns 0 if ok, 1 invalid input, 2 failed to open file, 3 failed to allocate memory, 4 header parsing error, 5 wrong file type, 6 failed to allocate memory, 8 parse error, 9 wrong data format
See also
sifInit, sifEmpty, sifWrite, sifExistentCounts, textfileReadLines
Parameters
filenameSIF file name to be read.
dataPointer to initiated SIF structure; any existing contents will be deleted.

Definition at line 21 of file sifio.c.

26 {
27 int i, n, frameNr, yy, mm, dd, h, m, s;
28 int ret;
29 struct tm *st;
30 time_t timet;
31
32
33 if(SIF_TEST) printf("sifRead(%s, *sif)\n", filename);
34 if(filename==NULL || data==NULL) return(1);
35 /* Empty data */
36 sifEmpty(data);
37
38 /* Read the lines of the SIF */
40 //printf("reading lines\n");
41 ret=textfileReadLines(filename, &tlst);
42 if(ret>2) {strcpy(siferrmsg, "cannot read file"); return(5);}
43 else if(ret>0) {strcpy(siferrmsg, "cannot open file"); return(2);}
44 if(0) {
45 printf("lineNr:=%d\n", tlst.token_nr);
46 for(int i=0; i<tlst.token_nr; i++) printf("token[%d] := '%s'\n", i, tlst.tok[i]);
47 }
48
49 /* Remove any comment or empty lines */
50 //printf("removing any comment lines\n");
51 i=tlst.token_nr-1;
52 while(i>=0 && tlst.token_nr>0) {
53 //printf("i=%d line='%s'\n", i, tlst.tok[i]);
54 if(strnlen(tlst.tok[i], 2)<1 || asciiCommentLine(tlst.tok[i], NULL)) {
55 //printf("-> remove\n");
56 str_token_list_del(&tlst, 1+i);
57 }
58 i--;
59 }
60 if(tlst.token_nr<1) {
62 strcpy(siferrmsg, "wrong format"); return(4);
63 }
64 if(0) {
65 printf("lineNr:=%d\n", tlst.token_nr);
66 for(int i=0; i<tlst.token_nr; i++)
67 printf("token[%d] := '%s'\n", i, tlst.tok[i]);
68 }
69
70 /* Read the title line */
71 if(SIF_TEST) printf("SIF title := '%s'\n", tlst.tok[0]);
72 n=sscanf(tlst.tok[0], "%d/%d/%d %d:%d:%d %d %d %d %255s %7s",
73 &dd, &mm, &yy, &h, &m, &s, &frameNr, &data->colNr, &data->version,
74 data->studynr, data->isotope_name);
75 //printf("tok_n := %d\n", n);
76 if(n<9 || frameNr<1 || data->colNr<2 || data->version!=1) {
77 if(SIF_TEST) printf("invalid SIF title line\n");
78 strcpy(siferrmsg, "wrong filetype");
80 return(4);
81 }
82 timet=time(NULL); st=gmtime(&timet);
83 if(st!=NULL) {
84 st->tm_mday=dd; st->tm_mon=mm-1; st->tm_year=yy-1900;
85 st->tm_hour=h; st->tm_min=m; st->tm_sec=s; st->tm_isdst=-1;
86 data->scantime=timegm(st); if(data->scantime==-1) data->scantime=0;
87 } else {
88 data->scantime=0;
89 }
90 //printf("frameNr := %d\n", frameNr);
91
92 /* Allocate memory for SIF data */
93 if(sifSetmem(data, frameNr)) {
95 strcpy(siferrmsg, "cannot allocate SIF"); return(6);
96 }
97
98 /* Read data lines into SIF */
99 i=0;
100 while(i<data->frameNr && i<tlst.token_nr-1) {
101 //printf("i := %d\n", i);
102 data->prompts[i]=data->randoms[i]=0.0;
103 n=sscanf(tlst.tok[1+i], "%lf %lf %lf %lf", &data->x1[i], &data->x2[i],
104 &data->prompts[i], &data->randoms[i]);
105 //printf("n := %d\n", n);
106 //if(n<data->colNr || data->x2[i]<data->x1[i]) {
107 if(n<2) {
108 strcpy(siferrmsg, "wrong data format");
110 sifEmpty(data);
111 return(9);
112 }
113 if(data->x2[i]<data->x1[i]) {
114 strcpy(siferrmsg, "invalid time frames");
116 sifEmpty(data);
117 return(9);
118 }
119 i++;
120 }
122 if(i!=data->frameNr) {
123 strcpy(siferrmsg, "wrong data format");
124 sifEmpty(data);
125 return(9);
126 }
127
128
129 /* Calculate trues */
130 if(data->colNr>=4) for(i=0; i<data->frameNr; i++)
131 data->trues[i]=data->prompts[i]-data->randoms[i];
132 /* Set weights to 1.0 */
133 for(i=0; i<data->frameNr; i++) data->weights[i]=1.0;
134
135 return(0);
136}
char siferrmsg[128]
Definition sif.c:7
void str_token_list_empty(STR_TOKEN_LIST *lst)
Definition readfile.c:26
int str_token_list_del(STR_TOKEN_LIST *lst, int item)
Definition readfile.c:70
int textfileReadLines(const char *filename, STR_TOKEN_LIST *lst)
Definition readfile.c:136
void str_token_list_init(STR_TOKEN_LIST *lst)
Definition readfile.c:13
int asciiCommentLine(const char *line, int *cont)
Definition readfile.c:246

Referenced by imgReadAnalyze(), imgReadAnalyzeFrame(), imgReadAnalyzeHeader(), imgReadModelingData(), imgReadNiftiFrame(), imgReadNiftiHeader(), imgWriteAnalyze(), and imgWriteNifti().

◆ sifSetmem()

int sifSetmem ( SIF * data,
int frameNr )
extern

Allocates memory for SIF data.

See also
sifInit, sifEmpty
Returns
0 if ok, 1 failed memory allocation
Parameters
dataPointer to initiated sif data struct. Any existing data is destroyed.
frameNrNumber of PET time frames.

Definition at line 56 of file sif.c.

61 {
62 if(SIF_TEST) printf("sifSetmem()\n");
63 if(data==NULL) return(1);
64 /* Clear previous data, if necessary */
65 if(data->frameNr>0) sifEmpty(data);
66 if(frameNr<1) return(0);
67
68 /* Allocate memory */
69 data->x1=(double*)calloc(frameNr, sizeof(double));
70 data->x2=(double*)calloc(frameNr, sizeof(double));
71 data->prompts=(double*)calloc(frameNr, sizeof(double));
72 data->randoms=(double*)calloc(frameNr, sizeof(double));
73 data->trues=(double*)calloc(frameNr, sizeof(double));
74 data->weights=(double*)calloc(frameNr, sizeof(double));
75 if(data->x1==NULL || data->x2==NULL || data->prompts==NULL ||
76 data->randoms==NULL || data->trues==NULL || data->weights==NULL) {
77 strcpy(siferrmsg, "out of memory"); return(1);}
78 data->frameNr=frameNr;
79
80 return(0);
81}
void sifEmpty(SIF *data)
Definition sif.c:33
char siferrmsg[128]
Definition sif.c:7

Referenced by img2sif(), imgGetMicropetSIF(), sifAllocateWithIMG(), and sifRead().

◆ sifWeight()

void sifWeight ( SIF * data,
double halflife )
extern

Calculate weights for frames in SIF data based on true counts. Weights are normalized to have an average of 1.0.

Weights are calculated from formula weight=(frame duration)^2 / (trues in a frame). Before calling this routine, trues must be calculated as total counts - randoms. Counts in SIF are not corrected for physical decay. Therefore, isotope halflife must be known, if weights are to be calculated for decay corrected TACs. Isotope halflife must be set to 0, if weights are used for TACs that are not corrected for decay.

Reference: Mazoyer BM, Huesman RH, Budinger TF, Knittel BL. Dynamic PET data analysis. J Comput Assist Tomogr 1986; 10:645-653.

See also
sifInit, sifRead, sifWrite, sifEmpty, sifModerateTrues, sifModerateWeights, sifExistentCounts, sifWeightByFrames, dftWeightByFreq, dftDecayCorrection
Parameters
dataPointer to SIF data.
halflifeHalflife (in seconds) of the isotope; If halflife is 0, the weights are calculated for non-decay corrected data. If halflife is >0, the weights are calculated using decay corrected trues, but trues data in SIF are not changed.

Definition at line 28 of file weight.c.

36 {
37 int i;
38 double f, d;
39
40 if(SIF_TEST) printf("sifWeight(*sif, %g)\n", halflife);
41 /* Calculate weights */
42 for(i=0; i<data->frameNr; i++) {
43 if(data->trues[i]<1.0) data->trues[i]=1.0;
44 f=data->x2[i]-data->x1[i]; if(f<=0.0) f=1.0;
45 if(halflife<=1.0E-8)
46 d=1.0;
47 else
48 d=exp( ((data->x1[i]+data->x2[i])/2.0)*0.693147/halflife );
49 data->weights[i]=(f*f)/(d*data->trues[i]);
50 /*printf("%3d %g %g\n", i, data->trues[i], data->weights[i]);*/
51 }
52
53 /* Scale weights so that average weight is 1.0 */
54 sifWeightNorm(data);
55
56 return;
57}
void sifWeightNorm(SIF *d)
Definition weight.c:105

Referenced by imgSetWeights().

◆ sifWeightByFrames()

void sifWeightByFrames ( SIF * data,
double halflife )
extern

Calculate weights for frames in SIF data based on frame lengths. Weights are normalized to have an average of 1.0.

Weights are calculated from the simple formula weight=(frame duration), if isotope halflife is set to 0, and using formula weight=(frame duration)*exp(-t*ln(2)/halflife), if isotope halflife is given (less weight for late frames, which may be more suitable for PET data that is corrected for physical decay).

See also
sifInit, sifRead, sifWrite, sifEmpty, sifWeight, dftWeightByFreq
Parameters
dataPointer to SIF data.
halflifeHalflife (in seconds) of the isotope; If halflife is >0, the late frames are given less weight.

Definition at line 72 of file weight.c.

78 {
79 int i;
80 double f, d;
81
82 if(SIF_TEST) printf("sifWeightByFrames(*sif, %g)\n", halflife);
83 /* Calculate weights */
84 for(i=0; i<data->frameNr; i++) {
85 f=data->x2[i]-data->x1[i]; if(f<=0.0) f=1.0;
86 if(halflife<=1.0E-8)
87 d=1.0;
88 else
89 d=exp( -((data->x1[i]+data->x2[i])/2.0)*0.693147/halflife );
90 data->weights[i]=f*d;
91 }
92
93 /* Scale weights so that average weight is 1.0 */
94 sifWeightNorm(data);
95
96 return;
97}

◆ sifWeightNorm()

void sifWeightNorm ( SIF * d)
extern

Scale weights in SIF data so that average weight is 1.0, and the sum of weights equals the nr of frames.

See also
sifInit, sifRead, sifWrite, sifEmpty, sifWeight, sifWeightByFrames
Parameters
dPointer to SIF data.

Definition at line 105 of file weight.c.

108 {
109 if(SIF_TEST) printf("sifWeightNorm(*sif)\n");
110 int i;
111 double f=0.0;
112 for(i=0; i<d->frameNr; i++) f+=d->weights[i];
113 f/=(double)d->frameNr;
114 for(i=0; i<d->frameNr; i++) d->weights[i]/=f;
115 return;
116}

Referenced by sifWeight(), and sifWeightByFrames().

◆ sifWrite()

int sifWrite ( SIF * data,
char * filename )
extern

Write SIF data to a standard SIF file, emptying files old contents.

Returns
Returns 0 if successful, 1 invalid input, 2 failed to open file, 3 failed to write into file.
See also
sifInit, sifEmpty, sifRead, sifPrint, sifWeight
Parameters
dataPointer to SIF structure containing data to be written in file.
filenameFile name for SIF; Set to 'stdout' to print the contents on console. File is overwritten without backup.

Definition at line 145 of file sifio.c.

151 {
152 int i, n, req_decimals=0;
153 char buf[1024];
154 struct tm tm; //*st;
155
156
157 if(SIF_TEST) printf("sifWrite(*sif, %s)\n", filename);
158 /* Check data */
159 if(data->frameNr<1) {strcpy(siferrmsg, "no data to save"); return 1;}
160
161 /* Set file pointer */
162 FILE *fp;
163 int intofile;
164 if(strcasecmp(filename, "STDOUT")==0) {
165 fp=stdout; intofile=0;
166 } else {
167 /* Open file */
168 fp=fopen(filename, "w");
169 if(fp==NULL) {strcpy(siferrmsg, "cannot open file"); return 2;}
170 intofile=1;
171 }
172
173 /* Write title line */
174 if(!gmtime_r((time_t*)&data->scantime, &tm) || !strftime(buf, 1024, "%d/%m/%Y %H:%M:%S", &tm))
175 strcpy(buf, "1/1/1900 00:00:00");
176 n=fprintf(fp, "%s %d %d %d", buf, data->frameNr, data->colNr, data->version);
177 if(SIF_TEST) printf("%s %d %d %d\n", buf, data->frameNr, data->colNr, data->version);
178 if(n<7) {
179 strcpy(siferrmsg, "cannot write file"); if(intofile) fclose(fp);
180 return 2;
181 }
182 if(strlen(data->studynr)!=0 || strlen(data->isotope_name)!=0) {
183 /* Write also study number and isotope */
184 if(strlen(data->studynr)==0) fprintf(fp, " ."); else fprintf(fp, " %s", data->studynr);
185 if(strlen(data->isotope_name)>0) fprintf(fp, " %s", data->isotope_name);
186 }
187 fprintf(fp, "\n");
188
189 /* Check if frame times need to printed with decimals */
190 for(i=1, req_decimals=0; i<data->frameNr; i++) {
191 if(round(data->x1[i])==round(data->x1[i-1])) {req_decimals=1; break;}
192 if(round(data->x2[i])==round(data->x2[i-1])) {req_decimals=1; break;}
193 }
194
195 /* Write data lines */
196 for(i=0; i<data->frameNr; i++) {
197 if(req_decimals==0) n=fprintf(fp, "%.0f %.0f", data->x1[i], data->x2[i]);
198 else n=fprintf(fp, "%.1f %.1f", data->x1[i], data->x2[i]);
199 if(n<3) {
200 strcpy(siferrmsg, "cannot write file"); if(intofile) fclose(fp);
201 return 3;
202 }
203 if(data->colNr<=2) {n=fprintf(fp, "\n"); continue;}
204 n=fprintf(fp, " %.0f %.0f", data->prompts[i], data->randoms[i]);
205 if(n<1) {
206 strcpy(siferrmsg, "cannot write file"); if(intofile) fclose(fp);
207 return 3;
208 }
209 if(data->colNr<5) {n=fprintf(fp, "\n"); continue;}
210 n=fprintf(fp, " %.0f", data->trues[i]);
211 if(n<1) {
212 strcpy(siferrmsg, "cannot write file"); if(intofile) fclose(fp);
213 return 3;
214 }
215 if(data->colNr<6) {n=fprintf(fp, "\n"); continue;}
216 n=fprintf(fp, " %.5f\n", data->weights[i]);
217 if(n<1) {
218 strcpy(siferrmsg, "cannot write file"); if(intofile) fclose(fp);
219 return 3;
220 }
221 }
222
223 /* Close file */
224 if(intofile) fclose(fp);
225
226 return 0;
227}

Referenced by imgWriteAnalyze(), and imgWriteNifti().

◆ string_to_xyz()

int string_to_xyz ( char * str,
int * x,
int * y,
int * z )
extern

Read pixel location from a string representation of it.

See also
string_to_xyzf, vrdRead
Returns
Returns 0 if successful, >0 if not.
Parameters
strString in format x,y,z or x y z ; this string is not changed
xPixel location in x dimension
yPixel location in y dimension
zPixel location in z dimension

Definition at line 653 of file vol.c.

662 {
663 char *cptr, tmp[256];
664
665 strncpy(tmp, str, 255); tmp[255]=(char)0;
666 cptr=strtok(tmp, " ,;:()|-"); if(cptr==NULL) return 1;
667 *x=atoi(cptr); if(*x<1) return 1;
668 cptr=strtok(NULL, " ,;:()|-"); if(cptr==NULL) return 2;
669 *y=atoi(cptr); if(*y<1) return 1;
670 cptr=strtok(NULL, " ,;:()|-"); if(cptr==NULL) return 3;
671 *z=atoi(cptr); if(*z<1) return 1;
672 return 0;
673}

Referenced by vrdRead().

◆ string_to_xyzf()

int string_to_xyzf ( const char * str,
IMG_PIXEL * v )
extern

Read voxel coordinates including time frame from a string representation.

See also
string_to_xyz, irdRead
Returns
Returns 0 if successful, >0 if not.
Parameters
strString in format x,y,z,f or x y z f; frame (f) is optional; if f is not specified, then 0 is written in its place.
vPointer to image pixel struct; obligatory.

Definition at line 14 of file ird.c.

20 {
21 if(v==NULL) return 1;
22 v->x=v->y=v->z=v->f=0;
23
24 char *cptr, tmp[256];
25 strncpy(tmp, str, 255); tmp[255]=(char)0;
26 cptr=strtok(tmp, " ,;:()|-"); if(cptr==NULL) return 1;
27 v->x=atoi(cptr); if(v->x<1) return 1;
28 cptr=strtok(NULL, " ,;:()|-"); if(cptr==NULL) return 2;
29 v->y=atoi(cptr); if(v->y<1) return 1;
30 cptr=strtok(NULL, " ,;:()|-"); if(cptr==NULL) return 3;
31 v->z=atoi(cptr); if(v->z<1) return 1;
32 cptr=strtok(NULL, " ,;:()|-"); if(cptr==NULL) return 0;
33 v->f=atoi(cptr);
34 return 0;
35}

Referenced by irdRead().

◆ svol2img()

int svol2img ( SVOL * svol,
IMG * img,
int frame )
extern

Copy 3D short int volume as one time frame (1..dimt) into 4D image. Img must be allocated.

Parameters
svolshort volume structure
imgimage structure
frameframe number [1..img->dimt]
Returns
0 if ok, 1 invalid image, 2 invalid frame number, 3 (x,y) dimension inconsistency, 4 plane number inconsistency

Definition at line 385 of file vol.c.

385 {
386 unsigned short int zi, yi, xi, fi;
387
388 if(VOL_TEST) printf("svol2img(svol, img, %d)\n", frame);
389 /* Check input */
390 if(svol==NULL || svol->status!=IMG_STATUS_OCCUPIED) return(1);
391 svol->statmsg=_volStatusMessage[1];
392 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
393 if(frame<1 || img->dimt<frame) return(2);
394 if(img->dimx!=svol->dimx || img->dimy!=svol->dimy) return(3);
395 if(img->dimz!=svol->dimz) return(4);
396
397 /* Copy data */
398 fi=frame-1;
399 for(zi=0; zi<svol->dimz; zi++)
400 for(yi=0; yi<svol->dimy; yi++)
401 for(xi=0; xi<svol->dimx; xi++)
402 img->m[zi][yi][xi][fi]=(svol->scale_factor)*(float)svol->v[zi][yi][xi];
403
404 return(0);
405}

◆ svolAllocate()

int svolAllocate ( SVOL * svol,
int planes,
int rows,
int columns )
extern

Allocate memory for 3D short int volume. Returns 0 if ok.

Parameters
svolshort volume structure
planesnumber of planes [>=1]
rowsnumber of rows [>=1]
columnsnumber of columns [>=1]
Returns
0 if ok, 1 invalid image status, 2 invalid input, 5 failed to allocate memory for planes, 6 failed to allocate memory for rows, 8 failed to allocate memory for rows

Definition at line 204 of file vol.c.

204 {
205 unsigned short int zi, ri;
206 int vxlNr, vi;
207 short int **rptr, *cptr;
208
209 if(VOL_TEST) printf("svoiAllocate(*svol, %d, %d, %d)\n", planes, rows, columns);
210 /* Check arguments */
211 if(svol==NULL) return(1); else svol->statmsg=_volStatusMessage[1];
212 if(svol->status==IMG_STATUS_UNINITIALIZED) return(1);
213 if(planes<1 || rows<1 || columns<1) return(2);
214 vxlNr=planes*rows*columns;
215
216 /* Check if correct volume size is already allocated */
217 if(svol->status>=IMG_STATUS_OCCUPIED) {
218 if(planes==svol->dimz && rows==svol->dimy && columns==svol->dimx) {
219 for(vi=0; vi<vxlNr; vi++) svol->_vxl[vi]=0;
220 return(0); /* that's it */
221 } else {
222 svolEmpty(svol);
223 }
224 }
225 /* Allocate memory for volume data */
226 svol->_pln=(short int***)malloc((size_t)planes*sizeof(short int**));
227 if(svol->_pln==NULL) {
228 return(5);}
229 svol->_row=(short int**)malloc((size_t)planes*rows*sizeof(short int*));
230 if(svol->_row==NULL) {
231 free(svol->_pln); return(6);}
232 svol->_col=svol->_vxl=(short int*)calloc((size_t)planes*rows*columns, sizeof(short int));
233 if(svol->_vxl==NULL) {
234 free(svol->_pln); free(svol->_row); return(8);
235 }
236 /* Set data pointers */
237 rptr=svol->_row; cptr=svol->_col;
238 for(zi=0; zi<planes; zi++) {
239 svol->_pln[zi]=rptr;
240 for(ri=0; ri<rows; ri++) {
241 *rptr++=cptr; cptr+=columns;
242 }
243 }
244 svol->v=svol->_pln;
245 svol->plane=svol->_pln;
246 svol->column=svol->_col;
247 svol->row=svol->_row;
248 svol->voxel=svol->_vxl;
249 /* Ok */
250 svol->dimz=planes; svol->dimy=rows; svol->dimx=columns;
251 svol->statmsg=_volStatusMessage[0];
253 return(0);
254}
short int ** row
short int * voxel
short int *** plane
short int * column
void svolEmpty(SVOL *svol)
Definition vol.c:103

Referenced by img2svol().

◆ svolEmpty()

void svolEmpty ( SVOL * svol)
extern

Free memory allocated for short int volume.

Parameters
svolshort int volume structure

Definition at line 103 of file vol.c.

103 {
104 if(VOL_TEST) printf("svolEmpty()\n");
105 if(svol==NULL || svol->status<IMG_STATUS_OCCUPIED) return;
106 /* Free up memory */
107 if(svol->_vxl!=NULL) free(svol->_vxl);
108 //if(svol->_col!=NULL) free(svol->_col); Same as _vxl
109 if(svol->_row!=NULL) free(svol->_row);
110 if(svol->_pln!=NULL) free(svol->_pln);
111 /* Set variables */
112 svol->statmsg=_volStatusMessage[0];
113 svol->orientation=0;
114 svol->dimx=svol->dimy=svol->dimz=0;
115 svol->sizex=svol->sizey=svol->sizez=0;
116 svol->scale_factor=1.0;
117 svol->v=(short int***)NULL;
118 svol->voxel=(short int*)NULL;
119 svol->column=(short int*)NULL;
120 svol->row=(short int**)NULL;
121 svol->plane=(short int***)NULL;
122 /* Set status */
124}

Referenced by svolAllocate().

◆ svolInfo()

void svolInfo ( SVOL * svol,
FILE * fp )
extern

Prints short int volume information to specified file pointer, e.g. stdout

Parameters
svolshort volume structure
fptarget file pointer

Definition at line 439 of file vol.c.

439 {
440 if(VOL_TEST) printf("svolInfo()\n");
441 if(svol==NULL || svol->status<=IMG_STATUS_UNINITIALIZED) {
442 fprintf(fp, "Volume data is not initialized.\n"); return;}
443 if(svol->status==IMG_STATUS_INITIALIZED) {
444 fprintf(fp, "Volume data is initialized but empty.\n"); return;}
445 if(svol->status==IMG_STATUS_ERROR) fprintf(stdout, "Volume data has errors.\n");
446 fprintf(fp, "Volume status: %s\n", svol->statmsg);
447 fprintf(fp, "Patient orientation: %d\n", svol->orientation);
448 fprintf(fp, "Voxel sizes (x, y, z): %g %g %g mm\n",
449 svol->sizex, svol->sizey, svol->sizez);
450 fprintf(fp, "Dimensions (x, y, z): %d %d %d\n",
451 svol->dimx, svol->dimy, svol->dimz);
452 fprintf(fp, "Scale factor: %g\n", svol->scale_factor);
453 return;
454}

◆ svolInit()

void svolInit ( SVOL * svol)
extern

Initiate short int volume before any use of SVOL data; this should be called once.

Parameters
svolshort int volume structure

Definition at line 50 of file vol.c.

50 {
51 if(VOL_TEST) printf("svolInit()\n");
52 if(svol==NULL) return;
53 memset(svol, 0, sizeof(SVOL));
56 svol->orientation=0;
57 svol->dimx=svol->dimy=svol->dimz=0;
58 svol->sizex=svol->sizey=svol->sizez=0;
59 svol->scale_factor=1.0;
60 svol->v=(short int***)NULL;
61 svol->voxel=(short int*)NULL;
62 svol->column=(short int*)NULL;
63 svol->row=(short int**)NULL;
64 svol->plane=(short int***)NULL;
65}

◆ upetExists()

int upetExists ( const char * upetname,
char * hdrfile,
char * imgfile,
int verbose )
extern

Check if specified image filename is a Concorde/microPET file

Returns
Returns 0 if it is not, and >0 if it is: 1 if header but not image is found, or 2 if both image and header are found.
Parameters
upetnameFilename, either header file, image file, or base name without extensions.
hdrfileIf upetname is a Concorde/microPET file, then header filename will be written in this char pointer (space needs to allocated by caller); NULL if not needed.
imgfileIf upetname is a Concorde/microPET file, then image filename will be written in this char pointer (space needs to allocated by caller); NULL if not needed.
verboseVerbose level; if <=0, then nothing is printed into stdout

Definition at line 86 of file micropet.c.

99 {
100 char *cptr, basefile[FILENAME_MAX], temp[FILENAME_MAX];
101
102 if(upetname==NULL || strlen(upetname)==0) return(0);
103 if(verbose>0) printf("\n%s(%s, *str, *str)\n", __func__, upetname);
104
105 /* Construct the base file name wo extensions */
106 strlcpy(basefile, upetname, FILENAME_MAX);
107 cptr=strrchr(basefile, '.');
108 if(cptr!=NULL) {
109 if(strncasecmp(cptr, ".HDR", 4)==0 || strncasecmp(cptr, ".IMG", 4)==0 )
110 *cptr=(char)0;
111 }
112 cptr=strrchr(basefile, '.');
113 if(cptr!=NULL) {
114 if(strncasecmp(cptr, ".IMG", 4)==0 )
115 *cptr=(char)0;
116 }
117 if(verbose>1) printf("\n basefile := %s\n", basefile);
118
119 /* Header file exists? */
120 strlcpy(temp, basefile, FILENAME_MAX-4); strcat(temp, ".hdr");
121 if(access(temp, 0) == -1) {
122 strlcpy(temp, basefile, FILENAME_MAX-8); strcat(temp, ".img.hdr");
123 if(access(temp, 0) == -1) {
124 if(verbose>0) printf("\n hdr file not found or accessible.\n");
125 return(0);
126 }
127 }
128 /* Is this microPET header file? */
129 if(upetIsHeader(temp)==0) {
130 if(verbose>0)
131 printf("\n %s was not identified as microPET header file.\n", temp);
132 return(0);
133 }
134 /* Preserve header filename */
135 if(hdrfile!=NULL) strlcpy(hdrfile, temp, FILENAME_MAX);
136
137 /* Image file exists? */
138 strlcpy(temp, basefile, FILENAME_MAX); strcat(temp, ".img");
139 if(access(temp, 0) == -1) {
140 if(verbose>0) printf("\n %s not found or accessible.\n", temp);
141 return(1);
142 }
143 /* Preserve image filename */
144 if(imgfile!=NULL) strlcpy(imgfile, temp, FILENAME_MAX);
145
146 return(2);
147}
int upetIsHeader(char *hdrfile)
Definition micropet.c:55

Referenced by imgFormatDetermine(), imgMicropetToEcat7(), imgRead(), imgReadMicropetFrame(), and imgReadMicropetHeader().

◆ upetGetImageDimensions()

int upetGetImageDimensions ( FILE * fp,
int * z,
int * x,
int * y,
int * f )
extern

Read image dimensions from header.

Returns
Returns 0 when successful.
Parameters
fpFile pointer to MicroPET image header
zPointers to dimensions: planes
xPointers to dimensions: columns
yPointers to dimensions: rows
fPointers to dimensions: frames; if not existent (CT), enter NULL

Definition at line 154 of file micropet.c.

165 {
166 char tmp[MAX_MICROPET_LINE_LEN];
167
168 if(fp==NULL) return 1;
169 *z=*x=*y=0; if(f!=NULL) *f=0;
170 rewind(fp);
171
172 if(f!=NULL) {
173 if(upetHeaderReadParameter(fp, "time_frames", tmp)!=0) {
174 if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
175 }
176 *f=-1; (void)sscanf(tmp, "%d", f);
177 }
178 if(upetHeaderReadParameter(fp, "x_dimension", tmp)!=0) return 12;
179 *x=-1; (void)sscanf(tmp, "%d", x);
180 if(upetHeaderReadParameter(fp, "y_dimension", tmp)!=0) return 13;
181 *y=-1; (void)sscanf(tmp, "%d", y);
182 if(upetHeaderReadParameter(fp, "z_dimension", tmp)!=0) return 14;
183 *z=-1; (void)sscanf(tmp, "%d", z);
184 if(*z<1 || *x<1 || *y<1) return 2;
185 if(f!=NULL && *f<1) return 2;
186 return 0;
187}
int upetHeaderReadParameter(FILE *fp, char *parameter, char *value)
Definition micropet.c:16

Referenced by imgMicropetCTToEcat7(), and imgMicropetPETToEcat7().

◆ upetHeaderReadParameter()

int upetHeaderReadParameter ( FILE * fp,
char * parameter,
char * value )
extern

Read specified parameter value from Concorde/MicroPET header.

Returns
Returns 0 if parameter was found, even if value is empty, and 1, if parameter was not found, and <0 in case of other errors.
Parameters
fpFile pointer to Concorde/MicroPET header; parameter is read starting from file pointer forward, therefore rewind file pointer before calling this routine if you want to search parameter from beginning.
parameterPointer to string which contains the header parameter name.
valuePointer to allocated string where parameter value will be written; memory for at least MAX_MICROPET_LINE_LEN chars must be allocated; NULL if not needed.

Definition at line 16 of file micropet.c.

27 {
28 char *cptr, tmp[MAX_MICROPET_LINE_LEN];
29
30 if(fp==NULL) return -1;
31 if(parameter==NULL || strlen(parameter)<1) return -2;
32 do {
33 if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) return 1;
34 if(tmp[0]=='#') continue;
35 if(strncasecmp(tmp, parameter, strlen(parameter))!=0) continue;
36 /* Get parameter value, if one exists */
37 cptr=tmp+strlen(parameter)+1;
38 if(strlen(cptr)>0) {
39 if(value!=0) strnCopyClean(value, cptr, MAX_MICROPET_LINE_LEN-1);
40 } else {
41 if(value!=0) strcpy(value, "");
42 }
43 /* In any case, we found the parameter */
44 if(MICROPET_TEST>9) printf("%s := %s\n", parameter, value);
45 return 0;
46 } while(1);
47 return 0;
48}
int strnCopyClean(char *str1, const char *str2, int maxlen)
Definition quots.c:52
int MICROPET_TEST
Definition micropet.c:6

Referenced by imgGetMicropetFrameHeader(), imgGetMicropetMainHeader(), imgGetMicropetSIF(), imgMicropetCTToEcat7(), imgMicropetToEcat7(), upetGetImageDimensions(), upetIsHeader(), and upetScanStart().

◆ upetIsHeader()

int upetIsHeader ( char * hdrfile)
extern

Verify that given file is a valid Concorde/microPET file header file.

Returns
Returns 0 if not, and 1 if it is a valid header file.
Parameters
hdrfileConcorde/microPET file header filename, with correct extension

Definition at line 55 of file micropet.c.

58 {
59 char tmp[MAX_MICROPET_LINE_LEN];
60 FILE *fp;
61 int ret;
62
63 if(hdrfile==NULL || strlen(hdrfile)<5) return 0;
64 if(MICROPET_TEST>1) printf("\n%s(%s)\n", __func__, hdrfile);
65 if((fp=fopen(hdrfile, "r"))==NULL) return 0;
66 /* Check that first line starts with '#' */
67 if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) {fclose(fp); return 0;}
68 if(tmp[0]!='#') {fclose(fp); return 0;}
69 /* Check that certain header parameters do exist */
70 ret=upetHeaderReadParameter(fp, "version", tmp);
71 if(ret!=0) {fclose(fp); return 0;}
72 ret=upetHeaderReadParameter(fp, "model", tmp);
73 if(ret!=0) {fclose(fp); return 0;}
74 ret=upetHeaderReadParameter(fp, "institution", tmp);
75 if(ret!=0) {fclose(fp); return 0;}
76 fclose(fp);
77 return 1;
78}

Referenced by upetExists().

◆ upetReadImagedata()

int upetReadImagedata ( FILE * fp,
IFT * ift,
int frame,
float * data )
extern

Reads microPET image data, scaling values to floats if necessary.

Reads only one frame at a time!

Returns
0 when successful, otherwise <>0.
Parameters
fpfile opened previously in binary mode
iftmicroPET header in IFT struct
frameframe number to read [1..number of frames]
datapointer to image float data allocated previously

Definition at line 243 of file micropet.c.

252 {
253 int dimx, dimy, dimz=1, dimt=1;
254 int i, fi, data_type, data_bytes, little;
255 char *mdata, *mptr;
256 float f, cf, bf, *fptr;
257 short int *sptr;
258 int *iptr;
260
261
262 if(MICROPET_TEST) printf("%s(fp, ift, %d, data)\n", __func__, frame);
263
264 /* Check the arguments */
265 if(frame<=0 || fp==NULL || ift==NULL || data==NULL) return(1);
266
267 /* Get the image dimensions from header */
268 i=iftGetIntValue(ift, 0, "time_frames", &dimt, 0);
269 if(i<0 || dimt<1) {
270 i=iftGetIntValue(ift, 0, "total_frames", &dimt, 0);
271 if(i<0 || dimt<1) return 4;
272 }
273 i=iftGetIntValue(ift, 0, "x_dimension", &dimx, 0);
274 if(i<0 || dimx<1) return 4;
275 i=iftGetIntValue(ift, 0, "y_dimension", &dimy, 0);
276 if(i<0 || dimy<1) return 4;
277 i=iftGetIntValue(ift, 0, "z_dimension", &dimz, 0);
278 if(i<0 || dimz<1) return 4;
279 long long pxlNr=dimx*dimy*dimz;
280 if(pxlNr<1) return(4);
281 if(frame>dimt) return(3); // do not change this return value
282
283 /* Get the data type (little=Intel, big=Sun) */
284 i=iftGetIntValue(ift, 0, "data_type", &data_type, 0);
285 if(i<0 || data_type<1) return 5;
286 switch(data_type) {
287 case 1: data_bytes=1; little=little_endian(); break;
288 case 2: data_bytes=2; little=1; break;
289 case 3: data_bytes=4; little=1; break;
290 case 4: data_bytes=4; little=1; break;
291 case 5: data_bytes=4; little=0; break;
292 case 6: data_bytes=2; little=0; break;
293 case 7: data_bytes=4; little=0; break;
294 default: return 5;
295 }
296 long long rawSize=pxlNr*data_bytes;
297 if(MICROPET_TEST>0) {
298 printf(" data_type=%d\n data_bytes=%d\n", data_type, data_bytes);
299 printf(" pxlNr=%lld\n rawSize=%lld\n", pxlNr, rawSize);
300 }
301
302 /* Allocate memory for the binary data */
303 mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11);
304
305 /* Seek the start of current frame data */
306 long long start_pos=(frame-1)*rawSize;
307 if(MICROPET_TEST>2) printf(" start_pos=%lld\n", start_pos);
308 fseeko(fp, start_pos, SEEK_SET);
309 if(ftello(fp)!=start_pos) {
310 if(MICROPET_TEST>5) printf("could not move to start_pos\n");
311 free(mdata); return(7);
312 }
313
314 /* Read the data */
315 mptr=mdata;
316 {
317 size_t n=fread(mptr, rawSize, 1, fp);
318 if(n<1) {
319 if(MICROPET_TEST>5)
320 printf("could read only %zu bytes when request was %lld\n", n, rawSize);
321 free(mdata); return(8);
322 }
323 }
324
325 /* Convert byte order if necessary */
326 mptr=mdata;
327 if(little!=little_endian()) {
328 if(MICROPET_TEST>0) {printf("byte conversion\n"); fflush(stdout);}
329 switch(data_bytes) {
330 case 1: /* no conversion needed */ break;
331 case 2: swabip(mptr, rawSize); break;
332 case 4: swawbip(mptr, rawSize); break;
333 default:
334 if(MICROPET_TEST>5) printf("unsupported data_type := %d\n", data_type);
335 free(mdata); return(5);
336 }
337 }
338
339 /* Get scale factor for this frame */
340 strcpy(key, "frame"); sprintf(value, "%d", frame-1);
341 fi=iftGetFullmatchFrom(ift, 0, key, value, 0); if(fi<0) {free(mdata); return(6);}
342 i=iftGetFloatValue(ift, fi+1, "scale_factor", &f, 0);
343 if(i<0 || f<=0.0) {free(mdata); return(6);}
344 if(MICROPET_TEST>5) printf(" scale_factor := %g\n", f);
345
346 /* calibration factor */
347 i=iftGetFloatValue(ift, 0, "calibration_factor", &cf, 0);
348 if(i<0 || cf<0.0) {free(mdata); return 7;}
349 if(MICROPET_TEST>5) printf(" calibration_factor := %g\n", cf);
350 /* branching_fraction */
351 i=iftGetFloatValue(ift, 0, "isotope_branching_fraction", &bf, 0);
352 if(i<0 || bf<0.0) {free(mdata); return 7;}
353 if(MICROPET_TEST>5) printf(" branching_fraction := %g\n", bf);
354 if(cf>0.0) {f=cf; if(bf>0.0) f/=bf;}
355 if(MICROPET_TEST>5) printf(" f := %g\n", f);
356
357 /* Copy data to float pixel values */
358 mptr=mdata; fptr=data;
359 switch(data_type) {
360 case 1: // unsigned char
361 for(long long i=0; i<pxlNr; i++, mptr++, fptr++) *fptr=f*(float)(*mptr);
362 break;
363 case 2: // short int
364 case 6:
365 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
366 sptr=(short int*)mptr; *fptr=f*(float)(*sptr);
367 }
368 break;
369 case 3: // int
370 case 7:
371 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
372 iptr=(int*)mptr; *fptr=f*(float)(*iptr);
373 }
374 break;
375 case 4: // float
376 case 5:
377 memcpy(fptr, mptr, pxlNr*data_bytes);
378 for(long long i=0; i<pxlNr; i++, fptr++) *fptr*=f;
379 break;
380 default:
381 if(MICROPET_TEST>5)
382 printf("unsupported data_type := %d\n", data_type);
383 free(mdata); return(5);
384 }
385
386 free(mdata);
387 if(MICROPET_TEST>1) printf("%s() succeeded\n", __func__);
388 return(0);
389}

Referenced by imgReadMicropetFrame().

◆ upetScanStart()

int upetScanStart ( FILE * fp,
time_t * scant )
extern

Read scan start time from Concorde/MicroPET header.

Returns
Returns 0 when successful.
Parameters
fpFile pointer to Concorde/MicroPET header
scantPointer to time_t where time and date will be saved

Definition at line 194 of file micropet.c.

199 {
200 char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
201 int n, i;
202#pragma clang diagnostic push
203#pragma clang diagnostic ignored "-Wmissing-field-initializers"
204 struct tm scanstart={0};
205#pragma clang diagnostic pop
206
207 if(fp==NULL || scant==NULL) return 1;
208
209 rewind(fp);
210 if(upetHeaderReadParameter(fp, "scan_time", tmp)!=0) return 2;
211 n=sscanf(tmp, "%s %s %d %d:%d:%d %d", tmp2, tmp3, &scanstart.tm_mday,
212 &scanstart.tm_hour, &scanstart.tm_min, &scanstart.tm_sec, &i);
213 if(n==7) {
214 scanstart.tm_year=i-1900;
215 if(strcasecmp(tmp3, "Jan")==0) scanstart.tm_mon=0;
216 else if(strcasecmp(tmp3, "Feb")==0) scanstart.tm_mon=1;
217 else if(strcasecmp(tmp3, "Mar")==0) scanstart.tm_mon=2;
218 else if(strcasecmp(tmp3, "Apr")==0) scanstart.tm_mon=3;
219 else if(strcasecmp(tmp3, "May")==0) scanstart.tm_mon=4;
220 else if(strcasecmp(tmp3, "Jun")==0) scanstart.tm_mon=5;
221 else if(strcasecmp(tmp3, "Jul")==0) scanstart.tm_mon=6;
222 else if(strcasecmp(tmp3, "Aug")==0) scanstart.tm_mon=7;
223 else if(strcasecmp(tmp3, "Sep")==0) scanstart.tm_mon=8;
224 else if(strcasecmp(tmp3, "Oct")==0) scanstart.tm_mon=9;
225 else if(strcasecmp(tmp3, "Nov")==0) scanstart.tm_mon=10;
226 else if(strcasecmp(tmp3, "Dec")==0) scanstart.tm_mon=11;
227 scanstart.tm_isdst=-1;
228 //*scant=mktime(&scanstart); if(*scant<0) return 4;
229 *scant=timegm(&scanstart); if(*scant<0) return 4;
230 } else return 5;
231
232 return 0;
233}

Referenced by imgGetMicropetSIF(), imgMicropetCTToEcat7(), and imgMicropetPETToEcat7().

◆ vol2img()

int vol2img ( VOL * vol,
IMG * img,
int frame )
extern

Copy 3D volume as one time frame (1..dimt) into 4D image. Img must be allocated.

Parameters
volvolume structure
imgimage structure
frameframe number [1..number of frames]
Returns
0 if ok, 1 invalid image status, 2 invalid input, 3 image<->volume (x,y) dimensions do not match, 4 image<->volume planes do not match.

Definition at line 351 of file vol.c.

351 {
352 unsigned short int zi, yi, xi, fi;
353
354 if(VOL_TEST) printf("vol2img(vol, img, %d)\n", frame);
355 /* Check input */
356 if(vol==NULL || vol->status!=IMG_STATUS_OCCUPIED) return(1);
358 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
359 if(frame<1 || img->dimt<frame) return(2);
360 if(img->dimx!=vol->dimx || img->dimy!=vol->dimy) return(3);
361 if(img->dimz!=vol->dimz) return(4);
362
363 /* Copy data */
364 fi=frame-1;
365 for(zi=0; zi<vol->dimz; zi++)
366 for(yi=0; yi<vol->dimy; yi++)
367 for(xi=0; xi<vol->dimx; xi++)
368 img->m[zi][yi][xi][fi]=vol->v[zi][yi][xi];
369
370 return(0);
371}

◆ volAllocate()

int volAllocate ( VOL * vol,
int planes,
int rows,
int columns )
extern

Allocate memory for 3D image volume. Returns 0 if ok.

Parameters
volvolume structure
planesnumber of planes [>=1]
rowsnumber of rows [>=1]
columnsnumber of columns [>=1]
Returns
0 if ok, 1 invalid image status, 2 invalid input, 5 failed to allocate memory for planes, 6 failed to allocate memory for rows, 8 failed to allocate memory for rows

Definition at line 139 of file vol.c.

139 {
140 unsigned short int zi, ri;
141 int vxlNr, vi;
142 float **rptr, *cptr;
143
144 if(VOL_TEST) printf("voiAllocate(*vol, %d, %d, %d)\n", planes, rows, columns);
145 /* Check arguments */
146 if(vol==NULL) return(1); else vol->statmsg=_volStatusMessage[1];
147 if(vol->status==IMG_STATUS_UNINITIALIZED) return(1);
148 if(planes<1 || rows<1 || columns<1) return(2);
149 vxlNr=planes*rows*columns;
150
151 /* Check if correct volume size is already allocated */
152 if(vol->status>=IMG_STATUS_OCCUPIED) {
153 if(planes==vol->dimz && rows==vol->dimy && columns==vol->dimx) {
154 for(vi=0; vi<vxlNr; vi++) vol->_vxl[vi]=0;
155 return(0); /* that's it */
156 } else {
157 volEmpty(vol);
158 }
159 }
160 /* Allocate memory for volume data */
161 vol->_pln=(float***)malloc((size_t)planes*sizeof(float**));
162 if(vol->_pln==NULL) {
163 return(5);}
164 vol->_row=(float**)malloc((size_t)planes*rows*sizeof(float*));
165 if(vol->_row==NULL) {
166 free(vol->_pln); return(6);}
167 vol->_col=vol->_vxl=(float*)calloc((size_t)planes*rows*columns, sizeof(float));
168 if(vol->_vxl==NULL) {
169 free(vol->_pln); free(vol->_row); return(8);
170 }
171 /* Set data pointers */
172 rptr=vol->_row; cptr=vol->_col;
173 for(zi=0; zi<planes; zi++) {
174 vol->_pln[zi]=rptr;
175 for(ri=0; ri<rows; ri++) {
176 *rptr++=cptr; cptr+=columns;
177 }
178 }
179 vol->v=vol->_pln;
180 vol->plane=vol->_pln;
181 vol->column=vol->_col;
182 vol->row=vol->_row;
183 vol->voxel=vol->_vxl;
184 /* Ok */
185 vol->dimz=planes; vol->dimy=rows; vol->dimx=columns;
188 return(0);
189}
float * column
float ** row
float *** plane
float * voxel
void volEmpty(VOL *vol)
Definition vol.c:74

Referenced by img2vol().

◆ volAvg()

int volAvg ( VOL * vol,
VOL_RANGE * r,
float * avg )
extern

Calculates average voxel value inside specified volume range.

Returns
0 if ok, 1 invalid image status, 2 inconsistent range ending, 3 inconsistent range dimensions, 4 inconsistent dimensions
Parameters
volPointer to VOL image structure
rPointer to volume range inside VOL; enter NULL if whole VOL is used
avgTarget for mean value

Definition at line 562 of file vol.c.

569 {
570 int zi, yi, xi, n=0;
571
572 if(vol==NULL || vol->status!=IMG_STATUS_OCCUPIED) return(1);
573 if(r!=NULL) {
574 if(r->z1<1 || r->y1<1 || r->x1<1) return(2);
575 if(r->z2<r->z1 || r->y2<r->y1 || r->x2<r->x1) return(3);
576 if(r->z2>vol->dimz || r->y2>vol->dimy || r->x2>vol->dimx) return(4);
577 }
578
579 *avg=0.0;
580 if(r!=NULL) {
581 for(zi=r->z1-1; zi<r->z2; zi++) {
582 for(yi=r->y1-1; yi<r->y2; yi++) {
583 for(xi=r->x1-1; xi<r->x2; xi++) {
584 *avg+=vol->v[zi][yi][xi]; n++;
585 }
586 }
587 }
588 } else {
589 for(zi=0; zi<vol->dimz; zi++) {
590 for(yi=0; yi<vol->dimy; yi++) {
591 for(xi=0; xi<vol->dimx; xi++) {
592 *avg+=vol->v[zi][yi][xi]; n++;
593 }
594 }
595 }
596 }
597 if(n>0) *avg/=(float)n;
598 return(0);
599}

◆ volContents()

void volContents ( VOL * vol,
VOL_RANGE r,
FILE * fp )
extern

Prints matrix values inside specified range to file pointer.

Parameters
volvolume structure
rvolume range structure
fptarget file pointer

Definition at line 464 of file vol.c.

464 {
465 int zi, yi, xi;
466
467 if(vol==NULL || vol->status!=IMG_STATUS_OCCUPIED) return;
468 if(r.z1<1 || r.y1<1 || r.x1<1) return;
469 if(r.z2<r.z1 || r.y2<r.y1 || r.x2<r.x1) return;
470 if(r.z2>vol->dimz || r.y2>vol->dimy || r.x2>vol->dimx) return;
471
472 for(zi=r.z1-1; zi<r.z2; zi++) {
473 fprintf(fp, "pl=%03d ", zi+1);
474 for(xi=r.x1-1; xi<r.x2; xi++) fprintf(fp, " x=%05d", xi+1);
475 fprintf(fp, "\n");
476 for(yi=r.y1-1; yi<r.y2; yi++) {
477 fprintf(fp, "y=%05d", yi+1);
478 for(xi=r.x1-1; xi<r.x2; xi++)
479 fprintf(fp, " %7.3f", vol->v[zi][yi][xi]);
480 fprintf(fp, "\n");
481 }
482 }
483}

◆ volEmpty()

void volEmpty ( VOL * vol)
extern

Free memory allocated for volume.

Parameters
volvolume structure

Definition at line 74 of file vol.c.

74 {
75 if(VOL_TEST) printf("volEmpty()\n");
76 if(vol==NULL || vol->status<IMG_STATUS_OCCUPIED) return;
77 /* Free up memory */
78 if(vol->_vxl!=NULL) free(vol->_vxl);
79 //if(vol->_col!=NULL) free(vol->_col); Same as _vxl
80 if(vol->_row!=NULL) free(vol->_row);
81 if(vol->_pln!=NULL) free(vol->_pln);
82 /* Set variables */
84 vol->orientation=0;
85 vol->dimx=vol->dimy=vol->dimz=0;
86 vol->sizex=vol->sizey=vol->sizez=0;
87 vol->v=(float***)NULL;
88 vol->voxel=(float*)NULL;
89 vol->column=(float*)NULL;
90 vol->row=(float**)NULL;
91 vol->plane=(float***)NULL;
92 /* Set status */
94}

Referenced by volAllocate().

◆ volInfo()

void volInfo ( VOL * vol,
FILE * fp )
extern

Prints volume information to specified file pointer, e.g. stdout

Parameters
volvolume structure
fptarget file pointer

Definition at line 415 of file vol.c.

415 {
416 if(VOL_TEST) printf("volInfo()\n");
417 if(vol==NULL || vol->status<=IMG_STATUS_UNINITIALIZED) {
418 fprintf(fp, "Volume data is not initialized.\n"); return;}
420 fprintf(fp, "Volume data is initialized but empty.\n"); return;}
421 if(vol->status==IMG_STATUS_ERROR) fprintf(stdout, "Volume data has errors.\n");
422 fprintf(fp, "Volume status: %s\n", vol->statmsg);
423 fprintf(fp, "Patient orientation: %d\n", vol->orientation);
424 fprintf(fp, "Voxel sizes (x, y, z): %g %g %g mm\n",
425 vol->sizex, vol->sizey, vol->sizez);
426 fprintf(fp, "Dimensions (x, y, z): %d %d %d\n",
427 vol->dimx, vol->dimy, vol->dimz);
428 return;
429}

◆ volInit()

void volInit ( VOL * vol)
extern

Initiate volume before any use of VOL data; this should be called once.

Parameters
volpointer to volume structure

Definition at line 26 of file vol.c.

26 {
27 if(VOL_TEST) printf("volInit()\n");
28 if(vol==NULL) return;
29 memset(vol, 0, sizeof(VOL));
32 vol->orientation=0;
33 vol->dimx=vol->dimy=vol->dimz=0;
34 vol->sizex=vol->sizey=vol->sizez=0;
35 vol->v=(float***)NULL;
36 vol->voxel=(float*)NULL;
37 vol->column=(float*)NULL;
38 vol->row=(float**)NULL;
39 vol->plane=(float***)NULL;
40}

◆ volMax()

int volMax ( VOL * vol,
VOL_RANGE * r,
VOL_PIXEL * maxp,
float * maxv,
VOL_PIXEL * minp,
float * minv )
extern

Finds max and/or min voxel inside specified volume range.

Returns
0 if ok, 1 invalid volume status, 2 invalid range endings, 3 inconsistent range dimensions, 4 inconsistent dimensions
Parameters
volPointer to VOL image structure
rPointer to volume range inside VOL; enter NULL if whole VOL is used
maxpPixel where max pixel position is written; NULL if not needed
maxvTarget for max value; NULL if not needed
minpPixel where min pixel position is written; NULL if not needed
minvTarget for min value; NULL if not needed

Definition at line 492 of file vol.c.

505 {
506 int zi, yi, xi;
507 float lmax, lmin;
508
509 if(vol==NULL || vol->status!=IMG_STATUS_OCCUPIED) return(1);
510
511 if(r!=NULL) {
512 if(r->z1<1 || r->y1<1 || r->x1<1) return(2);
513 if(r->z2<r->z1 || r->y2<r->y1 || r->x2<r->x1) return(3);
514 if(r->z2>vol->dimz || r->y2>vol->dimy || r->x2>vol->dimx) return(4);
515
516 zi=r->z1-1; yi=r->y1-1; xi=r->x1-1; lmax=lmin=vol->v[zi][yi][xi];
517 if(maxp!=NULL) {maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1;}
518 if(minp!=NULL) {minp->z=zi+1; minp->y=yi+1; minp->x=xi+1;}
519 for(zi=r->z1-1; zi<r->z2; zi++) {
520 for(yi=r->y1-1; yi<r->y2; yi++) {
521 for(xi=r->x1-1; xi<r->x2; xi++) {
522 if(lmax<vol->v[zi][yi][xi]) {
523 lmax=vol->v[zi][yi][xi];
524 if(maxp!=NULL) {maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1;}
525 } else if(lmin>vol->v[zi][yi][xi]) {
526 lmin=vol->v[zi][yi][xi];
527 if(minp!=NULL) {minp->z=zi+1; minp->y=yi+1; minp->x=xi+1;}
528 }
529 }
530 }
531 }
532 } else {
533 zi=yi=xi=0; lmax=lmin=vol->v[zi][yi][xi];
534 if(maxp!=NULL) {maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1;}
535 if(minp!=NULL) {minp->z=zi+1; minp->y=yi+1; minp->x=xi+1;}
536 for(zi=0; zi<vol->dimz; zi++) {
537 for(yi=0; yi<vol->dimy; yi++) {
538 for(xi=0; xi<vol->dimx; xi++) {
539 if(lmax<vol->v[zi][yi][xi]) {
540 lmax=vol->v[zi][yi][xi];
541 if(maxp!=NULL) {maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1;}
542 } else if(lmin>vol->v[zi][yi][xi]) {
543 lmin=vol->v[zi][yi][xi];
544 if(minp!=NULL) {minp->z=zi+1; minp->y=yi+1; minp->x=xi+1;}
545 }
546 }
547 }
548 }
549 }
550 if(maxv!=NULL) *maxv=lmax;
551 if(minv!=NULL) *minv=lmin;
552 return(0);
553}

◆ vrd2vol()

int vrd2vol ( VOL_RANGE * r,
VOL * vol,
float in,
float out,
char * status )
extern

Set volume voxel values based on volume range definition.

Returns
Returns 0 if successful.
See also
vrdRead, vrdVxlNr, volAllocate, vol2img
Parameters
rImage volume range.
volPre-allocated image volume data structure.
inValue to write into voxels inside the given volume range; enter nanf("") to not change the values.
outValue to write into voxels outside the given volume range; enter nanf("") to not change the values.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed

Definition at line 681 of file vol.c.

695 {
696 if(vol==NULL || vol->status!=IMG_STATUS_OCCUPIED) {
697 if(status!=NULL) strcpy(status, "invalid VOL struct");
698 return(1);
699 }
700 if(r->z2<r->z1 || r->y2<r->y1 || r->x2<r->x1) vrdReorder(r);
701 if(r->z1<1 || r->y1<1 || r->x1<1 ||
702 r->z2>vol->dimz || r->y2>vol->dimy || r->x2>vol->dimx)
703 {
704 if(status!=NULL) strcpy(status, "invalid volume range");
705 return(2);
706 }
707 if(isnan(in) && isnan(out)) {
708 if(status!=NULL) strcpy(status, "new values not given");
709 return(0);
710 }
711 int zi, yi, xi;
712
713 if(!isnan(in)) {
714 for(zi=r->z1-1; zi<r->z2; zi++)
715 for(yi=r->y1-1; yi<r->y2; yi++)
716 for(xi=r->x1-1; xi<r->x2; xi++)
717 vol->v[zi][yi][xi]=in;
718 }
719
720 if(!isnan(out)) {
721 for(zi=1; zi<=vol->dimz; zi++)
722 for(yi=1; yi<=vol->dimy; yi++)
723 for(xi=1; xi<=vol->dimx; xi++) {
724 if(zi>=r->z1 && zi<=r->z2 &&
725 yi>=r->y1 && yi<=r->y2 &&
726 xi>=r->x1 && xi<=r->x2)
727 continue;
728 vol->v[zi-1][yi-1][xi-1]=out;
729 }
730 }
731
732 if(status!=NULL) strcpy(status, "ok");
733 return(0);
734}
int vrdReorder(VOL_RANGE *vol_range)
Definition vol.c:607

◆ vrdRead()

int vrdRead ( char * vrdfile,
VOL_RANGE * vol_range,
char * status )
extern

Read Volume Range Definition File.

Returns
Returns 0 if successful.
See also
vrdReorder, vrdVxlNr, irdRead
Parameters
vrdfileVolume Range Definition File filename, which contains image volume corners (x y z) in IFT format: corner1 = x y z corner2 = x y z
vol_rangeImage volume range
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed

Definition at line 742 of file vol.c.

751 {
752 int ret, ii, x, y, z;
753 IFT ift;
754 char key[256];
755
756 /* Check that input is ok */
757 if(vrdfile==NULL || strlen(vrdfile)<1 || vol_range==NULL) {
758 if(status!=NULL) strcpy(status, "program error");
759 return 1;
760 }
761 /* Read VDF as IFT file */
762 iftInit(&ift); ret=iftRead(&ift, vrdfile, 1, 0); if(ret) {
763 if(status!=NULL) strcpy(status, ift.status);
764 iftEmpty(&ift); return 2;
765 }
766 /* Try to find keys 'corner1' and 'corner2' */
767 strcpy(key, "corner1"); ii=iftGet(&ift, key, 0);
768 if(ii>=0) {
769 ret=string_to_xyz(ift.item[ii].value, &x, &y, &z);
770 if(ret==0) {
771 vol_range->x1=x; vol_range->y1=y; vol_range->z1=z;
772 strcpy(key, "corner2"); ii=iftGet(&ift, key, 0);
773 if(ii>=0) {
774 ret=string_to_xyz(ift.item[ii].value, &x, &y, &z);
775 vol_range->x2=x; vol_range->y2=y; vol_range->z2=z;
776 if(ret==0) {
777 vrdReorder(vol_range);
778 if(status!=NULL) strcpy(status, "ok");
779 iftEmpty(&ift); return 0;
780 }
781 }
782 }
783 }
784 /* We are here only if keys were not found */
785 /* Lets not care about keys at all */
786 for(ii=0, ret=0; ii<ift.keyNr; ii++) {
787 if(ret==0 && string_to_xyz(ift.item[ii].value, &x, &y, &z)==0)
788 {
789 vol_range->x1=x; vol_range->y1=y; vol_range->z1=z;
790 ret++; continue;
791 }
792 if(ret==1 && string_to_xyz(ift.item[ii].value, &x, &y, &z)==0)
793 {
794 vol_range->x2=x; vol_range->y2=y; vol_range->z2=z;
795 ret++; break;
796 }
797 }
798 if(ret<2) {
799 if(status!=NULL) strcpy(status, "volume definitions not found");
800 iftEmpty(&ift); return 2;
801 }
802
803 vrdReorder(vol_range);
804 if(status!=NULL) strcpy(status, "ok");
805 iftEmpty(&ift);
806 return 0;
807}
int string_to_xyz(char *str, int *x, int *y, int *z)
Definition vol.c:653

◆ vrdReorder()

int vrdReorder ( VOL_RANGE * vol_range)
extern

Reorder Volume Range Definition.

Returns
Returns 0 if successful.
See also
vrdRead, vrdVxlNr, irdRead
Parameters
vol_rangeImage volume range; start and end range are set in correct order

Definition at line 607 of file vol.c.

610 {
611 int i;
612
613 /* Check that input is ok */
614 if(vol_range==NULL) return 1;
615 /* Change the order if necessary */
616 if(vol_range->x1<0 || vol_range->x2<0) return 2;
617 if(vol_range->x2<vol_range->x1) {
618 i=vol_range->x1; vol_range->x1=vol_range->x2; vol_range->x2=i;}
619 if(vol_range->y1<0 || vol_range->y2<0) return 3;
620 if(vol_range->y2<vol_range->y1) {
621 i=vol_range->y1; vol_range->y1=vol_range->y2; vol_range->y2=i;}
622 if(vol_range->z1<0 || vol_range->z2<0) return 4;
623 if(vol_range->z2<vol_range->z1) {
624 i=vol_range->z1; vol_range->z1=vol_range->z2; vol_range->z2=i;}
625 return 0;
626}

Referenced by vrd2vol(), and vrdRead().

◆ vrdVxlNr()

int vrdVxlNr ( VOL_RANGE * vol_range)
extern

Get the number of voxels in Volume Range Definition.

Returns
Returns the nr of voxels in the volume range.
See also
vrdReorder, vrdRead
Parameters
vol_rangeImage volume range; start and end range must be in correct order

Definition at line 634 of file vol.c.

637 {
638 int x, y, z;
639
640 if(vol_range==NULL) return(0);
641 z=1+vol_range->z2-vol_range->z1;
642 x=1+vol_range->x2-vol_range->x1;
643 y=1+vol_range->y2-vol_range->y1;
644 return(z*x*y);
645}

Variable Documentation

◆ ANALYZE_TEST

int ANALYZE_TEST
extern

Verbose prints from Analyze functions

Definition at line 8 of file analyze.c.

Referenced by anaDatabaseExists(), anaExistsNew(), anaFlipping(), anaReadHeader(), anaReadImagedata(), anaRemove(), and anaWriteHeader().

◆ ECAT63_TEST

◆ ecat63errmsg

◆ ECAT7_TEST

◆ ecat7errmsg

◆ IMG_TEST

◆ MICROPET_TEST

int MICROPET_TEST
extern

Verbose prints from microPET functions

Definition at line 6 of file micropet.c.

Referenced by imgGetMicropetHeader(), upetHeaderReadParameter(), upetIsHeader(), and upetReadImagedata().

◆ SIF_TEST

int SIF_TEST
extern

Verbose prints from SIF functions

Definition at line 6 of file sif.c.

Referenced by sifEmpty(), sifInit(), sifModerateTrues(), sifModerateWeights(), sifRead(), sifSetmem(), sifWeight(), sifWeightByFrames(), sifWeightNorm(), and sifWrite().

◆ siferrmsg

char siferrmsg[128]
extern

Error message from SIF functions

Definition at line 7 of file sif.c.

Referenced by imgReadModelingData(), sifRead(), sifSetmem(), and sifWrite().

◆ VOL_TEST

int VOL_TEST
extern

Verbose prints from Vol functions

Definition at line 6 of file vol.c.

Referenced by img2svol(), img2vol(), svol2img(), svolAllocate(), svolEmpty(), svolInfo(), svolInit(), vol2img(), volAllocate(), volEmpty(), volInfo(), and volInit().