medcon - MedCon C project for conversion of medical images
Local MedCon C library ( libmdc.a )
#include "medcon.h"
-----------------------------------------------------------------------
Important Global Variables
-----------------------------------------------------------------------
char prefix[MDC_MAX_PREFIX+1]; /* prefix for new filenames */
/* command-line input data */
char *mdc_arg_files[]; /* pointers to input files */
int mdc_arg_convs[]; /* conversions selected */
int mdc_arg_total[]; /* total files & conversions*/
/* options set at command-line */
Int8 MDC_INFO; /* print image info */
Int8 MDC_INTERACTIVE; /* interactive read */
Int8 MDC_CONVERT; /* do conversion */
Int8 MDC_EXTRACT; /* extract images */
Int8 MDC_PIXELS; /* print pixel values */
Int8 MDC_SKIP_PREVIEW; /* skip first preview image*/
Int8 MDC_DICOM_MOSAIC; /* support mosaic files */
Int8 MDC_TRUE_GAP; /* spacing true gap/overlap */
Int8 MDC_DEBUG; /* show debug info */
Int8 MDC_ANLZ_REV; /* analyze reverse images */
Int8 MDC_ANLZ_SPM; /* analyze for SPM */
Int8 MDC_GIF_OPTIONS; /* define gif options */
Int8 MDC_COLOR_MAP; /* gray colormap selected */
Int8 MDC_MAKE_GRAY; /* remap color to gray */
Int8 MDC_DITHER_COLOR; /* dither color reduction */
Int8 MDC_FORCE_INT; /* force writing BIT?_? pixs*/
Int8 MDC_NEGATIVE; /* preserve negative pixels */
Int8 MDC_QUANTIFY; /* preserve quantification */
Int8 MDC_CALIBRATE; /* preserve calibration */
Int8 MDC_VERBOSE; /* verbose mode */
Int8 MDC_NORM_OVER_FRAMES /* normalize over frames */
/* 'QUANTIFY' & 'CALIBRATE' may NOT be ON at the same time! */
-----------------------------------------------------------------------
Important Defines
-----------------------------------------------------------------------
/* representation of supported formats */
#define MDC_FRMT_NONE 0 /* unsupported format */
#define MDC_FRMT_RAW 1 /* Read Interactive */
/* Write RAW Binary */
#define MDC_FRMT_ASCII 2 /* Write RAW Ascii */
#define MDC_FRMT_GIF 3 /* GIF89a or GIF87a */
#define MDC_FRMT_ACR 4 /* Acr/Nema 2.0 (Papyrus) */
#define MDC_FRMT_INW 5 /* INW (RUG) */
#define MDC_FRMT_ECAT6 6 /* Siemens/CTI ECAT 6.4 */
#define MDC_FRMT_ECAT7 7 /* Siemens/CTI ECAT 7.2 */
#define MDC_FRMT_INTF 8 /* Interfile v3.3 */
#define MDC_FRMT_ANLZ 9 /* Analyze */
#define MDC_FRMT_DICM 10 /* DICOM 3.0 */
#define MDC_FRMT_PNG 11 /* PNG */
#define MDC_FRMT_CONC 12 /* Concorde uPet */
#define MDC_MAX_FMTS 13 /* total + 1 */
/* supported color maps */
#define MDC_MAP_PRESENT 0 /* 256 RGB colormap */
#define MDC_MAP_GRAY 1 /* grayscale colormap */
#define MDC_MAP_INVERTED 2 /* inverted colormap */
#define MDC_MAP_RAINBOW 3 /* rainbow colormap */
#define MDC_MAP_COMBINED 4 /* combined colormap */
#define MDC_MAP_HOTMETAL 5 /* hotmetal colormap */
#define MDC_MAP_LOADED 6 /* extern LUT loaded */
-----------------------------------------------------------------------
Important Definitions
-----------------------------------------------------------------------
typedef struct Gated_Data_t {
Int8 gspect_nesting; /* gated spect nesting */
float nr_projections; /* number of projections */
float extent_rotation; /* extent of rotation */
float study_duration; /* study duration (ms) */
float image_duration; /* image duration (ms) */
float time_per_proj; /* time per proj (ms) */
float window_low; /* lower limit (ms) */
float window_high; /* higher limit (ms) */
float cycles_observed; /* cardiac cycles observed */
float cycles_acquired; /* cardiac cycles acquired */
} GATED_DATA;
typedef struct Acquisition_Data_t {
Int16 rotation_direction; /* direction of rotation */
Int16 detector_motion; /* type detector motion */
float angle_start; /* start angle (interfile) */
float angle_step; /* angular step */
float scan_arc; /* angular range */
} ACQ_DATA;
typedef struct Dynamic_Data_t {
Uint32 nr_of_slices; /* images in time frame */
float time_frame_start; /* start time frame (ms) */
float time_frame_delay; /* delay this frame (ms) */
float time_frame_duration; /* duration frame (ms) */
float delay_slices; /* delay each slice (ms) */
} DYNAMIC_DATA;
typedef struct Bed_Data_t {
float hoffset; /* horizontal position (mm) */
float voffset; /* vertical position (mm) */
} BED_DATA;
typedef struct Static_Data_t {
char label[MDC_MAXSTR]; /* label name of image */
float total_counts; /* total counts in image */
float image_duration; /* duration of image (ms) */
Int16 start_time_hour; /* start time hour */
Int16 start_time_minute; /* start time minute */
Int16 start_time_second; /* start time second */
} STATIC_DATA;
typedef struct Image_Data_t {
/* ** general data ** */
Uint32 width,height; /* image dimension */
Int16 bits,type; /* bits/pixel & datatype */
Uint16 flags; /* extra flag */
double min, max; /* min/max pixelvalue */
double qmin, qmax; /* quantified min/max */
double fmin, fmax; /* min/max in whole frame */
double qfmin, qfmax; /* in whole frame (quant) */
float rescale_slope; /* rescale slope */ /* P */
float rescale_intercept; /* rescale intercept */ /* P */
Uint32 frame_number; /* part of frame (1-based) */ /* P */
float slice_start; /* start of slice (ms) */ /* P */
Uint8 *buf; /* pointer to raw image */
long load_location; /* load start in file */
/* ** internal items ** */
Int8 rescaled; /* rescaled YES or NO */
double rescaled_min; /* new rescaled max */
double rescaled_max; /* new rescaled min */
double rescaled_fctr; /* new rescale fctr */
double rescaled_slope; /* new rescaled slope */
double rescaled_intercept; /* new rescaled intercept */
/* ** ecat64 items ** */
Int16 quant_units; /* quantification units */
Int16 calibr_units; /* calibration units */
float quant_scale; /* quantification scale */
float calibr_fctr; /* calibration factor */
float intercept; /* scale intercept */
float pixel_xsize; /* pixel size X (mm) */
float pixel_ysize; /* pixel size Y (mm) */
float slice_width; /* slice width (mm) */
float recon_scale; /* recon magnification */
/* ** Acr/Nema items ** */
float image_pos_dev[3]; /* image pos. device (mm) */
float image_orient_dev[6]; /* image orient device (mm) */
float image_pos_pat[3]; /* image pos. patient (mm) */
float image_orient_dev[6]; /* image orient patient (mm) */
float slice_spacing; /* space btw centres (mm) */
float ct_zoom_fctr; /* CT image zoom factor */
/* ** Miscellaneous **
STATIC_DATA *sdata; /* extra static entries */
unsigned char *plugb; /* like to attach here? */
} IMG_DATA;
typedef struct File_Info_t {
FILE *ifp; /* pointer to input file */
FILE *ifp_raw; /* pointer to raw input file*/
FILE *ofp; /* pointer to output file */
FILE *ofp_raw; /* pointer to raw output file*/
char ipath[MAX_PATH]; /* path to input file */
char opath[MAX_PATH]; /* path to output file */
char *idir; /* dir to input file */
char *odir; /* dir to output file */
char *ifname; /* name of input file */
char *ofname; /* name of output file */
int iformat; /* format of input file */
int oformat; /* format of output file */
Int8 rawconv; /* FRMT_RAW | FRMT_ASCII */
Int8 endian; /* endian type of file */
Int8 compression; /* file compression */
Int8 truncated; /* truncated ? */
Int8 diff_type; /* images with diff type */
Int8 diff_size; /* images with diff size */
Int8 diff_scale; /* images with diff rescale? */
Uint32 number; /* total number of images */ /* P */
Uint32 mwidth, mheight; /* global max dimensions */
Uint16 bits, type; /* global bits & datatype */
Int16 dim[8]; /* [0] = # of dimensions */
/* [1] = X-dim (pixels) */
/* [2] = Y-dim (pixels) */
/* [3] = Z-dim (planes) */
/* [4] = (frames) */
/* [5] = (gates) */
/* [6] = (beds) */
/* ... */
/* values must be 1-based */
float pixdim[8]; /* [0] = # of dimensions */
/* [1] = X-dim (mm) */
/* [2] = Y-dim (mm) */
/* [3] = Z-dim (mm) */
/* [4] = time (ms) */
/* ... */
double glmin, glmax; /* global min/max value */
double qglmin, qglmax; /* quantified min/max */
Int8 contrast_remapped; /* contrast remap applied? */
float window_centre; /* contrast window centre */
float window_width; /* contrast window width */
Int8 slice_projection; /* projection of images */
Int8 pat_slice_orient /* combined flag */
char pat_pos[MDC_MAXSTR]; /* patient position */
char pat_orient[MDC_MAXSTR]; /* patient orientation */
char patient_sex[MDC_MAXSTR]; /* sex of patient */
char patient_name[MDC_MAXSTR]; /* name of patient */
char patient_id[MDC_MAXSTR]; /* id of patient */
char patient_dob[MDC_MAXSTR]; /* birth of patient YYYYMMDD */
float patient_weight; /* weight of patient (kg) */
char study_descr[MDC_MAXSTR]; /* study description */
char study_id[MDC_MAXSTR]; /* study id */
Int16 study_date_day; /* day of study */
Int16 study_date_month; /* month of study */
Int16 study_date_year; /* year of study */
Int16 study_time_hour; /* hour of study */
Int16 study_time_minute; /* minute of study */
Int16 study_time_second; /* second of study */
Int16 dose_time_hour; /* hour of dose start */
Int16 dose_time_minute; /* minute of dose start */
Int16 dose_time_second; /* second of dose start */
Int16 nr_series; /* number of series */
Int16 nr_acquisition; /* number of acquisition */
Int16 nr_instance; /* number of instance (image)*/
Int16 acquisition_type; /* acquisition type */
Int16 planar; /* planar of tomo ? */
Int16 decay_corrected; /* decay corrected ? */
Int16 flood_corrected; /* flood corrected ? */
Int16 reconstructed; /* reconstructed ? */
char recon_method[MDC_MAXSTR]; /* reconstruction method */
char institution[MDC_MAXSTR]; /* name of institution */
char manufacturer[MDC_MAXSTR]; /* name of manufacturer */
char series_descr[MDC_MAXSTR]; /* series description */
char radiopharma[MDC_MAXSTR]; /* radiopharmaceutical */
char filter_type[MDC_MAXSTR]; /* filter type */
char organ_code[MDC_MAXSTR]; /* organ */
char isotope_code[MDC_MAXSTR]; /* isotope */
float isotope_halflife; /* isotope halflife (sec) */
float injected_dose; /* amount injected (MBq) */
float gantry_tilt; /* gantry tilt */
Uint8 map; /* indexed 256 colormap */
Uint8 palette[768]; /* global palette */
char *comment; /* whatever comment */
Uint32 comm_length; /* length of comment */
Uint32 gatednr; /* number of gated entries */
GATED_DATA *gdata; /* array of GATED_DATA */
Uint32 acqnr; /* number acq. data entries */
ACQ_DATA *acqdata; /* array of ACQ_DATA entries */
Uint32 dynnr; /* number of time frames */
DYNAMIC_DATA *dyndata; /* array of DYNAMIC_DATA */
Uint32 bednr; /* number bed data entries */
BED_DATA *beddata; /* array of BED_DATA entries */
IMG_DATA *image; /* array of IMG_DATA images */
MOD_INFO *mod; /* modalities specific info */
unsigned char *pluga; /* want to attach stuff? */
} FILEINFO;
------------------------------------------------------------------------
Important Functions
------------------------------------------------------------------------
void MdcInit (void);
void MdcFinish (void);
int MdcHandleArgs ( FILEINFO *fi,int argc,char *argv[],int MAXFILES );
void MdcPrintUsage ( char *pgrname );
int MdcOpenFile ( FILEINFO *fi, char *path );
int MdcReadFile ( FILEINFO *fi, int filenr, char *(*ReadFile)(FILEINFO *fi) );
int MdcWriteFile ( FILEINFO *fi, int format, int prefixnr, char *(*WriteFile)(FILEINFO *fi) );
void MdcInitFI ( FILEINFO *fi, char *path );
void MdcFreeIDs ( FILEINFO *fi );
void MdcCleanUpFI ( FILEINFO *fi );
void MdcResetIDs ( FILEINFO *fi );
void MdcPrintFI ( FILEINFO *fi );
void MdcCloseFile ( FILEINFO *fi );
void MdcSplitPath ( char path[], char **dir, char **fname );
int MdcGetFrmt ( FILEINFO *fi );
void MdcGetColorMap ( int map, Uint8 palette[] );
char *MdcImagesPixelFiddle( FILEINFO *fi);
void MdcPrntMesg ( char *fmt, ... );
void MdcPrntWarn ( char *fmt, ... );
void MdcPrntErr ( int code, char *fmt, ... );
char *MdcReadGIF ( FILEINFO *fi );
char *MdcReadACR ( FILEINFO *fi );
char *MdcReadINW ( FILEINFO *fi );
char *MdcReadECAT6 ( FILEINFO *fi );
char *MdcReadECAT7 ( FILEINFO *fi );
char *MdcReadINTF ( FILEINFO *fi );
char *MdcReadANLZ ( FILEINFO *fi );
char *MdcReadRAW ( FILEINFO *fi );
char *MdcReadDICM ( FILEINFO *fi );
char *MdcReadPNG ( FILEINFO *fi );
char *MdcReadCONC ( FILEINFO *fi );
char *MdcReadNIFTI ( FILEINFO *fi );
char *MdcWriteRAW ( FILEINFO *fi );
char *MdcWriteGIF ( FILEINFO *fi );
char *MdcWriteACR ( FILEINFO *fi );
char *MdcWriteINW ( FILEINFO *fi );
char *MdcWriteECAT6 ( FILEINFO *fi );
char *MdcWriteINTF ( FILEINFO *fi );
char *MdcWriteANLZ ( FILEINFO *fi );
char *MdcWriteDICM ( FILEINFO *fi );
char *MdcWritePNG ( FILEINFO *fi );
char *MdcWriteCONC ( FILEINFO *fi );
char *MdcWriteNIFTI ( FILEINFO *fi );
The MedCon library is intended for easy use of read/write routines for
the various medical image formats. Our main test format is Ecat 6.4. The
FILEINFO structure holds all the interesting data and pointers to the images.
A fast introduction ...
- MdcInit(), MdcFinish()
- The very first and very last function to call when using this library.
Currently changes occur to the signal handler for floating point
exceptions and the program's locale.
- MdcHandleArgs()
- Parser for the command-line arguments. Last function argument determines
the maximum of input files allowed. The absolute maximum is MDC_MAX_FILES
defined in the library.
- MdcPrintUsage()
- Prints possible MedCon command-line options and terminates the
program.
- MdcOpenFile()
- Initializes FILEINFO struct and opens the file with or without
decompression.
- MdcReadFile()
- Reads the (decompressed) file with format autodetection or by trying a
fallback format, initializes a (grayscale) colormap and does the obligated
pixel handling. The last argument enables the use of an external read
function.
- MdcWriteFile()
- Writes a file in the supplied format. Last argument is a number used in
the prefix of the output filename. Give a negative value when a personal
prefix was prepared. The last argument enables the use of an external
write function.
- MdcCloseFile()
- Closes the file and sets the pointer to NULL.
- MdcInitFI()
- Initializes the FILEINFO structure.
- MdcFreeIDs()
- Cleans the IMG_DATA structures by freeing all allocated memory.
- MdcCleanUpFI()
- Cleans the FILEINFO structure. The routine makes use of FreeIDs().
- MdcResetIDs()
- Resets the IMG_DATA structures. This is necessary after each
conversion.
- MdcPrintFI()
- Prints the content of the FILEINFO structure. Useful for debug
purposes.
- MdcSplitPath()
- Splits the path in a string pointer to directory and filename.
- MdcGetFrmt()
- Checks the format of the file. For the return value, see the
representation of the supported formats under the section `Important
Defines'. With the INTERACTIVE variable ON, the function returns F_RAW;
see also ReadRaw().
- MdcGetColorMap()
- Fills a 256 byte RGB palette with the requested grayscale colormap.
- MdcImagesPixelFiddle()
- Performs all the pixel by pixel processes such as swapping bytes, make
positive values, quantification, rescaling, filling the FILEINFO structure
with global & image variables and check some important parameters.
This function is required after a file was read!
- MdcPrntMesg()
- Prints a message. Argument is a variable parameter list.
- MdcPrntWarn()
- Prints a warning. Argument is a variable parameter list.
- MdcPrntErr()
- Prints an error and quits the program. The first argument is the error
code.
- MdcReadRAW() - MdcWriteRAW()
- Reads files of an unknown format interactively and writes raw image arrays
with out headers. ReadInterActive() is an alias for MdcReadRAW().
- MdcReadGIF() - MdcWriteGIF()
- Reads GIF87a & GIF89a, writes annimated GIF89a files.
- MdcReadACR() - MdcWriteACR()
- Reads and writes Acr/Nema files.
- MdcReadINW() - MdcWriteINW()
- Reads and writes RUG INW files.
- MdcReadECAT6(), MdcReadECAT7() - MdcWriteECAT6()
- Reads ECAT 6 (resp. 7). Writes ECAT 6.4 files.
- MdcReadINTF() - MdcWriteINTF()
- Reads and writes Interfile 3.3 files.
- MdcReadANLZ() - MdcWriteANLZ()
- Reads and writes Analyze (SPM) files.
- MdcReadDICM() - MdcWriteDICM()
- Reads DICOM files. Writes DICOM files.
- MdcReadPNG() - MdcWritePNG()
- Reads PNG files. Writes PNG files.
- MdcReadCONC() - MdcWriteCONC()
- Reads and writes Concorde microPET.
- MdcReadNIFTI() - MdcWriteNIFTI()
- Reads and writes NIH's NIfTI files.
A sample C-source code to show the usage of the functions. Please, look into the
project source code for more details.
-----------------------------------------------------------------------
/* filename: testit.c */
#include <stdio.h>
#include "medcon.h"
#undef VERSION /* prevent any conflict */
#define VERSION "TestIt v2.3"
void NewPrefix(int n)
{
sprintf(prefix,"my%02d-",n); /* max of 5 chars */
}
int main(int argc, char *argv[])
{
FILEINFO fi;
int *total = mdc_arg_total; /* total arguments of files & conversions */
int *convs = mdc_arg_convs; /* counter for each conversion format */
char **files = mdc_arg_files; /* array of pointers to input filenames */
int f, c; /* some counters */
int t=0; /* counter for the output name prefix */
int convert, err=MDC_OK; /* some variables */
/* check arguments */
if (argc < 2) {
printf("%s - %s\n",VERSION,MdcGetLibLongVersion());
MdcPrintUsage(argv[0]);
}
/* init library */
MdcInit();
/* handle arguments, last one determines max inputfiles */
if (MdcHandleArgs(&fi,argc,argv,MDC_MAX_FILES) != MDC_OK)
MdcPrintUsage(argv[0]);
/* check output/conversion formats */
if (total[MDC_CONVS] == 0) {
printf("\n%s: ERROR : No output format specified\n\n",argv[0]);
return(MDC_BAD_CODE);
}
/* do the stuff for each input file */
for (f=0; f<total[MDC_FILES]; f++) {
if ((err = MdcOpenFile(&fi, files[f])) != MDC_OK) return(err);
if ((err = MdcReadFile(&fi, f+1, NULL)) != MDC_OK) return(err);
/* do the conversions */
if (total[MDC_CONVS] > 0) {
/* go through conversion formats */
for (c=1; c<MDC_MAX_FRMTS; c++) {
convert = convs[c];
/* write output format when selected */
while (convert -- > 0) {
if ((err = MdcWriteFile(&fi, c, t++, NULL)) != MDC_OK) {
MdcCleanUpFI(&fi);
return(err);
}
}
}
}
/* clean up FILEINFO struct */
MdcCleanUpFI(&fi);
}
/* finish library */
MdcFinish();
return(err);
}
-----------------------------------------------------------------------
Example `Makefile' for compiling `testit.c':
-----------------------------------------------------------------------
# filename: Makefile
CC = gcc
CCOPTS = -Wall -g
CFLAGS = $(CCOPTS)
INCS = `xmedcon-config --cflags`
LIBS = `xmedcon-config --libs`
testit: testit.c
$(CC) $(CFLAGS) $(INCS) -o testit testit.c $(LIBS)
# don't forget a <tab> before $(CC). You can lose this with copy/paste
-----------------------------------------------------------------------
/usr/local/xmedcon/include/ |
Directory with header files.. |
/usr/local/xmedcon/lib/ |
Directory with libraries. |
/usr/local/xmedcon/bin/ |
Directory with executables. |
/usr/local/xmedcon/man/ |
Directory with man-pages. |
/usr/local/xmedcon/etc/ |
Directory with rcfiles. |
medcon(1), xmedcon(1), xmedcon-config(1)
m-acr(4), m-anlz(4), m-gif(4), m-intf(4), m-ecat(4), m-inw(4)
(X)MedCon project was originally written by Erik Nolf (eNlf) for the
former PET-Centre at Ghent University (Belgium).
e-mail: |
enlf-at-users.sourceforge.net |
www: |
http://xmedcon.sourceforge.net |