/* ----------------------------- MNI Header ----------------------------------- @NAME : acr_output_group @INPUT : afp - acr file pointer group @OUTPUT : (none) @RETURNS : status @DESCRIPTION: Write out an acr-nema group @METHOD : @GLOBALS : @CALLS : @CREATED : November 10, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ Acr_Status acr_output_group(Acr_File *afp, Acr_Group group) { long ielement, nelements; Acr_Element cur, next; Acr_Status status; /* Update the length element */ update_group_length_element(group, acr_get_vr_encoding(afp)); /* Loop through the elements of the group, writing them out */ nelements = acr_get_group_nelements(group); next = acr_get_group_element_list(group); for (ielement=0; ielement < nelements && next != NULL; ielement++) { cur = next; next = cur->next; status = acr_output_element(afp, cur); if (status != ACR_OK) { return status; } } /* Check for a bogus group (the true number of elements is different from nelements) */ if ((ielement < nelements) || (next != NULL)) { status = ACR_OTHER_ERROR; return status; } return status; }
/* ----------------------------- MNI Header ----------------------------------- @NAME : acr_dump_group_list @INPUT : file_pointer - where output should go group_list @OUTPUT : (none) @RETURNS : (nothing) @DESCRIPTION: Dump information from an acr-nema group list @METHOD : @GLOBALS : @CALLS : @CREATED : November 24, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ void acr_dump_group_list(FILE *file_pointer, Acr_Group group_list) { Acr_Group cur_group; /* Check for empty list */ cur_group = group_list; if (cur_group == NULL) { (void) fprintf(file_pointer,"\nEmpty group list\n\n"); return; } /* Loop over groups */ while (cur_group != NULL) { /* Print the group id */ (void) fprintf(file_pointer, "\nGroup 0x%04x :\n\n", acr_get_group_group(cur_group)); /* Print the elements */ acr_dump_element_list(file_pointer, acr_get_group_element_list(cur_group)); /* Go to the next group */ cur_group = acr_get_group_next(cur_group); } /* Print a blank line after dump */ (void) fprintf(file_pointer, "\n"); /* Flush the buffer */ (void) fflush(file_pointer); return; }
/* ----------------------------- MNI Header ----------------------------------- @NAME : acr_find_group_element @INPUT : group_list elid @OUTPUT : (none) @RETURNS : element pointer @DESCRIPTION: Find an element in a group list @METHOD : @GLOBALS : @CALLS : @CREATED : November 10, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ Acr_Element acr_find_group_element(Acr_Group group_list, Acr_Element_Id elid) { Acr_Group group; /* Find the group */ group = acr_find_group(group_list, elid->group_id); /* If not found return NULL */ if (group == NULL) return NULL; /* Search through element list for element */ return acr_find_element_id(acr_get_group_element_list(group), elid); }
/* ----------------------------- MNI Header ----------------------------------- @NAME : acr_input_group_with_max @INPUT : afp - acr file pointer max_group_id - maximum group id to read in. If <= 0 then any group is read in. @OUTPUT : group @RETURNS : status @DESCRIPTION: Read in an acr-nema group with an optional maximum group id. If group id exceeds max, then *group is set to NULL. If an error occurs, then a group may still be returned. This routine will stop reading when it reaches a watchpoint. @METHOD : @GLOBALS : @CALLS : @CREATED : November 10, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ static Acr_Status acr_input_group_with_max(Acr_File *afp, Acr_Group *group, int max_group_id) { int group_id, element_id, next_group_id; long group_length; Acr_Status status; Acr_Element element; int have_length_element; int get_more_elements; Acr_VR_encoding_type vr_encoding; /* Initialize the group pointer */ *group = NULL; /* Look ahead at the next element */ status = acr_peek_at_next_element_id(afp, &group_id, &element_id); if (status != ACR_OK) return status; /* Check for a group past the limit */ if ((max_group_id > 0) && (group_id > max_group_id)) { return status; } /* Check for a length element */ have_length_element = (element_id == ACR_EID_GRPLEN); /* Read the length element and check it */ if (have_length_element) { status = acr_input_element(afp, &element); if (status != ACR_OK) { acr_delete_element(element); return status; } if ((acr_get_element_element(element) != ACR_EID_GRPLEN) || (acr_get_element_length(element) != ACR_SIZEOF_LONG)) { if (acr_ignore_protocol_errors(afp)) { group_length = 0; } else { acr_delete_element(element); status = ACR_PROTOCOL_ERROR; return status; } } else { group_length = acr_get_element_long(element); } acr_delete_element(element); } /* Create the group */ *group = acr_create_group(group_id); /* Set the VR encoding and the byte ordering for the length element according to the input stream. If the vr_encoding is implicit, then make the VR unknown. Note that the group will always have a length element even if the input stream does not. */ element = acr_get_group_element_list(*group); vr_encoding = acr_get_vr_encoding(afp); acr_set_element_vr_encoding(element, vr_encoding); acr_set_element_byte_order(element, acr_get_byte_order(afp)); if (vr_encoding == ACR_IMPLICIT_VR) { acr_set_element_vr(element, ACR_VR_UNKNOWN); } /* Loop through elements, adding them to the list */ get_more_elements = (have_length_element ? (group_length > 0) : TRUE); while (get_more_elements) { /* Check for a watchpoint */ if (acr_get_io_watchpoint(afp) <= 0) { get_more_elements = FALSE; break; } /* Look ahead at next element */ status = acr_peek_at_next_element_id(afp, &next_group_id, &element_id); if ((status != ACR_OK) || (next_group_id != group_id)) { if ( status == ACR_REACHED_WATCHPOINT ) status = ACR_OK; get_more_elements = FALSE; break; } /* Read in the next element */ status = acr_input_element(afp, &element); if (status != ACR_OK) { get_more_elements = FALSE; } /* Add it to the group */ if (element != NULL) { acr_group_add_element(*group, element); if (have_length_element) { group_length -= acr_get_element_total_length(element, acr_get_vr_encoding(afp)); } } /* Check group length */ if (have_length_element && !acr_ignore_protocol_errors(afp)) { get_more_elements = (group_length > 0); } } /* Check that we got a full group */ if (have_length_element && (group_length != 0) && !acr_ignore_protocol_errors(afp)) { switch (status) { case ACR_OK: status = ACR_PROTOCOL_ERROR; break; case ACR_END_OF_INPUT: status = ACR_ABNORMAL_END_OF_INPUT; break; } } return status; }
/* ----------------------------- MNI Header ----------------------------------- @NAME : save_transferred_object @INPUT : group_list - list of acr-nema groups that make up object file_prefix - prefix for file names @OUTPUT : new_file_name - name for newly created file data_info - information about data object @RETURNS : (nothing) @DESCRIPTION: Routine to save the object in a file. @METHOD : @GLOBALS : @CALLS : @CREATED : November 24, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ public void save_transferred_object(Acr_Group group_list, char *file_prefix, char **new_file_name, Data_Object_Info *data_info) { Acr_Group group; Acr_Element element; char temp_name[256]; char patient_name[256]; int study_id, acquisition_id, image_id; Acr_File *afp; FILE *fp; Acr_Status status; Acr_VR_encoding_type vr_encoding; Acr_byte_order byte_order; static int file_counter = 0; /* Get the VR encoding state and byte order */ element = acr_get_group_element_list(group_list); vr_encoding = acr_get_element_vr_encoding(element); byte_order = acr_get_element_byte_order(element); /* Get data info */ get_identification_info(group_list, &(data_info->study_id), &(data_info->acq_id), &(data_info->rec_num), &(data_info->image_type)); /* Get number of echos, echo number, number of dynamic scans and dynamic_scan_number */ data_info->num_echoes = acr_find_int(group_list, SPI_Number_of_echoes, 1); data_info->echo_number = acr_find_int(group_list, ACR_Echo_number, 1); data_info->num_dyn_scans = acr_find_int(group_list, ACR_Acquisitions_in_series, 1); data_info->dyn_scan_number = acr_find_int(group_list, ACR_Series, 1); /* Look for patient name */ element = acr_find_group_element(group_list, ACR_Patient_name); if (element != NULL) { string_to_filename(acr_get_element_string(element), patient_name, sizeof(patient_name)); } if ((element == NULL) || (strlen(patient_name) == 0)) (void) strcpy(patient_name, "unknown"); /* Look for study and image numbers */ study_id = data_info->study_id; acquisition_id = data_info->acq_id; image_id = acr_find_int(group_list, ACR_Image, 0); /* Create the new file name */ (void) sprintf(temp_name, "%s-%04d-%s_%d_%d_%d.dcm", file_prefix, file_counter++, patient_name, study_id, acquisition_id, image_id); /* Create the file and write out the data */ fp = fopen(temp_name, "w"); if (fp == NULL) { (void) fprintf(stderr, "Error opening file for write: %s\n", temp_name); } else { /* Set up the output stream */ afp = acr_file_initialize(fp, 0, acr_stdio_write); acr_set_vr_encoding(afp, vr_encoding); acr_set_byte_order(afp, byte_order); /* Loop over groups */ group = group_list; status = ACR_OK; while ((group != NULL) && (status == ACR_OK)) { /* Write out the group */ status = acr_output_group(afp, group); if (status != ACR_OK) { (void) fprintf(stderr, "Error writing file %s\n", temp_name); } group = acr_get_group_next(group); } /* Close the file */ acr_file_free(afp); (void) fclose(fp); } /* Copy the name */ *new_file_name = strdup(temp_name); return; }