static struct FSAState *AddState(LPXMLDTDVALIDATOR p) { struct FSAState **s2, *s = XMLPool_Alloc(p->StatePool); CHKMEM(s); s->mark = 0; s->trans = NULL; s2 = XMLVector_Append(p->fsa, NULL); CHKMEM(s2); *s2 = s; return s; }
static struct FSATran *AddTran(struct FSAState *src, struct FSAState *dst, void *label) { struct FSATran *t; if (!src->trans) { XMLVector_Create(&src->trans, 4, sizeof(struct FSATran)); CHKMEM(src->trans); } t = XMLVector_Append(src->trans, NULL); CHKMEM(t); t->label = label; t->src = src; t->dst = dst; return t; }
void event_mplexer_test() { dx_event_mplexer_create(); dx_event_mplexer_destroy(); CHKMEM(); }
static struct FSAState *RecurSeqCreateNFA(LPXMLDTDVALIDATOR vp, XMLCP *cp, struct FSAState *next) { /* ugly recursive solution to traverse singly linked list backwards :( BUT consider: for example docbook longest seq is 8 items - using prev pointer would take about 60kB...*/ struct FSAState *s = (cp->next) ? RecurSeqCreateNFA(vp, cp->next, next) : next; CHKMEM(s); return CreateNFA(vp, cp, s); }
void file_avi_test(char* path, dx_movie_context_t* movie) { dx_movie_context_t* context; int i, index; context = dx_movie_context_create("assets/drop.avi"); // context = dx_movie_context_create("/home/in/1.avi"); ASSERT("AVI파일 Parsing에 실패했습니다.", context != NULL); CONSOLE("\nPath : %.128s\n", context->path); CONSOLE("\nFrame Rate : %d\n", context->framerate); CONSOLE("Total Frames : %d\n", context->total_frame); CONSOLE("Play Time : %d\n", context->playtime); CONSOLE("Track Count : %d\n", context->track_count); CONSOLE("Frame Offset : %ld\n", context->frame_offset); CONSOLE("Index Offset : %ld\n", context->index_offset); CONSOLE("Width : %d\n", context->width); CONSOLE("Height : %d\n", context->height); for (i = 0; i < context->track_count; i++) { dx_movie_track_info_t* info = context->track_info + i; CONSOLE(" Track %.4s : type - %.4s, Handler - %.4s, Rate : %d\n", info->id, info->type, info->handler, info->framerate); } index = dx_avi_seek_frame(context, context->total_frame - 1, SEEK_SET); ASSERT("프레임 갯수 -1 인덱스는 EOF가 아니어야 한다.", dx_movie_frame_eof(context) == 0) CONSOLE("Found Index %d\n", index); index = dx_avi_seek_frame(context, context->total_frame, SEEK_SET); ASSERT("프레임 갯수번째 인덱스는 EOF이다.", dx_movie_frame_eof(context) != 0) index = dx_avi_seek_frame(context, 0, SEEK_END); ASSERT("현재 프레그먼트의 인덱스는 전체 프레그먼트의 갯수와 같아야 한다.", context->current_frame->fragment_no = context->total_fragment) index = dx_avi_seek_frame(context, 0, SEEK_SET); ASSERT("현재 프레그먼트의 인덱스는 1 이어야 한다.", context->current_frame->fragment_no = 1) index = dx_avi_seek_frame(context, context->total_frame + 1, SEEK_SET); ASSERT("마지막 프레임보다 큰 인덱스는 프레임 전체 갯수와 같아야 한다.", index == context->total_frame) ASSERT("현재 프레그먼트의 인덱스는 전체 프레그먼트의 갯수와 같아야 한다.", context->current_frame->fragment_no = context->total_fragment) dx_movie_context_destroy(context); CHKMEM(); }
void util_clock_test() { int i = 0; LONGLONG t_start = 0; LONGLONG t_end = 0; dx_clock_get_abs_msec(&t_start); t_start = htonll(t_start); t_start = ntohll(t_start); while(i++ < 100000) { dx_clock_get_abs_msec(&t_end); t_end = htonll(t_end); t_end = ntohll(t_end); } CONSOLE("Elapsed time for getting clock 100,000 time : %lld milli-seconds\n", t_end - t_start); CHKMEM(); }
static struct FSAState *CreateNFA2(LPXMLDTDVALIDATOR vp, XMLCP *cp, struct FSAState *next) { struct FSAState *ns; CHKMEM(ns = AddState(vp)); if (cp->type == XMLCTYPE_NAME) { CHKMEM(AddTran(ns, next, cp)); } else { struct FSAState *s; if (cp->type == XMLCTYPE_SEQ) { CHKMEM(s = RecurSeqCreateNFA(vp, cp->children, next)); CHKMEM(AddTran(ns, s, (void*)epsilon)); } else { for(cp = cp->children; cp; cp = cp->next) { CHKMEM(s = CreateNFA(vp, cp, next)); CHKMEM(AddTran(ns, s, (void*)epsilon)); } } } return ns; }
/* ----------------------------- MNI Header ----------------------------------- @NAME : read_3Dvff_file_image @INPUT : hvol minc volume handle filename (vff filename) m2 minc2 variables (struct) vattrs vff attributes to be added to minc2.0 range (data min and max range) @OUTPUT : (nothing) @RETURNS : @DESCRIPTION: Function to read the 3D vff file image @METHOD : @GLOBALS : @CALLS : @CREATED : Jan 2007 (Leila Baghdadi) @MODIFIED : ---------------------------------------------------------------------------- */ void read_3Dvff_file_image(mihandle_t hvol, char *filename, struct mnc_vars m2, struct vff_attrs vattrs, double range[2]) { FILE *fp ; int i,counts,r; void *buffer; int number_of_bits = vattrs.bits/8; unsigned long start[MAX_VFF_DIMS]; /* MINC data starts */ unsigned long count[MAX_VFF_DIMS]; double valid_range[2]; range[0] = DBL_MAX; range[1] = -DBL_MAX; start[1] = 0; start[2] = 0; count[1] = m2.mnc_count[1]; count[2] = m2.mnc_count[0]; counts = m2.mnc_count[0]*m2.mnc_count[1]; /* open file */ fp = fopen(filename , "rb" ); if( fp == NULL ) { exit(EXIT_FAILURE); /* bad open? */ } // Set file position indicator to beginning of image r = fseek(fp,-counts * m2.mnc_count[2] * number_of_bits,SEEK_END); if ( r != 0) { printf(" fseek is reporting a problem!!\n"); exit(EXIT_FAILURE); } // allocate memory for one slice only buffer = malloc( counts * number_of_bits); CHKMEM(buffer); for (i = 0; i < m2.mnc_count[2]; i++) { // set start to the current slice start[0] = i; count[0] = 1; // read data one slice at a time r = fread(buffer,sizeof(char),counts * number_of_bits,fp); if ( r == 0) { printf(" fread is reporting a problem leila.\n"); exit(EXIT_FAILURE); } if (G.little_endian && vattrs.bits==16) { swab(buffer, buffer, counts * number_of_bits); } // write the slice r = miset_voxel_value_hyperslab(hvol, m2.mnc_type, start, count, buffer); if (r != 0) { TESTRPT("can not write data with hperslab function",r); exit(EXIT_FAILURE); } //calculate min and max of slice computeScalarRange(m2.mnc_type,valid_range,counts,buffer); if (valid_range[0] < range[0]) { range[0] = valid_range[0]; } if (valid_range[1] > range[1]) { range[1] = valid_range[1]; } } free(buffer); fclose(fp); }
int main(int argc, char *argv[]) { int r; const char **file_list = NULL; /* List of file names */ struct vff_attrs vffattrs; struct mnc_vars mnc2; char out_str[1024]; /* Big string for filename */ midimhandle_t hdim[MAX_VFF_DIMS]; mihandle_t hvol; double mnc_vrange[2]; /* MINC valid min/max */ int num_file_args; /* Number of files on command line */ string_t out_dir; /* Output directory */ int length; struct stat st; int ifile; int num_files; /* Total number of files */ int is_file=0; int is_list=0; int ival; char *extension; mnc2.mnc_srange[0]= -1; mnc2.mnc_srange[1]= -1; G.pname = argv[0]; /* get program name */ G.dirname = NULL; G.little_endian = 1; /*default is little endian unless otherwise*/ G.minc_history = time_stamp(argc, argv); /* Create minc history string */ if (ParseArgv(&argc, argv, argTable, 0) || argc < 2) { usage(); exit(EXIT_FAILURE); } if (G.dirname != NULL) { #if HAVE_DIRENT_H if (stat(G.dirname, &st) != 0 || !S_ISDIR(st.st_mode)) { fprintf(stderr,"Option -addattrs requires directory as argument!!!\n"); exit(EXIT_FAILURE); } #endif } if (G.List) { num_file_args = argc - 1; } else { strcpy(out_str, argv[1]); extension = strrchr(out_str, '.'); if (extension != NULL ) { extension++; if (strcmp(extension, "mnc") !=0) { usage(); exit(EXIT_FAILURE); } } if (argc == 3) { /* check if last argument is dir */ num_file_args = argc - 2; strcpy(out_dir, argv[argc - 1]); /* make sure path ends with slash */ length = strlen(out_dir); if (out_dir[length - 1] != '/') { out_dir[length++] = '/'; out_dir[length++] = '\0'; } if (stat(out_dir, &st) != 0 || !S_ISDIR(st.st_mode)) {/* assume filename */ is_file =1; } } else { //list of 2d files must check! num_file_args = argc - 2; is_list = 1; } } if (!is_file || G.List) { /* Get space for file lists */ /* Allocate the array of pointers used to implement the * list of filenames. */ file_list = malloc(1 * sizeof(char *)); CHKMEM(file_list); /* Go through the list of files, expanding directories where they * are encountered... */ num_files = 0; for (ifile = 1 ; ifile <= num_file_args; ifile++) { #if HAVE_DIRENT_H if (stat(argv[ifile + 1], &st) == 0 && S_ISDIR(st.st_mode)) { DIR *dp; struct dirent *np; char *tmp_str; length = strlen(argv[ifile + 1]); dp = opendir(argv[ifile + 1]); if (dp != NULL) { while ((np = readdir(dp)) != NULL) { /* Generate the full path to the file. */ tmp_str = malloc(length + strlen(np->d_name) + 2); strcpy(tmp_str, argv[ifile + 1]); if (tmp_str[length-1] != '/') { tmp_str[length] = '/'; tmp_str[length+1] = '\0'; } strcat(&tmp_str[length], np->d_name); if (stat(tmp_str, &st) == 0 && S_ISREG(st.st_mode)) { file_list = realloc(file_list, (num_files + 1) * sizeof(char *)); file_list[num_files++] = tmp_str; } else { free(tmp_str); } } closedir(dp); } else { fprintf(stderr, "Error opening directory '%s'\n", argv[ifile + 1]); } } else { file_list = realloc(file_list, (num_files + 1) * sizeof(char *)); file_list[num_files++] = strdup(argv[ifile + 1]); } #else file_list = realloc(file_list, (num_files + 1) * sizeof(char *)); file_list[num_files++] = strdup(argv[ifile + 1]); #endif } } if (G.List) { exit(EXIT_SUCCESS); } if (is_file) { read_3Dvff_file_header(argv[2],&mnc2,&vffattrs); } else { read_2Dvff_files_header(file_list,num_files,&mnc2,&vffattrs); } /* ok starting to create minc2.0 file assuming 3D must take care of 2D*/ r = micreate_dimension("zspace", MI_DIMCLASS_SPATIAL, MI_DIMATTR_REGULARLY_SAMPLED, mnc2.mnc_count[2], &hdim[0]); if (r != 0) { TESTRPT("failed create_dimension zspace", r); return (1); } r = micreate_dimension("yspace", MI_DIMCLASS_SPATIAL, MI_DIMATTR_REGULARLY_SAMPLED, mnc2.mnc_count[1], &hdim[1]); if (r != 0) { TESTRPT("failed create_dimension yspace", r); return (1); } r = micreate_dimension("xspace", MI_DIMCLASS_SPATIAL, MI_DIMATTR_REGULARLY_SAMPLED, mnc2.mnc_count[0], &hdim[2]); if (r != 0) { TESTRPT("failed create_dimension xspace", r); return (1); } r = miset_dimension_start(hdim[0], mnc2.mnc_starts[2]); if (r < 0) { TESTRPT("failed dimension start xspace", r); return (1); } r = miset_dimension_start(hdim[1], mnc2.mnc_starts[1]); if (r < 0) { TESTRPT("failed dimension start yspace", r); return (1); } /* create negative start for xspace to correct orientation */ r = miset_dimension_start(hdim[2], mnc2.mnc_starts[0] * -1); if (r < 0) { TESTRPT("failed dimension start zspace", r); return (1); } /* create negative spacing for zspace to correct orientation */ r = miset_dimension_separation(hdim[0], mnc2.mnc_steps[2] * -1); if (r < 0) { TESTRPT("failed dimension separation xspace", r); return (1); } /* create negative spacing for yspace to correct orientation */ r = miset_dimension_separation(hdim[1], mnc2.mnc_steps[1] * -1); if (r < 0) { TESTRPT("failed dimension separation yspace", r); return (1); } r = miset_dimension_separation(hdim[2], mnc2.mnc_steps[0]); if (r < 0) { TESTRPT("failed dimension separation zspace", r); return (1); } r = micreate_volume(out_str,MAX_VFF_DIMS, hdim, mnc2.mnc_type, MI_CLASS_REAL, NULL, &hvol); if (r != 0) { TESTRPT("error creating volume", r); return (1); } r = micreate_volume_image(hvol); if (r != 0) { TESTRPT("error creating volume", r); return (1); } // read image slice by slice if (is_file) { read_3Dvff_file_image(hvol, argv[2], mnc2, vffattrs, mnc_vrange); } else { read_2Dvff_files_image(hvol,file_list,num_files, mnc2, vffattrs, mnc_vrange); } miset_volume_valid_range(hvol,mnc_vrange[1], mnc_vrange[0]); if (mnc2.mnc_srange[0] == -1 || mnc2.mnc_srange[1] == -1) { /* min and max are not specified in the file voxel range is set same as real range */ mnc2.mnc_srange[0] = mnc_vrange[0]; mnc2.mnc_srange[1] = mnc_vrange[1]; } miset_volume_range(hvol,mnc2.mnc_srange[1], mnc2.mnc_srange[0]); if (is_file) { /* create minc history 3D */ strcat(vffattrs.cmd_line,G.minc_history); G.minc_history = vffattrs.cmd_line; /* attributes from vff file itself 3D case*/ add_vff_attribute_to_file(hvol,&vffattrs); } if (G.dirname != NULL) { /* attributes from external files 3D case*/ add_attributes_from_files(hvol); } else if (!is_file) { /* just afew attributes from 2D case */ ival = vffattrs.year; r = miset_attr_values(hvol, MI_TYPE_INT, "study", MIstart_year,1 , &ival); if (r < 0) { TESTRPT("failed to add date:year attribute", r); } ival = vffattrs.month; r = miset_attr_values(hvol, MI_TYPE_INT, "study", MIstart_month,1 , &ival); if (r < 0) { TESTRPT("failed to add date:month attribute", r); } ival = vffattrs.day; r = miset_attr_values(hvol, MI_TYPE_INT, "study", MIstart_day,1 , &ival); if (r < 0) { TESTRPT("failed to add date:day attribute", r); } } /* add history attribute */ r = miadd_history_attr(hvol,strlen(G.minc_history), G.minc_history); if (r < 0) { TESTRPT("error creating history", r); return (1); } if (file_list != NULL) { free_list(num_files, file_list); free(file_list); } miclose_volume(hvol); exit(EXIT_SUCCESS); }
/* ----------------------------- MNI Header ----------------------------------- @NAME : add_attributes_from_files @INPUT : hvol volume handle @OUTPUT : (nothing) @RETURNS : @DESCRIPTION: adds a few files generated with vff file to minc file @METHOD : This method assumes the txt files are in the top directory @GLOBALS : @CALLS : @CREATED : Jul 2006 (Leila Baghdadi) @MODIFIED : This code is a bit ugly thanks for the wodnerful work of windows. ---------------------------------------------------------------------------- */ int add_attributes_from_files(mihandle_t hvol) { FILE *inf; char *strbuf; char *buffer; string_t fullpath_pro; string_t fullpath_des; string_t fullpath_par; char *p; int r,i; char **str; int found_protocol=0; int found_description=0; int found_parameters=0; /* first find files names --> different platforms */ find_filenames_first(fullpath_pro,fullpath_des,fullpath_par, &found_protocol,&found_description, &found_parameters); if (!found_protocol) { printf("could not find file with extension protocol\n"); } else { /* add *.protocol to "acquisition" protocol attribute */ inf = fopen(fullpath_pro,"r"); if (inf == NULL) { printf("Could not open file %s \n", fullpath_pro); exit(EXIT_FAILURE); } else { strbuf = malloc(MAX_BUF_LINE + 1); CHKMEM(strbuf); strbuf[0]='\0'; buffer = malloc(MAX_BUF_TEXT + 1); CHKMEM(buffer); buffer[0]='\0'; while (fgets(strbuf, MAX_BUF_LINE, inf) != NULL) { strcat(buffer,strbuf); } } fclose(inf); r = miset_attr_values(hvol, MI_TYPE_STRING, "acquisition", "protocol", strlen(buffer) ,buffer); free(buffer); free(strbuf); if (r < 0) { TESTRPT("failed to add protocol attribute", r); } } if (!found_description) { printf("Could not find file Description.txt\n"); } else { /* add Description.txt to patient name and study id */ inf = fopen(fullpath_des,"r"); if (inf == NULL) { printf("Could not open file %s \n", fullpath_des); exit(EXIT_FAILURE); } else { /* just need the first two lines of this file */ str = malloc(MAX_DESCRIPTION); CHKMEM(str); for (i=0; i < MAX_DESCRIPTION; i++) { str[i] = malloc(MAX_BUF_LINE + 1); CHKMEM(str[i]); if(fgets(str[i], MAX_BUF_LINE, inf) == NULL){ fprintf(stderr, "Error with fgets on line %d of %s\n", __LINE__, __FILE__); } for (p = str[i]; *p != '\0'; p++) { if (*p == '\r') { *p = '\0'; } } } r = miset_attr_values(hvol, MI_TYPE_STRING, "patient", "full_name",strlen(str[0]) , str[0]); if (r < 0) { TESTRPT("failed to add full_name attribute", r); } r = miset_attr_values(hvol, MI_TYPE_STRING, "study", "study_id",strlen(str[1]) , str[1]); if (r < 0) { TESTRPT("failed to add study_id attribute", r); } fclose(inf); for (i=0; i < MAX_DESCRIPTION; i++) { free(str[i]); } free(str); } } if (!found_parameters) { printf("Could not find file Parameters.txt\n"); } else { /* add Parameters.txt to "acquisition" scan_parameters */ inf = fopen(fullpath_par,"r"); if (inf == NULL) { printf("Could not open file %s \n", fullpath_par); exit(EXIT_FAILURE); } else { strbuf = malloc(MAX_BUF_LINE + 1); CHKMEM(strbuf); strbuf[0]='\0'; buffer = malloc(MAX_BUF_TEXT + 1); CHKMEM(buffer); buffer[0]='\0'; while (fgets(strbuf, MAX_BUF_LINE, inf) != NULL) { strcat(buffer,strbuf); } } fclose(inf); r = miset_attr_values(hvol, MI_TYPE_STRING, "acquisition", "scan_parameters",strlen(buffer) ,buffer); free(buffer); free(strbuf); if (r < 0) { TESTRPT("failed to add scan_parameters attribute", r); } } return(0); }
static struct FSAState *CreateNFA(LPXMLDTDVALIDATOR vp, XMLCP *cp, struct FSAState *next) { struct FSAState *sp, *n1, *n2; switch(cp->rep) { case 0: return CreateNFA2(vp, cp, next); case '*': CHKMEM(n1 = AddState(vp)); CHKMEM(sp = CreateNFA2(vp, cp, n1)); CHKMEM(AddTran(n1, sp, (void*)epsilon)); CHKMEM(AddTran(n1, next, (void*)epsilon)); return n1; case '+': CHKMEM(n1 = AddState(vp)); CHKMEM(n2 = AddState(vp)); CHKMEM(sp = CreateNFA2(vp, cp, n2)); CHKMEM(AddTran(n1, sp, (void*)epsilon)); CHKMEM(AddTran(n2, sp, (void*)epsilon)); CHKMEM(AddTran(n2, next, (void*)epsilon)); return n1; case '?': CHKMEM(n1 = AddState(vp)); CHKMEM(sp = CreateNFA2(vp, cp, next)); CHKMEM(AddTran(n1, sp, (void*)epsilon)); CHKMEM(AddTran(n1, next, (void*)epsilon)); return n1; } return NULL; }
static int use_the_files(int num_files, Data_Object_Info *di_ptr[], const char *out_dir) { int ifile; int acq_num_files; const char **acq_file_list; int *used_file; int *acq_file_index; double cur_study_id; int cur_acq_id; int cur_rec_num; int cur_image_type; int cur_echo_number; int cur_dyn_scan_number; string_t cur_patient_name; string_t cur_patient_id; string_t cur_sequence_name; int exit_status; const char *output_file_name; string_t file_prefix; string_t string; FILE *fp; int trust_location; int trust_coord; int user_opts; /* Options as set by user. We may override.. */ if (out_dir != NULL) { /* if an output directory name has been * provided on the command line */ if (G.Debug) { printf("Using directory '%s'\n", out_dir); } strcpy(file_prefix, out_dir); } else { file_prefix[0] = '\0'; } if (G.Debug) { /* debugging */ printf("file_prefix: [%s]\n", file_prefix); } /* Allocate space for acquisition file list. */ acq_file_list = malloc(num_files * sizeof(*acq_file_list)); CHKMEM(acq_file_list); acq_file_index = malloc(num_files * sizeof(*acq_file_index)); CHKMEM(acq_file_index); used_file = malloc(num_files * sizeof(*used_file)); CHKMEM(used_file); for (ifile = 0; ifile < num_files; ifile++) { used_file[ifile] = FALSE; } for (;;) { /* Loop through files, looking for an acquisition * * file groups should already have been sorted into acquisitions * in calling program * * this code is in a `forever' loop because we loop over multiple * acquisitions until all of the files are used up. */ acq_num_files = 0; for (ifile = 0; ifile < num_files; ifile++) { /* If already marked used (can this happen???), we've already * written the file to an output somewhere. */ if (used_file[ifile]) { continue; } if (acq_num_files == 0) { /* found first file: set all current attributes like * study id, acq id, rec num(?), image type, echo * number, dyn scan number, flag for multiple echoes, * flag for multiple time points the flag input file * as `used' */ cur_study_id = di_ptr[ifile]->study_id; cur_acq_id = di_ptr[ifile]->acq_id; cur_rec_num = di_ptr[ifile]->rec_num; cur_image_type = di_ptr[ifile]->image_type; cur_echo_number = di_ptr[ifile]->echo_number; cur_dyn_scan_number = di_ptr[ifile]->dyn_scan_number; strcpy(cur_patient_name, di_ptr[ifile]->patient_name); strcpy(cur_patient_id, di_ptr[ifile]->patient_id); strcpy(cur_sequence_name, di_ptr[ifile]->sequence_name); used_file[ifile] = TRUE; } /* otherwise check if attributes of the new input file match those * of the current output context and flag input file as `used' */ else if ((di_ptr[ifile]->study_id == cur_study_id) && (di_ptr[ifile]->acq_id == cur_acq_id) && (di_ptr[ifile]->rec_num == cur_rec_num) && (di_ptr[ifile]->image_type == cur_image_type) && (di_ptr[ifile]->echo_number == cur_echo_number || !G.splitEcho) && (di_ptr[ifile]->dyn_scan_number == cur_dyn_scan_number || !G.splitDynScan) && !strcmp(cur_patient_name, di_ptr[ifile]->patient_name) && !strcmp(cur_patient_id, di_ptr[ifile]->patient_id)) { used_file[ifile] = TRUE; } if (used_file[ifile]) { /* if input file is flagged as `used', then add its index to the list of files for this acquisition (and increment counter) */ acq_file_list[acq_num_files] = di_ptr[ifile]->file_name; acq_file_index[acq_num_files] = ifile; acq_num_files++; } } /* If no files were added to this acquisition, it implies that * all files have been processed. */ if (acq_num_files == 0) { break; /* All done!!! */ } /* Use the files for this acquisition */ /* Print out the file names if we are debugging. */ if (G.Debug || G.List) { printf("\nSeries %4d %20s %20s (%4d files):\n", cur_acq_id, cur_patient_name, di_ptr[acq_file_index[0]]->protocol_name, acq_num_files); for (ifile = 0; ifile < acq_num_files; ifile++) { printf(" %s\n", di_ptr[acq_file_index[ifile]]->file_name); } if (G.List) { continue; } } /* Do some sanity checks on the acquisition. In particular, we * verify that the coordinate and/or slice location information * looks reliable. */ trust_location = 1; trust_coord = 1; for (ifile = 0; ifile < acq_num_files; ifile++) { int jfile; int ix = acq_file_index[ifile]; if (!di_ptr[ix]->coord_found) { trust_coord = 0; } for (jfile = ifile + 1; jfile < acq_num_files; jfile++) { int jx = acq_file_index[jfile]; if (NEARLY_EQUAL(di_ptr[ix]->slice_location, di_ptr[jx]->slice_location)) { trust_location = 0; } } } /* We also check whether the acquisition number (0x0020, 0x0012) * and image number (0x0020, 0x0013) are informative or not. * They are sometimes absent, constant, or otherwise strange. * Determining this ahead of time helps us make good decisions * about how to treat these fields later. */ G.max_acq_num = INT_MIN; G.min_acq_num = INT_MAX; G.max_img_num = INT_MIN; G.min_img_num = INT_MAX; for (ifile = 0; ifile < acq_num_files; ifile++) { int ix = acq_file_index[ifile]; if (di_ptr[ix]->dyn_scan_number < G.min_acq_num) { G.min_acq_num = di_ptr[ix]->dyn_scan_number; } if (di_ptr[ix]->dyn_scan_number > G.max_acq_num) { G.max_acq_num = di_ptr[ix]->dyn_scan_number; } if (di_ptr[ix]->global_image_number < G.min_img_num) { G.min_img_num = di_ptr[ix]->global_image_number; } if (di_ptr[ix]->global_image_number > G.max_img_num) { G.max_img_num = di_ptr[ix]->global_image_number; } } user_opts = G.opts; if (!trust_coord) { printf("WARNING: Image coordinates absent or incomplete.\n"); if (!trust_location) { printf("WARNING: Slice location is untrustworthy.\n"); G.opts |= OPTS_NO_LOCATION; } } if (G.min_acq_num == G.max_acq_num) { printf("WARNING: Acquisition number is not informative.\n"); } else { int ix = acq_file_index[0]; if (G.max_acq_num == di_ptr[ix]->num_dyn_scans) { /* Acquisition number is per scan (e.g. time). */ printf("WARNING: Acquisition number is per scan.\n"); } else if (G.max_acq_num == di_ptr[ix]->num_slices_nominal * di_ptr[ix]->num_dyn_scans) { printf("WARNING: Acquisition number is global.\n"); } else { printf("WARNING: Acquisition number is a mystery.\n"); } } if (G.min_img_num == G.max_img_num) { /* Acquisition number is uninformative. */ printf("WARNING: Image number is not informative.\n"); } else { int ix = acq_file_index[0]; if (G.max_img_num == di_ptr[ix]->num_slices_nominal) { printf("WARNING: Image number is per slice.\n"); } else if (G.max_img_num == di_ptr[ix]->num_slices_nominal * di_ptr[ix]->num_dyn_scans) { printf("WARNING: Image number is global.\n"); } else { printf("WARNING: Image number is a mystery.\n"); } } if (G.min_acq_num < 0 || G.min_acq_num > 1) { printf("WARNING: Minimum acquisition number is %d\n", G.min_acq_num); } if (G.min_img_num < 0 || G.min_img_num > 1) { printf("WARNING: Minimum image number is %d\n", G.min_img_num); } printf("INFO: Acquisition number ranges from %d to %d\n", G.min_acq_num, G.max_acq_num); printf("INFO: Image number ranges from %d to %d\n", G.min_img_num, G.max_img_num); /* Create minc file */ exit_status = dicom_to_minc(acq_num_files, acq_file_list, NULL, G.clobber, file_prefix, &output_file_name); G.opts = user_opts; if (exit_status != EXIT_SUCCESS) continue; /* Print log message */ if (G.Debug) { printf("Created minc file %s.\n", output_file_name); } #if HAVE_POPEN /* Invoke a command on the file (if requested) and get the * returned file name */ if (G.command_line != NULL && *G.command_line != '\0') { sprintf(string, "%s %s", G.command_line, output_file_name); printf("-Applying command '%s' to output file... ", G.command_line); fflush(stdout); if ((fp = popen(string, "r")) != NULL) { char pipe_output_name[256]; fscanf(fp, "%s", pipe_output_name); if (pclose(fp) != EXIT_SUCCESS) { fprintf(stderr, "Error executing command\n \"%s\"\n", string); } else if (G.Debug) { printf("Executed command \"%s\",\nproducing file %s.\n", string, pipe_output_name); } } else { fprintf(stderr, "Error executing command \"%s\"\n", string); } printf("Done.\n"); } #endif /* HAVE_POPEN */ } /* Free acquisition file list */ free(acq_file_list); free(acq_file_index); free(used_file); return exit_status; }
int main(int argc, char *argv[]) { int ifile; Acr_Group group_list; char **file_list; /* List of file names */ Data_Object_Info **file_info_list; int num_file_args; /* Number of files on command line */ int num_files; /* Total number of files */ string_t out_dir; /* Output directory */ string_t message; /* Generic message */ int num_files_ok; /* Actual number of DICOM/IMA files */ struct stat st; int length; int exit_status; G.mosaic_seq = MOSAIC_SEQ_UNKNOWN; /* Assume ascending by default. */ G.splitDynScan = FALSE; /* Don't split dynamic scans by default */ G.splitEcho = TRUE; /* Do split by echo by default */ G.use_stdin = FALSE; /* Do not read file list from stdin */ G.filename_format = NULL; G.dirname_format = NULL; G.minc_history = time_stamp(argc, argv); /* Create minc history string */ G.prefer_coords = FALSE; G.abort_on_error = FALSE; G.pname = argv[0]; /* get program name */ /* Get the input parameters and file names. */ if (ParseArgv(&argc, argv, argTable, 0)) { usage(); } if (argc < 2) { usage(); } if (G.List) { num_file_args = argc - 1; /* Assume no directory given. */ } else { num_file_args = argc - 2; /* Assume last arg is directory. */ strcpy(out_dir, argv[argc - 1]); /* make sure path ends with slash */ length = strlen(out_dir); if (out_dir[length - 1] != '/') { out_dir[length++] = '/'; out_dir[length++] = '\0'; } if (stat(out_dir, &st) != 0 || !S_ISDIR(st.st_mode)) { fprintf(stderr, "The final argument, '%s', is not a directory\n", out_dir); exit(EXIT_FAILURE); } } /* Get space for file lists */ /* Allocate the array of pointers used to implement the * list of filenames. */ file_list = malloc(1 * sizeof(char *)); CHKMEM(file_list); /* Go through the list of files, expanding directories where they * are encountered... */ num_files = 0; for (ifile = 0 ; ifile < num_file_args; ifile++) { #if HAVE_DIRENT_H if (stat(argv[ifile + 1], &st) == 0 && S_ISDIR(st.st_mode)) { DIR *dp; struct dirent *np; char *tmp_str; if (G.Debug) { printf("Expanding directory '%s'\n", argv[ifile + 1]); } length = strlen(argv[ifile + 1]); dp = opendir(argv[ifile + 1]); if (dp != NULL) { while ((np = readdir(dp)) != NULL) { /* Generate the full path to the file. */ tmp_str = malloc(length + strlen(np->d_name) + 2); strcpy(tmp_str, argv[ifile + 1]); if (tmp_str[length-1] != '/') { tmp_str[length] = '/'; tmp_str[length+1] = '\0'; } strcat(&tmp_str[length], np->d_name); if (stat(tmp_str, &st) == 0 && S_ISREG(st.st_mode)) { file_list = realloc(file_list, (num_files + 1) * sizeof(char *)); file_list[num_files++] = tmp_str; } else { free(tmp_str); } } closedir(dp); } else { fprintf(stderr, "Error opening directory '%s'\n", argv[ifile + 1]); } } else { file_list = realloc(file_list, (num_files + 1) * sizeof(char *)); file_list[num_files++] = strdup(argv[ifile + 1]); } #else file_list = realloc(file_list, (num_files + 1) * sizeof(char *)); file_list[num_files++] = strdup(argv[ifile + 1]); #endif } if (G.use_stdin) { char linebuf[1024]; char *p; while (fgets(linebuf, sizeof(linebuf), stdin) != NULL) { /* Strip off newline at end of string. */ for (p = linebuf; *p != '\0'; p++) { if (*p == '\n') { *p = '\0'; } } if (strlen(linebuf) != 0) { file_list = realloc(file_list, (num_files + 1) * sizeof(char *)); file_list[num_files++] = strdup(linebuf); } } } file_info_list = malloc(num_files * sizeof(*file_info_list)); CHKMEM(file_info_list); /* figure out what kind of files we have - * supported types are: * * IMA (Siemens .ima format - Numaris 3.5) * N4DCM (Siemens DICOM - Numaris 4) * * if not all same type, return an error * * we start by assuming N4DCM with no offset - we find that the * file is IMA or has an offset (the 128 byte + DICM offset seen * on Syngo CD's and exports) then the appropriate flag will be * set. */ printf("Checking file types...\n"); if (check_file_type_consistency(num_files, file_list) < 0) { exit(EXIT_FAILURE); } /* Now loop over all files, getting basic info on each */ num_files_ok = 0; for (ifile = 0; ifile < num_files; ifile++) { char *cur_fname_ptr = file_list[ifile]; if (!G.Debug) { sprintf(message, "Parsing %d files", num_files); progress(ifile, num_files, message); } if (G.file_type == IMA) { group_list = siemens_to_dicom(cur_fname_ptr, ACR_IMAGE_GID - 1); } else { /* read up to but not including pixel data */ group_list = read_numa4_dicom(cur_fname_ptr, ACR_IMAGE_GID - 1); } if (group_list == NULL) { /* This file appears to be invalid - it is probably a dicomdir * file or some other stray junk in the directory. */ printf("Skipping file %s, which is not in the expected format.\n", cur_fname_ptr); free(cur_fname_ptr); } else { /* Copy it back to the (possibly earlier) position in the real * file list. */ file_list[num_files_ok] = cur_fname_ptr; /* allocate space for the current entry to file_info_list */ file_info_list[num_files_ok] = malloc(sizeof(*file_info_list[0])); CHKMEM(file_info_list[num_files_ok]); file_info_list[num_files_ok]->file_index = num_files_ok; parse_dicom_groups(group_list, file_info_list[num_files_ok]); /* put the file name into the info list */ file_info_list[num_files_ok]->file_name = strdup(file_list[num_files_ok]); /* Delete the group list now that we're done with it */ acr_delete_group_list(group_list); num_files_ok++; } } /* end of loop over files to get basic info */ if (G.Debug) { printf("Using %d files\n", num_files_ok); } num_files = num_files_ok; printf("Sorting %d files... ", num_files); /* sort the files into series based on acquisition number */ qsort(file_info_list, num_files, sizeof(file_info_list[0]), dcm_sort_function); /* If DEBUG, print a list of all files. */ if (G.Debug) { printf("\n"); for (ifile = 0; ifile < num_files; ifile++) { Data_Object_Info *info = file_info_list[ifile]; char *fname; if ((ifile % 16) == 0) { printf("%-4s %-32.32s %-14s %-8s %-8s %-4s %-4s %-4s %-4s %-4s %-4s %-4s %-4s %-4s %-5s %-16s\n", "num", "filename", "studyid", "serialno", "acq", "nec", "iec", "ndy", "idy", "nsl", "isl", "acol", "rcol", "mrow", "img#", "seq"); } /* Print out info about file. Truncate the name if necessary. */ fname = info->file_name; if (strlen(fname) > 32) { fname += strlen(fname) - 32; } printf("%4d %-32.32s %14.6f %8d %8d %4d %4d %4d %4d %4d %4d %4d %4d %4d %5d %-16s\n", ifile, fname, info->study_id, info->scanner_serialno, info->acq_id, info->num_echoes, info->echo_number, info->num_dyn_scans, info->dyn_scan_number, info->num_slices_nominal, info->slice_number, info->acq_cols, info->rec_cols, info->num_mosaic_rows, info->global_image_number, info->sequence_name); } } printf("Done sorting files.\n"); /* Loop over files, processing by acquisition */ if (G.List) { printf("Listing files by series...\n"); } else { printf("Processing files, one series at a time...\n"); } exit_status = use_the_files(num_files, file_info_list, out_dir); if (G.List) { printf("Done listing files.\n"); } else { printf("Done processing files.\n"); } free_list(num_files, file_list, file_info_list); free(file_list); free(file_info_list); exit(exit_status); }